firewalld规则不生效或重启后丢失,主因是未执行--reload、--permanent缺失、XML语法错误、rich-rule误用普通端口命令、服务未启用或配置未绑定zone。

firewalld 是 CentOS 7 默认的防火墙管理工具,修改策略不是改一行配置就完事——它分「命令行实时操作」和「手动编辑 XML 文件」两种路径,但二者行为不完全等价,容易导致规则不生效或重启后丢失。
用 firewall-cmd --permanent 添加端口时必须 reload
直接执行 firewall-cmd --permanent --add-port=6379/tcp 只会写入配置文件(如 /etc/firewalld/zones/public.xml),不会立即生效。常见错误是加完就去连 Redis,结果连不上。
- 必须跟上
firewall-cmd --reload才加载新规则到运行时 -
--permanent缺失会导致重启后规则消失;只加不加该参数,规则仅当前会话有效 - 如果
firewall-cmd --reload报错(比如 XML 格式损坏),整个防火墙可能拒绝所有连接,建议先备份:cp /etc/firewalld/zones/public.xml{,.bak}
手动改 public.xml 后不能只 systemctl restart firewalld
很多人编辑完 /etc/firewalld/zones/public.xml 就直接 systemctl restart firewalld,结果发现规则没加载——因为 firewalld 服务重启时并不强制重读所有 zone 文件,尤其当有语法错误或缓存残留时。
CentOS Linux 7.9.2009是传统CentOS Linux 7的最后主要版本,也是很多企业历史服务器中仍可能遇到的系统版本。它以稳定、兼容RHEL 7生态、文档丰富和软件支持广泛著称,曾长期用于Web服务、数据库、虚拟化节点和企业内部业务系统。不过CentOS Linux 7已于2024年6月30日停止维护,现在继续使用会面临安全补丁缺失风险。该版本更适合旧业务迁移、历史环境恢复或离
- 推荐做法:先
firewall-cmd --reload,它会校验 XML 并热加载;失败时会明确提示哪行出错 - 若执意用
systemctl restart firewalld,需确认服务真正启动成功:systemctl status firewalld中状态为active (running),且无Failed to load类日志 - 注意:手动添加的
<port>标签必须在<zone>根节点内,且属性顺序无关,但protocol和port属性名不能拼错(如写成protcol就静默忽略)
限制某 IP 访问指定端口要用 rich-rule,不是 --add-port
想让只有 192.168.1.100 能连 3306?别用 --add-port=3306/tcp,那是全放开。得用富规则(rich rule)。
- 正确命令:
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port port="3306" protocol="tcp" accept' - 单引号必须包裹整条规则,内部双引号不能省;
accept末尾不能加分号或逗号 - 这条规则和普通端口规则互不影响:即使你删了
3306的开放端口,只要 rich-rule 存在,该 IP 仍可访问 - 查是否生效:
firewall-cmd --list-all --zone=public里会显示rules段,而不是ports段
规则冲突时,rich-rule 优先级高于普通端口规则
如果你既开了 --add-port=8080/tcp,又加了 rich-rule 拒绝某个 IP 访问 8080,后者会生效。但反过来——先加 rich-rule 放通某 IP 的 22,再用 --remove-port=22/tcp ——不会影响 rich-rule 的效果。
- firewalld 规则匹配是“自上而下”,rich-rule 插入位置由 firewalld 内部决定,用户不可控
- 最稳妥的调试方式:
firewall-cmd --list-all-zones看所有 zone 的完整输出,确认目标规则确实出现在对应 zone 下 - 生产环境别依赖“先删后加”,用
--query-rich-rule=...和--remove-rich-rule=...显式管理,避免残留
--permanent 操作不验证端口是否真实存在、服务是否监听,它只管写配置。所以即使你开放了 9999/tcp,但应用根本没监听,外部依然连不通——这时候问题不在防火墙,而在服务本身。

















