Rocky 10:接口、源地址与 zone——一次被 REJECT 的排查记录
Rocky Linux 10.2 Server 组虚拟机,firewalld 2.4.0,ens18 由 NetworkManager 管理。
实验:把源地址 192.168.2.2/32 放进新 zone 并放行 8089/tcp,再从该地址访问,记录真实结果与内核链。截图:public/evidence/firewalld/rocky-zone-match.png。
现象:规则写了,连接还是被拒
Section titled “现象:规则写了,连接还是被拒”$ firewall-cmd --get-active-zoneslabzone sources: 192.168.2.2/32public (default) interfaces: ens18$ firewall-cmd --zone=labzone --list-all | grep -E "^ (sources|ports)" sources: 192.168.2.2/32 ports: 8089/tcp从 192.168.2.2 访问:
$ curl -v --max-time 6 http://192.168.2.241:8089/* connect ... failed: No route to hostcurl: (7) Failed to connect ... No route to host0 ms 返回的 No route to host 是 REJECT(ICMP admin-prohibited),不是「网络不通」,也不是防火墙超时丢包。
先分清三种失败
Section titled “先分清三种失败”| 现象 | 含义 | 看哪里 |
|---|---|---|
No route to host,0 ms | 被 REJECT | firewall-cmd --get-active-zones、nft 链 |
Connection timed out,数秒~数十秒 | 被 DROP 或在链路上丢 | 路由、上游 ACL |
Connection refused,0 ms | 端口没人监听 | ss -ltn、服务状态 |
把 REJECT 当链路故障去查网络,是最常见的误判。
内核链给出解释
Section titled “内核链给出解释”$ nft list chain inet firewalld filter_INPUT_POLICIESchain filter_INPUT_POLICIES { ip saddr 192.168.2.2 jump filter_IN_policy_allow-host-ipv6 ip saddr 192.168.2.2 jump filter_IN_labzone ip saddr 192.168.2.2 reject with icmpx admin-prohibited iifname "ens18" jump filter_IN_policy_allow-host-ipv6 iifname "ens18" jump filter_IN_public iifname "ens18" reject with icmpx admin-prohibited}源地址与接口各自成段,每段末尾都有 reject。能生效的只有链上真正命中的那一段,--get-active-zones 列出两个 zone 不代表规则会合并。

接口归属由 NetworkManager 决定
Section titled “接口归属由 NetworkManager 决定”$ firewall-cmd --permanent --zone=public --remove-interface=ens18The interface is under control of NetworkManager, setting zone to default.$ firewall-cmd --reload && firewall-cmd --get-active-zonespublic (default) interfaces: ens18接口的 zone 是 NM 连接属性,--remove-interface 在 NM 接管时不生效,reload 后会被写回默认 zone。
nmcli -g connection.zone connection show lab-static # 先看当前值sudo nmcli connection modify lab-static connection.zone labzonesudo nmcli connection up lab-staticfirewall-cmd --get-active-zones # 确认接口出现在目标 zone 下跨 zone 的精细控制(按源 + 入/出接口组合)用 firewalld 2.x 的 policy,不要和接口归属较劲。
复核三条命令
Section titled “复核三条命令”firewall-cmd --get-active-zones # 谁在 active,靠什么匹配nmcli -g connection.zone connection show <连接名> # NM 侧的真实归属nft list chain inet firewalld filter_INPUT_POLICIES # 内核里的最终顺序- 只看
--list-all不看 active zones:规则在 zone 里,但流量可能压根不走那个 zone; - 把 REJECT 当网络故障:0ms 返回已经说明是策略拒绝;
- 改完不 reload 不核对:NM 会把接口 zone 改回去;
- 在接口 zone 与源 zone 之间反复加规则:先确定流量走哪个 zone,再决定往哪加。
练习:用三条命令定位
Section titled “练习:用三条命令定位”firewall-cmd --get-active-zonesnmcli -g connection.zone connection show lab-staticsudo nft list chain inet firewalld filter_INPUT_POLICIES | head -8检查:
- 接口在哪个 zone 下(第一行的 interfaces 列表);
- NM 报告的 zone 与之一致;
- nft 链里
iifname与ip saddr两段的顺序与 reject 位置; - 结论:本例的流量由接口段处理,源地址 zone 的放行不生效。
常见问题
能不能让接口同时属于两个 zone?
不能。一个接口只属于一个 zone;需要多个来源不同策略时,用 policy 或 rich rule。
改了 nmcli 的 zone 为什么要 up 连接?
zone 是连接属性,重新激活连接才会下发;也可以 firewall-cmd --reload 后复核。
No route to host 一定是防火墙吗?
不一定,但 0ms 返回且端口在监听时,基本就是本机 firewalld 的 REJECT;可用 nft 链确认。
- zone 与 service:/firewalld-zones/
- rich rule:/firewalld-rich-rules/
- direct 与 policy:/firewalld-direct-rules/