Linux 服务器重启后 iptables 规则全丢了,原来是没做持久化

举报
phantomxjc 发表于 2026/11/02 10:02:30 2026/11/02
【摘要】 前阵子一台公网服务器重启做完内核升级,重启完没多久就收到告警:对外开放的数据库端口居然能在外网直接连上。登录一查,iptables 规则空空如也,之前辛辛苦苦配的防火墙全没了。踩了一次才明白,iptables 规则默认只活在内存里,不做持久化,重启必然丢。 问题现象 重启前后对比特别明显。重启前我明明配了类似这样的规则: 重启后再看: 不仅规则没了,连默认策略都回到了 ACCEPT。等于这台机器在

前阵子一台公网服务器重启做完内核升级,重启完没多久就收到告警:对外开放的数据库端口居然能在外网直接连上。登录一查,iptables 规则空空如也,之前辛辛苦苦配的防火墙全没了。踩了一次才明白,iptables 规则默认只活在内存里,不做持久化,重启必然丢。

问题现象

重启前后对比特别明显。重启前我明明配了类似这样的规则:

iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 3306 -j DROP
iptables -P INPUT DROP

重启后再看:

$ iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source   destination

不仅规则没了,连默认策略都回到了 ACCEPT。等于这台机器在重启后裸奔了一段时间,直到有人从外网扫到 3306 才被发现。

排查过程

第一反应是「谁把规则清了」?先排除人为操作:

$ last reboot
$ history | grep iptables

没查到有人执行过 iptables -F。接着怀疑是不是有别的服务在启动阶段重置了 netfilter,比如 firewalld 或 nftables 在开机时抢占了规则表:

$ systemctl status firewalld
$ nft list ruleset

这台机器没开 firewalld,nftables 也是空的。最后才反应过来:iptables 的规则从来就只存在内核内存里,没有落盘,重启即清零。我之前一直是「配完就走」,从没保存过。这是认知盲区,不是被谁动了。

补充一个排查时容易忽略的点:确认 iptables 的后端实现。现代发行版很多把 iptables 偷偷接到了 nft 后端,命令看着一样,实际写进了另一张表:

$ iptables --version
iptables v1.8.7 (nf_tables)

看到 nf_tables 就说明是「新」后端。这时如果你用老办法把规则存到 /etc/sysconfig/iptables 再用 legacy 的 iptables-restore 灌回去,表里不会有任何东西。正确做法是同一套 save/restore 工具配对使用——nf_tables 后端就用 iptables-save / iptables-restore,不要混用。搞清楚后端,能省掉一半「怎么存都不生效」的返工。

根因

iptables 本质是用户态工具,通过 netlink 把规则下发到内核的 netfilter 框架。规则存储在内核内存,断电/重启后自然消失。所谓「保存」,其实是把当前规则导出成文本文件,开机时再重新灌回去。

另一个坑是后端不一致:现代发行版 iptables 可能映射到 nft 后端(iptables-nft),而你用 iptables-save 导出、用 iptables-restore 导入时若后端不匹配,也会看起来「没生效」。可以用 iptables --version 看它指向的是 legacy 还是 nf_tables。

解决办法

第一,配完立刻保存。 用发行版自带工具最省心:

# Debian/Ubuntu
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6
# 开机自动恢复
apt install iptables-persistent netfilter-persistent
netfilter-persistent save

netfilter-persistent 会在开机和关机时自动 save / restore,以后改完规则只要再跑一次 netfilter-persistent save 即可。

第二,CentOS/RHEL 用 service 版本:

service iptables save        # 写入 /etc/sysconfig/iptables
systemctl enable iptables

第三,嫌手工管理麻烦,直接上 firewalld 或 nftables。 firewalld 的配置是落盘的,重启不丢,而且支持 zone 和 rich-rule,长期维护比裸 iptables 省心:

firewall-cmd --permanent --add-port=22/tcp
firewall-cmd --permanent --add-rich-rule='rule family=ipv4 port port=3306 reject'
firewall-cmd --reload

注意一定要带 --permanent,否则只改运行时、重启照样没。

第四,上线前验证。 改完别只看 iptables -L,用一台跳板机实打实扫一下端口(nmap -Pn 主机),确认该开的开了、该堵的堵了,再交付。

小结

iptables 的规则是「内存态」的,任何改动都必须显式持久化,否则一次重启就回到解放前,甚至把安全策略搞丢。我的习惯现在是:配完规则 → 立即 save → 重启验证 → 用 nmap 实测端口。用 firewalld/nftables 这类配置落盘的方案能少踩一半坑。记住一句话:没持久化的防火墙,等于没配。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。