iptables连接跟踪状态表conntrack爆满网络故障处理[已解决]本文记录了Openwrt 软路由，由于iptables连接跟踪状态表conntrack达到最大限制，触发一系列奇怪的网络。从故障现象到排查过程，到优化方案都做了详细的总结首先介绍下公司的网络设备连接方式：{message type="info" content=" 电信出口光猫->软路由openwrt->行为管理（深信服AC）->华为核心交换->二层交换机（有线和无线网络）"/}问题描述：某天接到公司同事反馈 IOS端的 Appstore应用打不开。一开始以为是同事电脑问题。报错如下：故按照管理，重启大法伺候，重启完之后，故障仍在。没多久，又有其他同事陆续范围，MAC笔记本电脑打不开 Appstore，断网重连，重启电脑都不行。看来网络确实有问题。开始排查排查接入点网络先尝试有线和无线，2.4G和5G两个WIFI频段都尝试一次，以上问故障都会出现。初步定位为和WIFI热点无关。应该是上层网络节点出问题。排查路由防火墙设置排查了常规的iptables防火墙，端口转发，行为管理行为策略。发现都正常。路由器tcpdump抓包登录openwrt路由器命令行界面，使用tcpdump -vn 192.168.24.31 抓包debug这里的 192.168.24.31 是其中的一台苹果手机IP，我们用这台手机访问appstore抓包测试。经排查发现打开appstore 这个app时网络数据包异常，从app服务器发来的udp数据包，无法被手机端接收，服务器发来的3次同样的Udp数据包，均没有被手机端接收到。问题就出在这里。那么是什么原因导致的呢？考虑到既然是网络数据包进不来，重置一下网络连接是否有效呢？然后在openwrt上面重载iptables，再测试发现app store可以正常访问了。然而。。。，过了1分钟之后，app store就又无法访问了，一脸懵逼。。。看来这个问题确实跟防火墙有关。防火墙上配置了一系列端口转发规则，都是业务在用的，无法通过关闭Iptables解决。在这里卡了大半天，实在找不到解决办法。并且在这期间app store有时候是能访问的，大部分时间都无法访问。看起来相当不稳定，很奇怪的问题。这里就想着如何追踪iptables工作状态，经过查资料发现。openwrt 网络连接主要和iptables有关，并且记录在 /proc/net/nf_conntrack 中，这个文件中。nf_conntrack详解nf_conntrack(在老版本的 Linux 内核中叫 ip_conntrack)是一个内核模块,用于跟踪一个连接的状态的。连接状态跟踪可以供其他模块使用,最常见的两个使用场景是 iptables 的 nat 的 state 模块。 iptables 的 nat 通过规则来修改目的/源地址,但光修改地址不行,我们还需要能让回来的包能路由到最初的来源主机。这就需要借助 nf_conntrack 来找到原来那个连接的记录才行。而 state 模块则是直接使用 nf_conntrack 里记录的连接的状态来匹配用户定义的相关规则。例如下面这条 INPUT 规则用于放行 80 端口上的状态为 NEW 的连接上的包。iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT。iptables中的状态检测功能是由state选项来实现iptable的/proc/net/nf_conntrack内容详解cat /proc/net/nf_conntrack ipv4 2 tcp 6 8 CLOSE src=115.231.78.3 dst=107.173.34.159 sport=64904 dport=443 src=107.173.34.159 dst=115.231.78.3 sport=443 dport=64904 [ASSURED] mark=0 zone=0 use=2 ipv4 2 tcp 6 119 TIME_WAIT src=115.231.78.3 dst=107.173.34.159 sport=45761 dport=443 src=107.173.34.159 dst=115.231.78.3 sport=443 dport=45761 [ASSURED] mark=0 zone=0 use=2 ipv4 2 tcp 6 6 CLOSE src=115.231.78.3 dst=107.173.34.159 sport=57985 dport=443 src=107.173.34.159 dst=115.231.78.3 sport=443 dport=57985 [ASSURED] mark=0 zone=0 use=2 每一列表达的意思 第一列：网络层协议名字。 第二列：网络层协议号。 第三列：传输层协议名字。 第四列：传输层协议号。 第五列：无后续包进入时无效的秒数，即老化时间。 第六列：不是所有协议都有，连接状态。 其它的列都是通过名字的方式（key与value对)表述，或和呈现标识（[UNREPLIED], [ASSURED], …）。一行的不同列可能包含相同的名字（例如src和dst），第一个表示请求方，第二个表示应答方。 呈现标识含义 [ASSURED]: 在两个方面（即请求和响应）方向都看到了流量。 [UNREPLIED]: 尚未在响应方向上看到流量。如果连接跟踪缓存溢出，则首先删除这些连接。 请注意，某些列名仅出现在特定协议中（例如，TCP和UDP的sport和dport，ICMP的type和code）。 仅当内核使用特定选项构建时，才会显示其他列名称（例如mark）。经检查发现，这个文件现在有16000行左右。这个值刚好和当前配置的 net.netfilter.nf_conntrack_max=16000 值接近，并且一直在这个值左右徘徊。查阅资料发现这个值是系统用来记录跟踪所有网络连接状态的表。已经超过了最大值。我们修改并添加一下参数再试试：在 /etc/sysctl.conf 文件中新增以下内容net.netfilter.nf_conntrack_buckets=262144 net.netfilter.nf_conntrack_generic_timeout=600 net.netfilter.nf_conntrack_udp_timeout=30 net.netfilter.nf_conntrack_udp_timeout_stream=180 net.netfilter.nf_conntrack_tcp_timeout_syn_recv=60 net.netfilter.nf_conntrack_tcp_timeout_syn_sent=120 net.netfilter.nf_conntrack_tcp_timeout_time_wait=120然后：sysctl -w net.netfilter.nf_conntrack_buckets=262144 sysctl -w net.netfilter.nf_conntrack_generic_timeout=600 sysctl -w net.netfilter.nf_conntrack_udp_timeout=30 sysctl -w net.netfilter.nf_conntrack_udp_timeout_stream=180 sysctl -w net.netfilter.nf_conntrack_tcp_timeout_syn_recv=60 sysctl -w net.netfilter.nf_conntrack_tcp_timeout_syn_sent=120 sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=120使之生效。再运行 sysctl -p以防万一。找个业务低峰期重启一下openwrt，重启速度openwrt硬件有关。我们的硬件为inter 10代i7，30秒左右就重启好了。经过2天的观察，发现app store已经完全正常， /proc/net/nf_conntrack 文件记录数也从1.6w，涨到了2w看起来确实生效了。收工。