为什么会有这个 wiki 页面?
在 Linux 中,iptables 是一个防火墙控制工具,但并不是一个“服务”。
真正内核中负责防火墙工作的是 Netfilter,iptables 仅仅是一个控制内核防火墙如何去工作的工具而已。
Netfilter 分为两部分:规则、附加模块。
由于部分发行版的 /etc/init.d/iptables 脚本存在一定 BUG,在运行 service iptables stop 时只能停掉“规则”,而无法停掉“附加模块”。
Netfilter 的 conntrack 机制往往是导致“可用性低”、“无法正确建连”、“响应时间差”的罪魁祸首。
对于无需做地址转换(NAT)的设备而言,完全无需启用 Netfilter 的 conntrack 功能,因此我们要彻底停掉它。
为什么 conntrack 会导致“可用性低”、“无法正确建连”、“响应时间差”等现象?
如果启用了 conntrack,所有连接,无论是 tcp 还是 udp 还是 icmp 甚至其他传输层协议,连接信息都会占用 conntrack(连接追踪表)。
默认情况下,Linux 的 conntrack_max 只有 65535。
当网络中连接数很高时,conntrack 表很快被占满,系统无法响应新请求(包括 ssh),这样会导致“可用性低”和“无法正确建连”的现象。
通过 sysctl 可以设置更大的 conntrack_max 值,但因为默认情况下 conntrack 的 hashsize 很小,
大量的连接会导致 Linux 系统查找 hash 表效率低下,会导致“响应时间差”的现象。
为什么 service iptables status 看不到任何规则,但 iptables 仍是“工作状态”?
因为即使没有任何规则,但只要针对某个表的某个(些)链进行过 -L 操作,就会自动载入 iptables 模块,这是 iptables 的一个特性。
为什么 service iptables status 看不到任何信息,但 lsmod|grep conn 仍能看到信息?
因为曾经由于某些原因,Netfilter 的 conntrack 被启用过,后期虽然停止过规则。
但由于某些发行版的脚本 /etc/init.d/iptables 存在 BUG,无法在停掉规则的同时禁用 conntrack 机制,
导致“可用性低”、“无法正确建连”、“响应时间差”等现象。
在什么情况下系统会自动载入 iptables?
- 启用了 iptables 服务,且 /etc/sysconfig/iptables 中有内容
- 仅仅运行过 iptables -L 命令查看过某个表,此时 kernel 会自动载入 iptables 的相关模块
在什么情况下会自动启用 conntrack 机制?
- /ets/sysconfig/iptables-config 中 IPTABLES_MODULES 变量不为空时
- 做 NAT 时
- 规则里使用了 state 模块时
- 规则里使用了 connbytes 模块时
- 规则里使用了 hashlimit 模块时
- 规则里使用了 connmark 模块时
- 规则里使用了 CONNMARK 动作时
如何知道 iptables 是何时、如何、被怎样启动的?
#! /bin/bash PID=`echo $$` DATE=`date` echo "DATE: $DATE" >> /tmp/iptables.log ps aufx|grep -rn15 $PID >> /tmp/iptables.log echo "PID is $PID" >> /tmp/iptables.log echo "$0 $*" >> /tmp/iptables.log echo -e "\n\n\n\n\n" >> /tmp/iptables.log
- 备份 /sbin/iptables 和 /sbin/iptables-restore
- 用上面的脚本替换这两个文件
- chmod a+x /sbin/iptables*
- 静观其变,等待系统自动生成 /tmp/iptables.log(记得最后将两个文件恢复回来)
如何彻底停掉 iptables?
若要彻底停掉 iptables,不仅需要清除所有规则,还要移除所有 iptables、Netfilter 相关的内核模块
清除所有规则比较简单,可以使用 service iptables stop 完成
但移除内核模块则需要考虑内核模块的依赖关系
可以考虑使用下面的代码完成
wget -qO- http://61.135.208.20/download/baijin/release/iptables-stop | bash
#! /bin/bash service iptables stop service ip6tables stop chkconfig iptables off chkconfig ip6tables off for((i=0;i<10;i++)) do for M in `lsmod|awk ‘/conn/||/xt_/||/ipt_/||/ip6t_/||/nf_/||/_tables/||/ip_vs/{print $1}‘` do rmmod $M &>/dev/null done done chkconfig --level 12345 iptables off chkconfig --level 12345 ip6tables off if [ "`lsmod |awk ‘/conn/‘`" == "" ] then echo "iptables has been stopped completely." else echo "WARNING: For some reasons, iptables can NOT be stopped, the device must be rebooted!" fi
如果必须使用 conntrack,如何优化其性能?
- 加大 hashsize
在确保 lsmod|grep conn 没有任何提示的情况下 modprobe nf_conntrack hashsize=200000
- 加大 conntrack_max 值
sysctl -w net.netfilter.nf_conntrack_max=1024000
- 缩短异常连接在 conntrack 表中的 timeout 时间
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=7300
检查 iptables 是否是开机自启动
chkconfig --list iptables 如果有 on 就是开机自动启动
禁止 iptables 开机自动启动的方法是 chkconfig iptables off
必须使用 conntrack 的情况:CPIS WCCP 优化案例
增加 conntrack_max 数量
增加后可以存储更多的连接数据,不会造成 conntrack table full 的情况,提高可用性
增加 bucket 数量
增加 bucket 数量后,利用空间换时间的方法,将少量长链表换成多个短链表,单个链表检索速度会大幅度下降
降低 timeout 值
降低 timeout 值会让僵尸数据尽快从表中删除,提高效率,降低对 conntrack_max 的占用
降低 establish 值
原因同上,会提高效率,降低对 conntrack_max 的占用