专业的编程技术博客社区

网站首页 > 博客文章 正文

解决ip_conntrack table full dropping packet问题

baijin 2025-05-03 12:06:35 博客文章 4 ℃ 0 评论

原创不易

前篇:iptables 使用conntrack ctstate 提高防火墙处理效率

前篇谈到了iptables使用conntrack ctstate提高防火墙效率的问题,有朋友私信:在web服务器上启用了iptables常常出现“ip_conntrack: table full, dropping packet”,这种情况原因是什么?应该怎么处理?

我们先看一下iptables对出入站的数据包的处理过程图:

iptables整个处理过程可以说是十分繁琐的。

数据包进入,先经过raw表,进入到图中“Connection (state) Tracking”位置,开启连接跟踪处理,也就是从这个位置起iptables就会建立跟踪表来跟踪记录每一个连接情况,当服务器连接量较多,跟踪表空间消耗完,就会出现“ip_conntrack: table full, dropping packet”错误提示。

有没有办法解决这个问题呢?

一、通用解决方法:扩表及调整tcp超时时间

1、扩表:加大ip_conntrack跟踪表的大小

(1)先查看原来的跟踪表大小:

cat /proc/sys/net/netfilter/nf_conntrack_max

(2)/etc/sysctl.conf添加项目

net.netfilter.nf_conntrack_max = 393216


net.netfilter.nf_conntrack_buckets = 49152 #计算哈希表大小(通常为 max 的 1/8)

(3)执行生效

sudo sysctl -p

(4)实时查看当前连接数

watch -n 1 "cat /proc/sys/net/netfilter/nf_conntrack_count"


2、调整tcp超时时间

(1)/etc/sysctl.conf添加项目

net.netfilter.nf_conntrack_tcp_timeout_established = 3600

net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120

net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60

net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120

(2)实时监控超时连接

watch -n 1 "conntrack -L | grep -E 'TIME_WAIT|FIN_WAIT'"

(3)超时时间建议值

established 状态:默认 432000 秒(5天),若设置过短(如 300 秒)可能导致长连接异常中断。推荐值:至少保留 3600(1小时),根据业务需求调整。

time_wait 状态:默认 60 秒,用于处理延迟的 TCP 报文。设置 120 秒是安全的,但需确保服务器能处理大量短连接。

close_wait 状态:默认 60 秒,表示等待应用层关闭连接。设置过低可能导致连接强制终止。

fin_wait 状态:默认 120 秒,确保 TCP 连接正常终止。

3、注意问题

(1)如果系统是老版本的请如下修改(新版本使用 nf_conntrack 替代 ip_conntrack):

判断新老:cat
/proc/sys/net/ipv4/ip_conntrack_max,有数值提示就是老版本。

vi /etc/sysctl.conf

net.ipv4.ip_conntrack_max = 393216

net.ipv4.netfilter.ip_conntrack_max = 393216


修改ip_conntrack timeout时间

vi /etc/sysctl.conf

net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 300

net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 120

net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 60

net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 120

(2) 如果设定参数不生效,可能是模块没加载

sudo modprobe nf_conntrack # 加载模块

sudo sysctl -p # 重新加载配置


二、釜底抽薪:用好raw表

回到iptables处理过程图,能看到“Connection (state) Tracking”位置总是在raw(prerouting,output)之后。如果将压力非常大的服务(tcp 80)在raw表中标明其服务不再进行跟踪处理了不就解决了吗?你想的很对!这就是iptables raw表的主要用途。

(1)绕过连接跟踪:raw表用于在连接跟踪机制(conntrack)之前处理数据包,通过 NOTRACK 标记可以直接跳过连接跟踪表。

(2)性能优化:适用于高并发场景(如Web服务器、游戏服务器),可避免 conntrack 表溢出导致的性能瓶颈或丢包。

(3)示例:设置 raw 表规则(跳过HTTP/HTTPS流量跟踪)

iptables -t raw -A PREROUTING -p tcp --dport 80 -j NOTRACK

iptables -t raw -A PREROUTING -p tcp --sport 80 -j NOTRACK

iptables -t raw -A PREROUTING -p tcp --dport 443 -j NOTRACK

iptables -t raw -A PREROUTING -p tcp --sport 443 -j NOTRACK

(4)测试HTTP服务访问,观察 conntrack 表中无相关条目

conntrack -L | grep 80

通过以上配置,你的服务器可以在高并发场景下显著减少 conntrack 的开销。


前篇:iptables 使用conntrack ctstate 提高防火墙处理效率

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表