重启 iptables 为啥内核参数不对了?
问题描述
在一台服务器上重启 iptables 服务后,经过一段时间出现服务器丢包问题,看系统日志出现报错:
nf_conntrack 是啥
Linux 内核中有一个内核模块 nf_conntrack 用于做连接跟踪,当 iptables 添加了 nat 相关规则时此模块会被自动启用。
顾名思义这个模块维护了一个连接跟踪表,当 iptables 做网络地址转换(nat)或设置一些跟连接状态(state)相关的规则时,此模块会被自动启用。该模块生效后,需要对部分参数做优化,如:
net.netfilter.nf_conntrack_max: 连接跟踪表最大值,超出后会导致操作系统会丢包。默认为 65535,优化至 6553500
net.netfilter.nf_conntrack_tcp_timeout_established: 已建立连接的最大超时时间,配置过大可能会导致更容易被攻击,无效链接挂起太多,连接跟踪表更容易被打满。默认为 43200 秒,优化至 3600 秒
为什么重启 iptables 后会有问题?
严格来讲不是重启 iptables 后会有问题,而是重新加载 nf_conntrack 内核模块后会有问题。
系统参数仅在系统启动时加载一次,这导致内核模块被反复加载时,并不会重新生效系统内核的配置。
如何解决?
考虑如下几个方案。
方案一 修改 iptables 配置
iptables 本身考虑到了这个问题,可以支持在启动服务时自动加载内核参数。
这样在执行 systemctl start iptables 启动 iptables 服务时,会自动加载上述两个内核参数。问题本方案仅能在 iptables 以服务方式启动时实现参数加载。
nf_conntrack 模块的启用条件比较复杂,我们可以直接执行一条 iptables 命令就可以加载此模块,这样就无法顺利的加载内核参数。
执行任意包含 NAT 或 state 模块的 iptables 规则,即可导致系统加载 nf_conntrack 内核模块。如:iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
方案二 增加内核模块选项
在/etc/modprobe.d/目录下创建配置文件,增加配置 options nf_conntrack hashsize = 1048576。
则系统在加载内核模块时,会自动应用 net.netfilter.nf_conntrack_max = hashsize * 8,即 net.netfilter.nf_conntrack_max = 8388608
一般加载内核模块的选项,使用这种方式配置是标准的方式。
问题此方案无法修改 nf_conntrack 连接超时相关的配置,无法满足需求。
方案三 通过 udev 配置实现
最终采用此方案。udev 是 Linux 操作系统的设备管理器,用来管理设备加载、固件及模块加载时的一些动作。
这个配置文件的含义是,系统加载 nf_conntrack 内核模块时,会执行下面两条命令:
/usr/lib/systemd/systemd-sysctl --prefix=/net/netfilter/nf_conntrack_max
/usr/lib/systemd/systemd-sysctl --prefix=/net/netfilter/nf_conntrack_tcp_timeout_established
在 CentOS6 系统中由于没有 systemd-sysctl 命令,我们可以这样定义:
通过此方案实现,不论什么原因导致 nf_conntrack 模块被加载,都能自动生效内核配置。
参考文档
版权声明: 本文为 InfoQ 作者【BUG侦探】的原创文章。
原文链接:【http://xie.infoq.cn/article/c271f0b17cc3b0cf2c2f7f73c】。文章转载请联系作者。
评论