firewalld规则没生效需四步确认:一查服务是否真运行且无nftables初始化失败等报错;二验permanent规则是否reload进runtime;三核接口是否绑定到正确zone;四排宝塔自动清理、SELinux或iptables冲突等外部干扰。

firewalld 规则没生效,不是“加了就行”,而是要确认规则写进去了、加载进内存了、落在正确的区域里、没被其他机制悄悄覆盖——四步缺一不可。
确认 firewalld 服务真正在运行且无底层报错
很多问题其实卡在第一步:服务看似在跑,实则已失效。
- 执行 systemctl status firewalld,重点看 Active 是否为 active (running),并滚动到底部查最后几行日志
- 若出现 Failed to initialize nftables backend、Connection refused 或 Zone 'public' not found,说明后端初始化失败,规则根本没加载
- 遇到这类错误,不要直接 restart,先执行 firewall-cmd --reload 强制重载配置,再 systemctl restart firewalld,重启后立刻验证
- 特别注意 CentOS 8+/Rocky 9 等系统使用 nftables 后端,某些宝塔旧版本或手动修改过 /etc/firewalld/firewalld.conf 的环境容易触发初始化失败
区分 permanent 和 runtime,验证规则是否真正落地
加了 --permanent ≠ 规则已生效;不 reload = 白加。这是最常被忽略的逻辑断点。
Linux系统管理专家,覆盖12大模块:用户权限、SSH、存储、网络、systemd、防火墙、日志监控、备份恢复、TLS证书、Ansible、容器、IaC。提供配置、验证、加固、监控、备份、自动化、故障排查、回滚闭环。关键词:useradd、sudo、sshd_config、chmod、SEL...
- 查永久配置:firewall-cmd --permanent --list-ports(或 --list-services、--list-rich-rules)
- 查运行时配置:firewall-cmd --list-ports(不含 --permanent)
- 如果前者有输出、后者为空 → 漏了 firewall-cmd --reload
- 如果两者都有,但端口仍不通 → 问题不在 firewalld 本身,需检查服务监听状态、SELinux、或云平台安全组
- 每次修改 permanent 配置后,必须 reload;reboot 前务必补一次 reload,否则重启后 runtime 清空,只从 permanent 重建——而重建可能因依赖顺序失败
核对 zone 绑定与接口归属
firewalld 是按 zone 工作的,规则加错 zone 或接口不在目标 zone,等于没加。
- 查当前活跃 zone:firewall-cmd --get-active-zones,看你的网卡(如 eth0)属于哪个 zone
- 查默认 zone:firewall-cmd --get-default-zone,新规则默认加到这个 zone
- 若接口在 internal zone,但你往 public zone 加了端口,那完全无效
- 临时把接口划入指定 zone:firewall-cmd --zone=public --add-interface=eth0 --permanent,然后 reload
- 最小化安装系统有时默认 zone 为空或异常,可重置:firewall-cmd --set-default-zone=public
排查外部干扰:宝塔自动清理、SELinux、多防火墙冲突
规则“明明加了却消失”,往往不是 firewalld 的问题,而是它被其他机制动了手脚。
- 宝塔面板 8.x 会周期性检查端口监听状态:若 ss -tlnp | grep :8888 无输出,它会自动删掉对应放行规则。确认 /www/server/panel/data/port.pl 端口一致,并等 bt restart 完全生效后再验证
- 查 SELinux 是否拦截:sestatus,若为 enforcing,临时设宽容模式测试:setenforce 0;若恢复通了,需用 audit2allow 生成策略
- 检查是否与其他防火墙共存:systemctl list-unit-files | grep -E "(iptables|ufw)",若有启用项,停用并禁用:systemctl stop iptables && systemctl disable iptables
- 查看防火墙日志是否有静默丢包:firewall-cmd --set-log-denied=all && firewall-cmd --reload,然后 journalctl -u firewalld | grep DROP

















