AlmaLinux 10:哪个 firewalld zone 生效——源地址 zone 为什么没起作用
AlmaLinux 10.2 Server 组虚拟机,firewalld 2.4.0,接口 ens18 由 NetworkManager 管理。
做法:新建一个按源地址匹配的 zone(源 192.168.2.2/32,放行 8089/tcp),再从 192.168.2.2 访问该端口,观察是否放行;同时用 nft list chain inet firewalld filter_INPUT_POLICIES 看内核里真正的匹配链。截图:public/evidence/firewalld/alma-zone-match.png。
两个 zone 同时 active 是正常的
Section titled “两个 zone 同时 active 是正常的”$ firewall-cmd --get-active-zoneslabzone sources: 192.168.2.2/32public (default) interfaces: ens18一个按 source 匹配,一个按 interface 匹配——两者都列在 active 里。很多人看到这里就以为「源地址 zone 一定优先」,实际要看内核链。
内核里的匹配链才是答案
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。也就是说,即使源地址匹配到了某个 zone,只要该 zone 没有明确接受这条流量,接口那一段的默认拒绝仍会生效。
实测结果:放行了,还是被拒
Section titled “实测结果:放行了,还是被拒”labzone 明确放行该端口:
$ 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 to 192.168.2.241 port 8089 from 192.168.2.2 port 38332 failed: No route to host* Failed to connect to 192.168.2.241 port 8089 after 0 mscurl: (7) Failed to connect ... No route to host同理,从没写进任何 zone 的另一台机器(192.168.2.240)也是立即失败。
判读要点:No route to host 且 0 ms 返回 = 被 REJECT(ICMP admin-prohibited),不是网络不通;超时(十几秒)才是链路问题。

接口的 zone 由 NetworkManager 决定
Section titled “接口的 zone 由 NetworkManager 决定”想把接口从默认 zone 移走时,会遇到这条提示:
$ 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 是 NetworkManager 的连接属性,firewalld 的 --remove-interface 在 NM 接管时改不动,reload 后又被写回默认 zone。
① 用 nmcli 把连接绑到目标 zone
sudo nmcli connection modify lab-static connection.zone labzonesudo nmcli connection up lab-staticfirewall-cmd --get-active-zones # 确认 interfaces: ens18 出现在 labzone 下② 或者用 firewalld 的 policy(2.x 推荐):按 ingress/egress zone 与源地址组合定义规则,不用和接口归属打架。
③ 改完必须复核,看的是这条链而不是文档:
nft list chain inet firewalld filter_INPUT_POLICIES- 看到
--get-active-zones两个 zone 都有就以为规则叠加:实际是「先匹配到的那一段」决定结果; - 把
No route to host当链路故障:0ms 返回是 REJECT; - 只写
--add-source不改接口归属:源地址 zone 的放行未必生效; - reload 后不核对:NM 会把接口 zone 改回默认值,配置看起来「没保存」。
练习:确认接口到底在哪个 zone
Section titled “练习:确认接口到底在哪个 zone”firewall-cmd --get-active-zonesnmcli -g connection.zone connection show lab-staticsudo firewall-cmd --permanent --new-zone=probesudo firewall-cmd --permanent --zone=probe --add-port=8089/tcpsudo firewall-cmd --reloadnft list chain inet firewalld filter_INPUT_POLICIESsudo firewall-cmd --permanent --delete-zone=probesudo firewall-cmd --reload检查:
--get-active-zones里接口出现在哪个 zone 下;nmcli报告的connection.zone与之一致(不一致时以 NM 为准);nft链里能看到iifname "ens18"的 jump 与 reject;- 清理后
--get-active-zones恢复成只有public。
常见问题
源地址 zone 和接口 zone 哪个优先?
不要背结论。用 nft list chain inet firewalld filter_INPUT_POLICIES 看当前主机真实的匹配链,两者都存在时以链上的顺序与 reject 位置为准。
为什么 nmcli 改了 zone 还要 reload?
nmcli 会触发 firewalld 重载;手工改完用 firewall-cmd --reload 更稳妥,然后用 --get-active-zones 复核。
rich rule 能绕过这个问题吗?
rich rule 属于某个 zone,仍受 zone 匹配约束;跨 zone 的精细控制用 policy 更合适。
- zone 基础:/firewalld-zones/
- rich rule:/firewalld-rich-rules/
- direct 与 policy:/firewalld-direct-rules/