firewalld 规则不生效:nftables 后端排查
This content is not available in your language yet.
“我加了端口/服务,还是不通”是 firewalld 最常见的工单。90% 的情况不是规则写错,而是改在了 permanent、没 reload,或者规则加到了非活动 zone。本页给一条可复现的排查顺序。
在 PVE 390 rhel10-lab(RHEL 10.2 x86_64)上实际执行:
sudo dnf -y install firewalldsudo systemctl start firewalldfirewall-cmd --statefirewall-cmd --get-default-zonefirewall-cmd --list-allsudo firewall-cmd --permanent --add-service=httpsudo firewall-cmd --reloadfirewall-cmd --list-servicessudo nft list ruleset | grep -A6 'table inet firewalld'sudo firewall-cmd --permanent --remove-service=httpsudo firewall-cmd --reloadfirewall-cmd --list-servicesE3 记录:plans/content-expansion/evidence/rhel/rhel-firewalld/run.json(9 步,含每步输出 sha256)。
先分清 runtime 与 permanent
Section titled “先分清 runtime 与 permanent”| 操作 | 写哪里 | 何时生效 |
|---|---|---|
firewall-cmd --add-service=http | runtime | 立即,重启/ reload 丢失 |
firewall-cmd --permanent --add-service=http | 配置文件 | --reload 后 |
firewall-cmd --reload | 把 permanent 加载到 runtime | 立即(会丢未保存的 runtime 改动) |
所以顺序必须是:先 --permanent 改,再 --reload;只做前者不会生效。
# 1. 服务在不在firewall-cmd --state # running / not running
# 2. 哪个 zone 在管这个接口firewall-cmd --get-active-zones# public# interfaces: eth0
# 3. 这个 zone 到底放了什么firewall-cmd --list-all# services: cockpit dhcpv6-client ssh
# 4. runtime 的 services/portsfirewall-cmd --list-servicesfirewall-cmd --list-ports
# 5. 内核里实际规则(nftables 后端)sudo nft list ruleset | grep -A6 'table inet firewalld'
# 6. 配置语法自检sudo firewall-cmd --check-config如果 --list-all 有、nft list ruleset 没有,通常是没 reload 或看错 zone;如果两者都有但仍不通,问题在服务监听/路由/上游安全组,不在 firewalld。
$ firewall-cmd --list-allpublic (active) interfaces: eth0 services: cockpit dhcpv6-client ssh
$ sudo firewall-cmd --permanent --add-service=httpsuccess$ sudo firewall-cmd --reloadsuccess$ firewall-cmd --list-servicescockpit dhcpv6-client http sshnftables 后端
Section titled “nftables 后端”$ sudo nft list ruleset | grep -A6 'table inet firewalld'table inet firewalld { flags owner,persist chain mangle_PREROUTING { type filter hook prerouting priority mangle + 10; policy accept; ...RHEL 10 的 firewalld 用 nftables 后端,iptables -L 看不到这些规则;排查要看 nft list ruleset。table inet firewalld 存在,说明 firewalld 已接管。
删除:
sudo firewall-cmd --permanent --remove-service=httpsudo firewall-cmd --reloadfirewall-cmd --list-services# cockpit dhcpv6-client sshsudo systemctl stop firewalldsudo systemctl disable firewalld # 如需-
--state是 running; -
--get-active-zones的接口是你要放行的接口; - permanent 改完是否
--reload; -
--list-all与nft list ruleset是否一致; - 服务本身是否在监听(
ss -lntp); - 上游安全组/路由是否放行。
未实测与边界
Section titled “未实测与边界”- 未测试 rich rule、source/port 转发与 masquerade;
- 未测试
--panic-on与 emergency 模式; - 未测试 firewalld 与 NetworkManager zone 绑定的联动;
- 未测试 IPv6 规则与 direct 规则。
- RHEL 10 NetworkManager 双栈 — 接口与地址
- RHEL 安全基线与加固 — 主机加固
- 官方:Securing networks