持久化iptables规则的确是个让人头大的问题,每次服务器重启,辛辛苦苦配置的防火墙规则就像被施了魔法一样消失不见。我敢打赌,每个运维人都至少经历过一次这种崩溃时刻——明明之前测试得好好的,怎么一重启就全乱套了?说实话,我第一次遇到这种状况时,差点以为是服务器被人入侵了!
为什么规则会消失?
其实这跟Linux系统启动流程有关。iptables规则默认都是保存在内存中的,就像你用记事本记录的东西,如果不主动保存到硬盘上,断电自然就没了。这就是为什么我们总说”iptables只是临时配置”的原因。不过奇怪的是,很多人明明知道这一点,还是会忘记持久化这茬,大概是因为在测试阶段实在太过顺利吧?
拯救方案:iptables-save/restore
最经典的方法当然是使用iptables-save
和iptables-restore
这对命令组合了。我第一次使用时就感觉像是发现了新大陆——原来只需要这么简单的两步:先把当前规则保存到文件里,再在开机时自动加载。具体操作是这样的:首先执行iptables-save > /etc/iptables.rules
把规则保存到文件,这个路径通常是大家都认可的默认位置;然后在/etc/network/interface
中加入一条pre-up iptables-restore < /etc/iptables.rules
。
不过!这里有个大坑——不同的Linux发行版处理方式可能完全不同。比如在CentOS/RHEL系统上,你可能需要修改的是/etc/rc.local
;而Ubuntu 18.04之后又变成了用netfilter-persistent
这个东西。我就曾经在一个RedHat 7系统上折腾了整整一个下午才发现问题所在。
更现代的解决方案
现在很多系统推荐使用iptables-persistent
这个工具包,它通过一个名为netfilter-persistent
的服务来管理规则持久化。安装后只需要执行service netfilter-persistent save
就能自动帮你处理保存的事情。听起来是不是很方便?但说实话,这个工具在复杂环境下可能会遇到各种奇怪的权限问题。我遇到最诡异的情况是在一个Docker容器里,莫名其妙就是保存失败,最后发现是SELinux在暗中使绊子。
另外一个越来越流行的工具是firewalld,特别是在RedHat系系统中。虽然很多人吐槽它过度封装了iptables,但不得不承认它的持久化机制确实更加可靠。Firewalld会把配置以XML格式存储在/etc/firewalld/
目录下,重启后会自动加载。
终极验证指南
每次配置完永久规则,我都要重复这个”宗教仪轨”般的验证步骤:先故意重启服务器,然后iptables -L
检查规则是否存在。不过更专业的方法是查看计数器是否在正常增长(iptables -vL
),因为有些情况下规则虽然在但可能没被正确应用。说起这个,我就想起曾经有个同事信誓旦旦地说规则已经持久化了,结果客户半夜打来电话说服务挂了,原因就是他忘记检查计数器了。
记住啊,在真实的生产环境中,没有一个运维人员会相信”应该生效了”这种话,我们只相信亲眼看到的事实。毕竟服务器的稳定性,有时候就是取决于这种近乎强迫症的谨慎。
评论