firewalld自定义规则重启后丢失,核心原因是服务未开机自启、permanent规则未执行--reload加载至runtime、nftables后端初始化失败或zone文件损坏;需依次检查systemctl is-enabled firewalld、systemctl status firewalld、firewall-cmd --permanent --list-all、firewall-cmd --reload及zone配置完整性。

firewalld 自定义规则重启后丢失,不是配置没写对,而是“写进去了但没真正加载进来”。核心问题就三个:服务没开机自启、永久规则没重载、nftables 后端初始化失败。下面分四块说清楚怎么一步步查。
确认 firewalld 是否开机自启且启动成功
reboot 后规则全空,第一反应不是规则错了,而是服务压根没起来。
- 执行 systemctl is-enabled firewalld,输出不是 enabled 就补上:systemctl enable firewalld
- 再查真实运行状态:systemctl status firewalld,重点看 Active 行是否为 active (running),不是 failed 或 inactive
- 如果状态异常,末尾日志出现 Failed to initialize nftables backend 或 Zone 'public' not found,说明后端初始化失败,需单独处理(见第四点)
验证 permanent 规则是否真写入磁盘
--permanent 命令只是改配置文件,不等于规则已存在。很多人加完端口就 reboot,忘了这步。
- 查磁盘里有没有存进去:firewall-cmd --permanent --list-all(不是 --list-all)
- 如果输出里没有你加的端口或服务,说明命令根本没执行成功,或者执行时 zone 写错了(比如误用了 internal 区域)
- 常见错误:用 firewall-cmd --add-port=8080/tcp(runtime-only)后,又补了 --permanent --add-port,但没 reload —— 此时 permanent 配置可能为空,reboot 就清零
检查是否漏掉 firewall-cmd --reload
这是最常被忽略的动作。--permanent 只写文件,--reload 才把文件内容载入内存,并让 firewalld 在下次启动时知道该读哪份配置。
- 每次执行带 --permanent 的增删操作后,必须紧跟:firewall-cmd --reload
- reboot 前建议手动再跑一次 firewall-cmd --reload,确保磁盘和内存状态一致
- 验证 reload 是否生效:执行 firewall-cmd --list-ports,看到端口才说明 runtime 已加载
排查 nftables 后端兼容性与 zone 文件损坏
CentOS 8+/Rocky 9/AlmaLinux 9 等系统默认用 nftables,宝塔 8.x 或某些最小化安装环境对它支持不完整,容易静默失败。
- 运行 firewall-cmd --state 确认服务在响应;再执行 firewall-cmd --get-active-zones,如果报错或无输出,大概率是后端卡住
- 检查 zone 配置是否损坏:ls -l /etc/firewalld/zones/public.xml,文件大小为 0 或权限异常(如非 root:root)会导致 reload 失败
- 临时回退测试:若系统装了 iptables-services,可尝试 systemctl stop firewalld && systemctl start iptables,看规则能否持久——用来隔离是 firewalld 本身问题还是配置问题











