服务器报错nf_conntrack: table full, dropping packet解决

现象:

你的系统日志提示 nf_conntrack: table full, dropping packet,说明 conntrack 连接跟踪表已满,导致新连接被丢弃。这个问题通常发生在高并发网络环境中,特别是 NAT 或防火墙规则使用 conntrack 进行连接跟踪时。

解决方案:

1. 临时增加 conntrack 表大小

可以暂时增大 nf_conntrack_max 值,让系统能跟踪更多连接:

1
echo 262144 > /proc/sys/net/netfilter/nf_conntrack_max

也可以使用 sysctl 命令:

1
sysctl -w net.netfilter.nf_conntrack_max=262144

说明:

  • 默认值通常在 65536 左右,建议适当增加,比如 262144 或更高,具体取决于服务器的网络负载。

2. 永久增加 conntrack 表大小

编辑 /etc/sysctl.conf,添加:

1
net.netfilter.nf_conntrack_max=262144

然后使其生效:

1
sysctl -p

3. 查看当前 conntrack 使用情况

执行以下命令,查看当前的 conntrack 连接数和上限:

1
2
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max

如果 conntrack_count 接近 conntrack_max,说明表快满了,需要增加 conntrack_max

4. 调整 hashsize

conntrack 使用哈希表存储连接信息。如果表太大,默认 hashsize 可能导致查询效率降低,可以增加:

1
echo 65536 > /sys/module/nf_conntrack/parameters/hashsize

5. 清理无用连接

可以定期清理 conntrack 连接,释放资源:

1
conntrack -F

6. 检查 nf_conntrack_buckets 设置

默认情况下,conntrack 哈希桶的大小是 nf_conntrack_max / 4,如果 conntrack_max 过大,可能导致哈希冲突,影响性能。可以调整:

1
echo 16384 > /sys/module/nf_conntrack/parameters/hashsize

或者永久生效:
/etc/modprobe.d/nf_conntrack.conf 添加:

1
options nf_conntrack hashsize=16384

然后重启服务器。

7. 降低 conntrack 超时时间

可以减少 conntrack 表项的超时时间,让旧连接更快释放:

1
2
3
4
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=300
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=120
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_close_wait=60
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_fin_wait=60

然后保存到 /etc/sysctl.conf,并执行 sysctl -p

8. 检查系统负载

高负载情况下,conntrack 处理效率可能降低:

1
2
3
top
htop
dmesg | tail -50

如果发现 CPU、内存或 I/O 负载过高,可能需要优化服务器性能。

9. 关闭 conntrack(仅适用于无状态流量)

如果你的服务器只是转发流量,不需要 conntrack,可以禁用它:

1
2
iptables -t raw -A PREROUTING -j NOTRACK
iptables -t raw -A OUTPUT -j NOTRACK

然后检查:

1
iptables -t raw -L -n -v

总结

如果你的服务器 需要连接跟踪,可以:

  1. 增加 nf_conntrack_max
  2. 调整 hashsize
  3. 清理无用连接
  4. 降低 conntrack 超时时间
  5. 监控服务器负载

如果服务器只是 转发大量流量(如网关或边界路由器),考虑 **禁用 conntrack**。

你可以先尝试 sysctl -w net.netfilter.nf_conntrack_max=262144,然后观察是否减少丢包情况。如果问题仍然存在,检查是否有异常流量或 DDoS 攻击。