firewalld --permanent 规则 reboot 后消失,主因是未执行 firewall-cmd --reload 或 firewalld 服务未启用;--permanent 仅写入磁盘配置,需 reload 才加载至运行时,且服务必须 enabled 并正常启动。

firewalld --permanent 规则 reboot 后消失?先确认是否漏了 --reload
加了 --permanent 不等于规则已生效,它只是写进磁盘配置;真正加载进运行时防火墙的是 firewall-cmd --reload。很多人执行完 firewall-cmd --permanent --add-port=8080/tcp 就以为完事了,结果 reboot 后发现端口不通——因为没 reload,旧的 runtime 配置还在,而 reboot 会清空 runtime,只从 permanent 配置重建,但若 permanent 配置没被显式 reload 过,systemd-firewalld 服务启动时可能因依赖顺序或初始化时机问题未能正确载入。
- 每次修改
--permanent规则后,必须手动执行firewall-cmd --reload(哪怕刚加完就 reboot) - reboot 前建议补一次
firewall-cmd --reload,确保磁盘配置和内存状态一致 - 检查是否真写入了 permanent 配置:
firewall-cmd --permanent --list-all,而不是只看--list-all
systemd firewalld 服务未启用导致 reboot 后规则不加载
firewalld 是按需启动的服务,如果没设为开机自启,reboot 后服务压根没跑,自然不会读取 /etc/firewalld/zones/ 下的 permanent 配置。
- 运行
systemctl is-enabled firewalld,输出不是enabled就要补上:systemctl enable firewalld - 即使启用了,也要确认服务实际启动成功:
systemctl status firewalld,留意是否有Failed to initialize nftables或Zone 'public' not found类错误 - 某些最小化安装的系统(如 CentOS Stream 9 minimal)默认禁用 firewalld,且不自带
iptables-services回退方案
使用 --runtime-only 添加规则却误以为 --permanent 生效
容易混淆的点:firewall-cmd --add-port=8080/tcp(无 --permanent)是 runtime-only,reboot 必丢;但有人加完 runtime 规则后,顺手执行了 firewall-cmd --permanent --add-port=8080/tcp,却忘了 reload,于是误判“permanent 也没用”。
- 区分清楚:带
--permanent的命令只改配置文件,不改当前防火墙行为 - 带
--runtime-only的命令只改当前内存,不写磁盘 - 最稳妥流程:
firewall-cmd --permanent --add-port=8080/tcp→firewall-cmd --reload→firewall-cmd --list-ports验证是否在 runtime 中出现
nftables 后端下 zone 文件损坏导致 reload 失败静默丢规则
firewalld 在较新系统(RHEL 8+/CentOS 8+)默认用 nftables 后端。如果手动编辑过 /etc/firewalld/zones/public.xml,格式出错或标签不闭合,--reload 会失败但不报错(只在 journal 里记 warning),导致后续 reboot 时 firewalld 初始化跳过该 zone,所有规则失效。
- 执行
firewall-cmd --reload后立刻查结果:firewall-cmd --state应返回running,再firewall-cmd --list-all看规则是否在 runtime 中 - 查日志:
journalctl -u firewalld --since "1 hour ago" | grep -i "error\|warn",重点关注Failed to load zone或Invalid XML - 不要直接改 xml 文件,优先用
firewall-cmd命令操作;非改不可时,用xmllint --noout /etc/firewalld/zones/public.xml校验格式
permanent 规则 reboot 失效,八成不是 bug,而是 reload 没做、服务没启、或者 reload 实际失败了却没验证。别信“加了 permanent 就一劳永逸”,firewalld 的两层抽象(runtime + permanent)恰恰是出问题最多的地方。










