一次线上环境nf_conntrack导致的dropping pa
背景
某个线上环境运维人员执行了一条命令,在很短的时间内造成了web服务不可用的严重后果,后来重启服务器恢复正常.据后来事后排查,是因为执行了iptables -t nat -L这条命令引起的.现在我们抱着学习的态度来分析下为什么会造成这个后果及我们可以采取的应对办法,毕竟在线上环境重启服务器是个比较大的操作。
问题描述
该线上环境服务器iptables状态默认是打开的,问朋友拿到了他们当时的系统日志,执行完iptables -t nat -L后,发现当时/var/log/messages产生了大量日志
Apr 27 00:03:27 bogon kernel: nf_conntrack: table full, dropping packet.
Apr 27 00:03:27 bogon kernel: nf_conntrack: table full, dropping packet.
Apr 27 00:03:27 bogon kernel: nf_conntrack: table full, dropping packet.
Apr 27 00:03:27 bogon kernel: nf_conntrack: table full, dropping packet.
Apr 27 00:03:27 bogon kernel: nf_conntrack: table full, dropping packet.
Apr 27 00:03:29 bogon kernel: nf_conntrack: table full, dropping packet.
问题分析
nf_conntrack是内核的连接跟踪模块,和iptables有关,当我们使用iptables的state模块的时候,内核会加载nf_conntrack模块,对连接进行跟踪管理,我们在测试环境模拟下操作,系统环境为CentOS6.9,如下所示:
iptables未使用state时的状态:
图片.png
然后我们添加一条防火墙规则,使用state模块,如下图所示:
图片.png
从2个图片对比可以看出,使用state的时候,内核会加载nf_conntrack模块对连接进行跟踪处理,和这个参数有关的还有个内核参数nf_conntrack_max,该参数设置了内核记录跟踪的最大连接数目,如果当前需要跟踪的连接数过多,内核就会随机丢包.在外面看来,就是丢包严重,影响服务的可用性.
回到当前问题,该运维人员只是执行了一条查询命令,我们来看下改命令执行的时候会发生什么
图片.png
从上面我们可以看到,执行iptables -t nat -L的时候,系统会加载nf_conntrack模块,然后nf_conntrack开始对连接进行跟踪,由此推测,该线上环境默认没有加载nf_conntrack模块,当该运维人员执行iptables -t nat -L的时候,系统加载该模块对连接进行跟踪,而此时系统正在提供服务,连接数比较多,大量的连接被跟踪,超出了nf_conntrack_max的限制,内核开始随机丢包,导致服务可用性降低
问题总结
当我们使用iptables的state模块和nat功能的时候,系统会加载nf_conntrack模块对连接进行跟踪处理,而只查看nat表的规则,也会触发该模块加载,导致连接被跟踪.如果nf_conntrack_max的数值设置的又比较小,内核就会随机丢包.
处理建议
1:线上环境尽量避免加载该模块,例如关闭防火墙,不使用state模块
2:根据线上环境调大nf_conntrack_max的值
3:在raw表里设置不跟踪某些服务的连接,比如web服务