先把当时的情况摆出来。CentOS 7.9 上为了放行一个特殊端口的转发,用 firewall-cmd --direct 加了规则,当时生效,机器重启后规则全没了,业务又断了一次。

这类报错背后常见的原因有几处,逐个排除就行。direct 规则默认只写运行时,没带 --permanent 就不会落到配置文件。另一种情况是规则加在了错误的表或链上,重载后被默认策略覆盖。

少数情况下是firewalld 的 direct 语法里 ipv4 和 ipv6 要分别写,漏了一半。不容易想到的是,同时装了 iptables-services,两边都管规则互相冲掉。

上来先看运行时和永久配置里的规则差异

firewall-cmd --direct --get-all-rules && firewall-cmd --permanent --direct --get-all-rules

带上 permanent 重新加一遍

firewall-cmd --permanent --direct --add-rule ipv4 filter FORWARD 0 -i eth0 -j ACCEPT

接着重载并确认规则已进入永久配置

firewall-cmd --reload && firewall-cmd --direct --get-all-rules

末了重启后复查规则还在

systemctl restart firewalld && firewall-cmd --direct --get-all-rules

别只看报错消失,验证要多做一步。重启 firewalld 之后 direct 规则依旧存在,既能从运行时也能从 permanent 列表里查到,业务转发恢复正常。

补一句。能用 zone 和 service 表达的规则不要走 direct,direct 不参与 firewalld 的对象模型,冲突时排查成本很高。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189