AlmaLinux 10:为什么 iptables -L 看不到 firewalld 的规则
AlmaLinux 10.2 虚拟机(最小化安装),实测组件版本:
| 组件 | 版本 |
|---|---|
| firewalld | 2.4.0-1.el10_1 |
| nftables | 1.1.5-3.el10 |
| iptables-nft | 1.8.11-13.el10_1 |
截图与结论都来自同一台机器:public/evidence/nftables/alma-iptables-vs-nft.png。
后端是显式配置项
Section titled “后端是显式配置项”$ grep -E "^FirewallBackend" /etc/firewalld/firewalld.confFirewallBackend=nftables配置文件里同时写着:
# Choices are:# - nftables (default)# - iptables (iptables, ip6tables, ebtables and ipset)# Note: The iptables backend is deprecated. It will be removed in a future release.也就是说 iptables 后端在 EL10 上还能选但已废弃,默认值是 nftables。
两套规则表互不可见
Section titled “两套规则表互不可见”firewalld 把规则写进自己的 nftables 表:
$ nft list tablestable inet firewalld而 iptables 命令在 EL10 是 iptables-nft(/usr/sbin/iptables 是 alternatives 软链,实体由 iptables-nft 包提供),它只操作 table ip filter 之类的独立表:
$ iptables -nLChain INPUT (policy ACCEPT)target prot opt source destination
Chain FORWARD (policy ACCEPT)...看起来「没有任何规则」,其实 firewalld 的规则全在另一张表里。这不是权限问题,也不是防火墙没启动,而是两条互不相通的写路径。
加一条规则,看两边反应
Section titled “加一条规则,看两边反应”$ firewall-cmd --add-service=httpsuccess
$ iptables -nL | grep -c 'dpt:80'0
$ nft list chain inet firewalld filter_IN_public_allowtable inet firewalld { chain filter_IN_public_allow { tcp dport 22 accept ip6 daddr fe80::/64 udp dport 546 accept tcp dport 9090 accept ip saddr 10.0.0.0/24 tcp dport 8443 accept tcp dport 80 accept }}tcp dport 80 accept 只出现在 nft 侧。任何用 iptables -L 检查 firewalld 放行是否生效的做法,在 EL10 上都会得出错误结论。

正确查看方式
Section titled “正确查看方式”| 目的 | 命令 |
|---|---|
| 看放行了什么(推荐) | firewall-cmd --list-all |
| 看某条链的原始规则 | nft list chain inet firewalld filter_IN_public_allow |
| 看全部 nft 规则 | nft list ruleset |
| 看接口属于哪个 zone | firewall-cmd --get-active-zones |
firewall-cmd --list-all 与 nft 输出是同一份数据的两种视角;排查时先用前者(可读),需要看计数器或判断顺序时再用后者。
什么时候还会碰到 iptables
Section titled “什么时候还会碰到 iptables”- 旧运维脚本
iptables -A INPUT -p tcp --dport 8080 -j ACCEPT:在 nft 后端下依然能执行,但规则进了 iptables-nft 自己的表,firewalld reload 不会清掉它,两套规则各管一段,很容易相互覆盖; - 容器运行时(podman/docker)会插入自己的 nft 表,排障时
nft list tables能看到多张; - 第三方安全软件可能只认 iptables 命令。
结论:能做,但不要和 firewalld 混着写。
iptables -L空 = 防火墙没开? 错,先firewall-cmd --state;- 加了
iptables规则以为绕过 firewalld:其实两套表都在生效,谁先匹配取决于 hook 优先级,很难推理; systemctl restart firewalld后自己的 iptables 规则还在:它们不在 firewalld 管理的表里;- 把
FirewallBackend改成 iptables「求稳」:该后端已标注废弃,未来版本会移除。
练习:验证两套表
Section titled “练习:验证两套表”nft list tablessudo iptables -nL | head -5sudo firewall-cmd --add-service=httpsudo nft list chain inet firewalld filter_IN_public_allow | grep -c "dport 80"sudo iptables -nL | grep -c "dpt:80"sudo firewall-cmd --remove-service=http检查:
nft list tables至少有一张inet firewalld;- 加 http 后 nft 侧能 grep 到
dport 80,iptables 侧计数仍为 0; - 最后用
--remove-service撤销,保持机器干净。
常见问题
能同时用 iptables 和 firewalld 吗?
技术上可以,规则进不同的表;但排障成本高,生产上建议只用一种入口(firewalld 的 rich rule / direct 规则已能覆盖大多数需求)。
nft 的输出看不懂怎么办?
先用 firewall-cmd --list-all 得到人可读的结论,再用 nft 看具体链和计数器;两者是同一份规则的两种视角。
direct 规则走哪条路径?
firewalld 的 --direct 规则会被翻译进同一张 inet firewalld 表,因此 iptables -L 依然看不到。
- zone 与放行:/firewalld-zones/
- rich rule 精确匹配:/firewalld-rich-rules/
- 离线环境安装:/offline-updates/