#!/usr/bin/env bash
# ==============================================================================
# 脚本名称: check_conntrack_drop.sh
# 功能描述: 探测内核 nf_conntrack 容量水位与静默丢包风险 (纯只读)
# 使用方式: 在 Linux 宿主机以 root 权限执行
# ==============================================================================
set -o pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
PLAIN='\033[0m'
echo -e "${BLUE}================================================================${PLAIN}"
echo -e "${BLUE} 内核 Netfilter 连接跟踪表静默丢包安全巡检 ${PLAIN}"
echo -e "${BLUE}================================================================${PLAIN}"
# 1. 检查 nf_conntrack 模块是否加载
if [ ! -f /proc/sys/net/netfilter/nf_conntrack_count ]; then
echo -e "${GREEN}[OK] 当前系统未启用 nf_conntrack 模块,无此类丢包风险。${PLAIN}"
exit 0
fi
# 2. 提取当前连接数与上限
CT_COUNT=$(cat /proc/sys/net/netfilter/nf_conntrack_count 2>/dev/null)
CT_MAX=$(cat /proc/sys/net/netfilter/nf_conntrack_max 2>/dev/null)
CT_BUCKETS=$(cat /sys/module/nf_conntrack/parameters/hashsize 2>/dev/null)
# 修复了逻辑或乱码
if [ -z "$CT_COUNT" ] || [ -z "$CT_MAX" ]; then
echo -e "${RED}[ERROR] 无法读取 nf_conntrack 统计数据。${PLAIN}"
exit 1
fi
USAGE_PCT=$(echo "scale=2; ($CT_COUNT / $CT_MAX) * 100" | bc)
echo -e "\n${YELLOW}[1/3] nf_conntrack 容量水位分析...${PLAIN}"
echo -e " -> 当前跟踪连接数 : ${YELLOW}${CT_COUNT}${PLAIN}"
echo -e " -> 系统配置上限 : ${CT_MAX}"
echo -e " -> 哈希桶数量 : ${CT_BUCKETS}"
# 修复了百分号转义乱码
echo -e " -> 容量使用率 : ${YELLOW}${USAGE_PCT}%${PLAIN}"
if (( $(echo "$USAGE_PCT > 85.0" | bc -l) )); then
# 修复了百分号转义乱码
echo -e " -> ${RED}[DANGER] 连接跟踪表水位超过 85%!极易触发内核静默丢包并导致接口 Timeout。${PLAIN}"
echo -e " -> [处置建议] 立即执行扩容: sysctl -w net.netfilter.nf_conntrack_max=$((CT_MAX * 2))"
else
echo -e " -> ${GREEN}[OK] 当前容量处于安全水位。${PLAIN}"
fi
# 3. 检查 dmesg 内核丢包日志
echo -e "\n${YELLOW}[2/3] 检查系统内核 dmesg 历史丢包记录...${PLAIN}"
DROP_MSG=$(dmesg -T 2>/dev/null | grep -i "nf_conntrack: table full" | tail -n 3)
if [ -n "$DROP_MSG" ]; then
echo -e " -> ${RED}[ALERT] 在内核日志中检测到连接表溢出丢包记录:${PLAIN}"
echo -e "${YELLOW}${DROP_MSG}${PLAIN}"
else
echo -e " -> ${GREEN}[OK] dmesg 中未发现 table full 丢包告警。${PLAIN}"
fi
# 4. 检查超时回收机制配置
echo -e "\n${YELLOW}[3/3] 检查连接跟踪超时回收参数...${PLAIN}"
TIMEOUT_EST=$(cat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established 2>/dev/null)
if [ -n "$TIMEOUT_EST" ] && [ "$TIMEOUT_EST" -gt 86400 ]; then
echo -e " -> ${RED}[WARN] ESTABLISHED 状态跟踪超时时间长达 ${TIMEOUT_EST} 秒(默认 5 天,偏大)。${PLAIN}"
echo -e " -> ${YELLOW}[建议] 高并发环境下建议调小至 600~3600 秒,加快僵死连接回收。${PLAIN}"
else
echo -e " -> ${GREEN}[OK] ESTABLISHED 超时清理时间配置合理 (${TIMEOUT_EST} 秒)。${PLAIN}"
fi
echo -e "\n${BLUE}================================================================${PLAIN}"
echo -e "${BLUE}巡检完毕。若需进一步实时定位内核丢包位置,请结合 bpftrace 挂载 kfree_skb 追踪。${PLAIN}"
echo -e "${BLUE}================================================================${PLAIN}"