`firewall-cmd` 的富规则(Rich Rules)是 firewalld 防火墙中最强大、最灵活的功能之一。它允许你编写非常具体和复杂的防火墙规则,这些规则通过基本的 `--add-port` 或 `--add-service` 命令无法实现。 下面我将对富规则进行详细的详解。 ### 什么是富规则? 富规则提供了一种表达性语言,让你可以设置比普通规则更复杂的规则。你可以基于以下条件来允许或拒绝流量: * **源/目标 IP 地址**(单个 IP、IP 范围、IP 集) * **端口**(单个端口、端口范围) * **协议** * **日志** * **限制连接速率** * **网络接口/区域** * **动作**(接受、拒绝、丢弃、记录) --- ### 基本语法结构 一条完整的富规则通常遵循以下逻辑结构: ```bash rule [family="ipv4|ipv6"] [source|destination address="" [invert="True"]] [service name=""] [port port="" protocol=""] [protocol value=""] [log [prefix=""] [level=""]] [limit value="/"] [accept | reject [type=""] | drop | mark set=""] ``` **注意:** 你不需要在一个规则中使用所有选项,而是根据你的需求组合它们。 --- ### 核心参数详解 #### 1. 规则家族 (`family`) * 指定规则是针对 IPv4 还是 IPv6。 * `family="ipv4"`(默认,可省略) * `family="ipv6"` #### 2. 源/目标地址 (`source` / `destination`) * **`source address`**: 匹配流量的**源 IP 地址**。 * **`destination address`**: 匹配流量的**目标 IP 地址**。 * 可以指定单个 IP (`192.168.1.100`)、CIDR 网段 (`192.168.1.0/24`) 或预定义的 IP 集。 * `invert="True"` 表示反向匹配(即,除了这个地址以外的所有地址)。 #### 3. 服务与端口 * **`service name`**: 使用预定义的服务(如 `ssh`, `http`, `https`)。这比指定端口更安全、更方便。 * **`port`**: 直接指定端口号和协议。`port port="8080" protocol="tcp"`。也支持端口范围:`port port="8080-8090" protocol="tcp"`。 #### 4. 协议 (`protocol`) * 直接指定 IP 协议编号或名称。 * `protocol value="icmp"` * `protocol value="ipv6-icmp"` * `protocol value="50"` (ESP 协议) #### 5. 动作 (`action`) * **`accept`**: 允许数据包通过。 * **`reject`**: 拒绝数据包,并向发送方返回一个拒绝消息(如 `icmp-host-prohibited`)。 * 可以指定拒绝类型:`reject type="icmp-host-prohibited"`。 * **`drop`**: silently 丢弃数据包,不发送任何回复。更安全,但对方会认为网络不通。 * **`mark`**: 给数据包打上标记,用于后续更复杂的策略路由。 #### 6. 日志 (`log`) 和限速 (`limit`) * **`log`**: 记录匹配此规则的数据包。 * `prefix="SSH attempt: "`: 在日志消息前添加自定义前缀,便于识别。 * `level="debug|info|notice|warning|err|crit|alert|emerg"`: 定义日志级别。 * **`limit`**: 限制日志记录或规则匹配的速率,防止日志爆炸。 * `limit value="3/m"`: 每分钟最多记录 3 次。 * `limit value="30/s"`: 每秒最多 30 次。 --- ### 常用命令 在添加、删除或查询规则时,务必指定区域(`--zone`),如果不指定,则默认为 `public` 区域。**所有修改操作都需要 `--permanent` 参数或 `--runtime-to-permanent` 才能永久生效。** #### 添加富规则 ```bash sudo firewall-cmd [--zone=] --add-rich-rule='' ``` #### 删除富规则 ```bash sudo firewall-cmd [--zone=] --remove-rich-rule='' ``` #### 列出所有富规则 ```bash sudo firewall-cmd [--zone=] --list-rich-rules ``` #### 使规则永久生效 如果添加时使用了 `--permanent`,则需要重载防火墙: ```bash sudo firewall-cmd --reload ``` 如果添加时没有使用 `--permanent`(即运行时规则),可以将其转换为永久规则: ```bash sudo firewall-cmd --runtime-to-permanent ``` --- ### 实用示例 #### 示例 1:允许特定 IP 访问 SSH 允许 IP 地址 `192.168.1.100` 访问本机的 SSH 服务(22 端口)。 ```bash sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" service name="ssh" accept' ``` #### 示例 2:拒绝某个 IP 段访问 HTTP 拒绝网段 `10.0.0.0/24` 访问本机的 HTTP 服务(80 端口)。 ```bash sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" service name="http" reject' ``` #### 示例 3:限制 SSH 连接速率并记录日志 每分钟只允许从一个 IP 地址建立 2 个新的 SSH 连接,超过的连接将被丢弃,并记录日志。 ```bash sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.50" service name="ssh" limit value="2/m" accept' sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.50" service name="ssh" log prefix="SSH DROPPED: " level="warning" drop' ``` *解释:第一条规则允许每分钟前 2 次连接。第二条规则对来自同一 IP 的其他 SSH 连接进行丢弃并记录日志。* #### 示例 4:允许来自任何地方 ping (ICMP),但记录并限制日志 允许 ICMP 请求,但每秒最多只记录 1 次。 ```bash sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" protocol value="icmp" log prefix="PING: " level="info" limit value="1/s" accept' ``` #### 示例 5:将流量转发到其他地址(端口转发) 这不是严格的富规则,但常与富规则结合使用。将到达本机 80 端口的流量转发到内部服务器 `192.168.1.200` 的 8080 端口。 ```bash # 1. 开启防火墙的伪装(MASQUERADE) sudo firewall-cmd --permanent --add-masquerade # 2. 添加端口转发规则 sudo firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=192.168.1.200 ``` 如果需要更精细的控制(如只转发来自特定 IP 的流量),就需要结合富规则和直接规则,这超出了富规则的基本范畴。 --- ### 规则优先级 理解 firewalld 的规则优先级非常重要: 1. **直接规则(Direct Rules)** 2. **富规则(Rich Rules)** 3. **预定义的服务(如 `--add-service`)** 4. **端口(如 `--add-port`)** **规则是按顺序匹配的,一旦匹配成功,就不再继续检查后面的规则。** 因此,更具体的规则(如富规则)应该先被匹配,通用的规则(如开放端口)在后。 ### 总结 富规则是 firewalld 的精髓,它提供了企业级的防火墙策略配置能力。关键点在于: * **组合使用**:将源/目标 IP、端口/服务、日志、限速等条件灵活组合。 * **明确动作**:清楚 `accept`, `reject`, `drop` 的区别。 * **注意区域和永久生效**:确保规则添加到正确的区域,并记得使其永久生效。 * **测试**:在应用新规则后,务必从客户端进行测试,确保规则按预期工作。 建议在生产环境中应用任何规则之前,先在测试环境中验证,并确保你有一个活动的会话(例如,不是通过 SSH 在你要配置的服务器上操作),以防止意外将自己锁在外面。 # 富规则案例 # 富规则 - 目的地址端口为本机 firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source ipset="test1" sport port="1522" port port="235" protocol="tcp" accept' # 富规则 - 目的地址为本机 firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source ipset="test1" sport port="1522" destination address="192.168.10.5" port port="235" protocol="tcp" accept' # 富规则 - 端口转发 firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" forward-port port="11123" protocol="tcp" to-port="1123" to-addr="192.168.10.5"'