firewalld --permanent 规则 reboot 后未生效的根本原因是服务启动时仅加载 runtime 配置,permanent 规则必须通过 firewall-cmd --reload 显式应用到内存,否则仍驻留磁盘不生效。

firewalld --permanent 规则为什么 reboot 后没生效
根本原因不是规则没保存,而是 firewalld 服务启动时默认只加载 runtime 配置,--permanent 规则必须显式“应用”到 runtime 才能起作用。reboot 后服务重启,但没人执行 firewall-cmd --reload,所以 permanent 区域里的规则仍躺在磁盘里,没进内存。
firewall-cmd --reload 不等于“重载永久规则”
--reload 的真实行为是:丢弃当前 runtime 配置,然后从 /etc/firewalld/ 下的 permanent 文件(如 zones/public.xml)重新加载——但它**不会校验或同步你之前用 --permanent 命令临时写入的规则**。那些规则只存在 daemon 内存里,没落盘就丢失了。
- ✅ 正确流程:
firewall-cmd --permanent --add-port=8080/tcp→firewall-cmd --reload - ❌ 错误操作:
firewall-cmd --permanent --add-port=8080/tcp→ 直接 reboot(没 reload) - ⚠️ 注意:
--reload必须在--permanent操作后执行,且需 root 权限;普通用户即使加了--permanent,不 reload 就等于白加
检查 permanent 规则是否真已落盘
别信命令返回 “success”,要看文件。firewalld 的 permanent 配置最终都写进 /etc/firewalld/zones/ 对应 zone 的 XML 文件里。比如加了端口到 public 区域:
firewall-cmd --permanent --zone=public --add-port=8080/tcp firewall-cmd --reload
之后立刻检查:
- 运行
cat /etc/firewalld/zones/public.xml,确认已存在 - 如果没出现,说明
--permanent命令压根没成功(常见于 zone 名拼错、服务未运行、或用了--zone但当前默认 zone 不是它) -
firewall-cmd --list-all --permanent显示的是内存中暂存的 permanent 规则,不是磁盘实际内容,不可靠
systemd 服务依赖和开机自启陷阱
firewalld 默认启用并设为开机启动,但它的 unit 文件里没有强制要求“先读 permanent 再生效”。某些系统(尤其是 minimal CentOS/RHEL 安装)可能因 firewalld.service 启动过早,或被其他网络服务干扰,导致 --reload 逻辑没跑完。
- 确保服务状态正常:
systemctl is-enabled firewalld应输出enabled;systemctl status firewalld看是否 active (running) - 不要手动改
/usr/lib/systemd/system/firewalld.service加 ExecStartPost,firewalld 自身设计就是靠--reload同步 permanent,硬塞命令反而易出竞态 - 真正保险的做法:所有
--permanent操作后,立刻跟一次--reload,并在部署脚本里把这两步写成原子操作
permanent 规则本身不会自动活过来,它只是个配置仓库;真正让规则在 reboot 后可用的,永远是那一行 firewall-cmd --reload —— 而且得在服务起来之后、且配置已落盘的前提下执行。










