firewalld富规则是实现细粒度流量控制的高级机制,用于处理源ip、目的端口、协议、限速、日志等多条件组合场景,当基础service/port规则无法满足需求时必须使用。

firewalld富规则是什么,什么时候必须用它
富规则(rich rule)是 firewalld 提供的高级语法,用于表达比基础服务/端口更细粒度的控制逻辑,比如“只允许某IP在工作时间访问SSH”或“对特定源IP限速”。普通 --add-service 或 --add-port 无法实现这类条件组合,这时就得写富规则。
它不是替代基础规则的工具,而是补位——当 firewall-cmd --add-service=ssh 不够用时才上。误用富规则反而增加维护成本,也容易因语法错误导致整条规则失效。
富规则怎么写:结构、参数和常见错误
富规则本质是一段带引号的 XML 风格字符串,通过 --add-rich-rule 注入。核心结构固定为:rule [family="ipv4|ipv6"] source address="x.x.x.x[/mask]" [destination address="..."] service name="..." port port="..." protocol="tcp|udp" log [prefix="..."] limit value="..." accept|reject|drop
常见踩坑点:
-
source和destination必须显式指定family,否则默认 ipv4,但若混用 IPv6 地址会静默失败 - 限速必须配合
log或动作使用,单独写limit value="10/s"不生效 - 多个条件要写在同一行引号内,不能拆成多条
--add-rich-rule;否则后一条会覆盖前一条(firewalld 不支持“追加条件”,只支持“追加整条规则”) - 日志前缀
prefix不能含空格或特殊字符,否则firewall-cmd报错Invalid argument
示例:限制某IP每分钟最多5次SSH新连接,并记录日志:
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.45" service name="ssh" limit value="5/m" log prefix="ssh-brute-" accept'
富规则如何持久化与调试
富规则默认只作用于 runtime,必须加 --permanent 才写入磁盘配置。但即使加了,也不自动生效——你得手动 firewall-cmd --reload,否则规则还在内存里睡大觉。
调试时别只信 --list-all,它不显示富规则细节。正确做法是:
- 查是否已存入配置:
sudo firewall-cmd --permanent --list-rich-rules - 确认当前运行时是否加载:
sudo firewall-cmd --list-rich-rules(两者输出应一致) - 看日志是否触发:
sudo journalctl -u firewalld | grep "ssh-brute"(前提是规则里写了log) - 删错规则别用编号:富规则没有行号,只能靠完整内容匹配删除,例如:
sudo firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="203.0.113.45" service name="ssh" log prefix="ssh-brute-" accept'
富规则和 iptables 规则能共存吗
不能混用。firewalld 底层调用的是 nftables(RHEL 8+/CentOS 8+)或 iptables(旧版),但它的规则管理是原子性的——一旦启用 firewalld,就该让它全权负责,手工改 iptables 或直接写 nft 规则会导致状态不一致,firewall-cmd --reload 可能清掉你手写的规则,或者反过来,firewalld 的 reload 失败。
如果已有 iptables 脚本,迁移路径只有一条:把原规则逻辑重写为等效的富规则或 direct rule(--direct),再导入 firewalld。试图“两边都管一点”,最后一定是策略打架、排查困难。
真正容易被忽略的是:富规则里的 accept / drop 动作,其行为严格依赖所在 zone 的默认策略。比如 public 区默认是 target: default(即隐式拒绝),但如果你把富规则加到 trusted zone,那 same rule 就可能意外放行不该放的流量——zone 语义永远优先于单条规则。











