firewalld富规则需明确“谁、从哪来、想连什么、怎么处理”四要素:必须指定family、source、port+protocol、action;多端口需拆分规则;建议为敏感端口添加log+limit增强可观测性。

用 firewalld 富规则做源IP + 端口的复合控制,关键不是堆条件,而是把“谁、从哪来、想连什么、怎么处理”这四件事说清楚。它不依赖 iptables 语法,但逻辑必须严谨——漏写 family 或拼错 action,规则就无效。
明确目标流量特征
富规则必须显式声明匹配维度,缺一不可:
-
地址族:99% 场景用
family="ipv4",IPv6 需单独配置 -
源地址:支持单 IP(
source address="192.168.5.22")或网段(source address="10.20.0.0/16") -
目标端口与协议:必须同时指定
port port="8082" protocol="tcp",只写端口不写协议会报错 -
动作类型:
accept(放行)、reject(拒绝并回提示)、drop(静默丢弃)三者语义不同,不能混用
编写可持久生效的白名单规则
比如只允许办公网 172.16.10.0/24 访问本机 SSH(22/tcp)和后台 API(8080/tcp):
sudo firewall-cmd --permanent --zone=public \ --add-rich-rule='rule family="ipv4" source address="172.16.10.0/24" port port="22" protocol="tcp" accept' sudo firewall-cmd --permanent --zone=public \ --add-rich-rule='rule family="ipv4" source address="172.16.10.0/24" port port="8080" protocol="tcp" accept'
注意:每条规则只能定义一个端口;多个端口需拆成多条规则。不要试图写成 port port="22,8080",firewalld 不支持这种写法。
叠加日志与限速增强可观测性
对高敏感端口(如数据库管理端口 3306),建议加日志+限速双保险:
sudo firewall-cmd --permanent --zone=public \
--add-rich-rule='rule family="ipv4" source address="192.168.1.100" port port="3306" protocol="tcp" \
log prefix="mysql-access" level="info" limit value="5/m" accept'
这条规则含义是:仅允许 192.168.1.100 连 3306/tcp,每次匹配都记日志(带前缀),且每分钟最多记录 5 条,超出的日志被抑制。既满足审计要求,又避免日志刷爆磁盘。
快速验证与排错要点
规则加完不生效?按顺序检查这几项:
- 是否用了
--permanent?没加则重启后丢失;加了必须执行sudo firewall-cmd --reload - 是否指定了正确区域?用
sudo firewall-cmd --get-active-zones确认接口归属,再用--list-rich-rules --zone=xxx查对应区域规则 - 是否被更宽泛的规则覆盖?富规则按添加顺序匹配,但最终受区域默认策略影响。例如 public 区域默认
target: default,若已有全局 accept 规则,你的限制规则可能被跳过 - 测试时用
telnet IP PORT或nc -zv IP PORT,别只看端口开放状态,要确认实际连接行为是否符合预期

















