在 CentOS 7 中,所谓的“默认拦截规则”并不是某一条独立的防火墙规则单独生效,而是由 firewalld 的 default_zone(例如 public)及其对应的 target(默认通常为 default)共同决定的:凡是已经明确加入白名单的服务和端口会被允许访问,未被放行的其他流量则会被直接拒绝。想修改这套防火墙默认拦截逻辑,需要通过 firewall-cmd 调整 zone target,或增删 service、port、rich rule;另外还有一个关键细节不能忽略,必须配合 --permanent 和 --reload,修改后规则才会真正生效。

CentOS 7 里常说的“默认拦截规则”,并不是一条可以直接单独修改的语句。它本质上是由 firewalld 的 zone 默认策略组合形成的,也就是 default_zone + target,再叠加链级别的默认动作共同决定。简单来说,在动手修改 CentOS 7 防火墙默认拦截规则之前,必须先搞清楚自己要调整的是“入站默认拒绝”这类行为,还是“某个 zone 的默认放行逻辑”;如果这一步判断不清,很容易一操作就把 SSH 远程连接直接中断。
firewalld 的 default_zone 和 target 决定默认拦截规则的起点
firewalld 与 iptables 的工作方式不同,它不像 iptables 那样直接存在显式的 INPUT DROP 规则。CentOS 7 防火墙的“默认拦截”主要来自两层机制:
default_zone(例如public)的target值,默认通常是default,可以理解为“只允许白名单中的服务或端口通过,其余流量默认拒绝”- 底层 netfilter 链的默认策略仍然是
ACCEPT,但 firewalld 会通过 rich rule 或 zone 配置在 runtime 中插入隐式拒绝逻辑,从而实现默认拦截效果
因此,不能简单地通过修改 /etc/firewalld/zones/public.xml 中某一行来“关闭默认拦截”,而应该从 zone 的 target 或 zone 切换方式入手。
例如把 public zone 的 target 改成 ACCEPT(非常不推荐):
sudo firewall-cmd --permanent --zone=public --set-target=ACCEPT sudo firewall-cmd --reload
⚠️ 这样会让所有未被显式拒绝的入站连接都被接受——基本等同于关闭 CentOS 7 防火墙的默认过滤逻辑,只剩下基础链控制。
真正可控的默认拦截行为,在 zone 的 target 与 service/port 白名单中
日常管理中,能够安全调整的其实是 zone 的“白名单范围”,而不是简单理解的“默认拦截开关”。常见且更推荐的操作方式包括:
- 使用
firewall-cmd --add-service=xxx --permanent添加预定义服务(如http、mysql),这些服务通常自带端口、协议以及辅助模块(如 conntrack) - 使用
firewall-cmd --add-port=3306/tcp --permanent开放指定单端口,但不会自动附带服务级说明;不过 RELATED/ESTABLISHED 流量 firewalld 默认已处理 - 使用
firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" accept' --permanent做基于源 IP 的精确放行,这种方式通常比直接修改 target 更安全、更细粒度
需要特别注意:--permanent 必须结合 --reload 一起使用才会生效;遗漏 --reload,是 CentOS 7 修改防火墙规则后“看起来没生效”的最常见原因之一。
如果想绕过 firewalld 默认拦截,别急着停服务,优先考虑切换 zone
如果你的场景需要临时开放大量端口,或者涉及动态端口段(例如 Docker、K8s 等环境),不要直接停止 firewalld 服务,也不建议贸然切回 iptables,更稳妥的方式是:
- 新建一个相对宽松的 zone:
sudo firewall-cmd --permanent --new-zone=trusted-internal - 将其 target 设置为
ACCEPT:sudo firewall-cmd --permanent --zone=trusted-internal --set-target=ACCEPT - 把内网网卡绑定到该 zone:
sudo firewall-cmd --permanent --zone=trusted-internal --change-interface=eth1 sudo firewall-cmd --reload
这样一来,外网流量仍然走 public(默认拦截),而内网流量则走新建的 zone(默认放行),隔离边界更清晰、风险更可控。相比之下,直接执行 systemctl stop firewalld 会丢失所有 zone 状态,系统重启后还可能因为网络脚本再次自动拉起服务,最终导致防火墙策略漂移。
修改配置文件前,一定要确认改的是 permanent 配置,而不是 runtime
firewalld 区分 runtime(当前正在生效)和 permanent(重启后仍保留)两套配置。直接编辑 /etc/firewalld/zones/public.xml 只会影响 permanent 配置,并不会自动同步到 runtime —— 必须手动执行 --reload,否则即使文件已经改了,firewall-cmd --list-all 看到的依然可能是旧规则。
更需要警惕的是:如果 XML 文件格式写错(例如少了闭合标签、属性值缺少引号),--reload 会失败,并回退到上一次有效配置,但错误提示通常只记录在 journal 日志中:journalctl -u firewalld | tail -20。很多人不查看日志,就会误以为“CentOS 7 防火墙默认拦截规则修改没有反应”,实际上是 firewalld 已经静默拒绝了这次 reload 请求。
