Firewalld 进阶
Firewalld 是 RHEL/CentOS 系列的默认防火墙管理工具。本文将深入介绍 Rich Rules、Direct Rules、自定义区域、端口转发、IP 伪装、ipset 等进阶功能,帮助你构建精细化的网络安全策略。
Rich Rules(富规则)
Section titled “Rich Rules(富规则)”Rich Rules 提供了比简单的 --add-port/--add-service 更强大、更灵活的规则定义能力,可以基于源地址、目标地址、端口等条件进行精细控制。
Rich Rules 语法结构
Section titled “Rich Rules 语法结构”rule [family="ipv4|ipv6"] [source address="地址[/掩码]" [invert="true"]] [destination address="地址[/掩码]" [invert="true"]] [service name="服务名" | port port="端口" protocol="tcp|udp" | protocol value="协议" | icmp-block name="类型" | masquerade | forward-port port="端口" protocol="tcp|udp" to-port="端口" [to-addr="地址"]] [log [prefix="前缀"] [level="级别"] [limit value="频率"]] [audit] [accept|reject|drop]常用 Rich Rules 示例
Section titled “常用 Rich Rules 示例”允许特定 IP 访问指定端口
Section titled “允许特定 IP 访问指定端口”sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port port="3306" protocol="tcp" accept'拒绝特定 IP 的所有流量
Section titled “拒绝特定 IP 的所有流量”sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.50" drop'允许子网访问 SSH
Section titled “允许子网访问 SSH”sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept'拒绝特定 IP 访问 HTTP 并记录日志
Section titled “拒绝特定 IP 访问 HTTP 并记录日志”sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" service name="http" log prefix="HTTP-BLOCKED: " level="warning" limit value="5/m" reject'允许特定 IP 范围访问多个端口
Section titled “允许特定 IP 范围访问多个端口”sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" port port="8080-8090" protocol="tcp" accept'管理 Rich Rules
Section titled “管理 Rich Rules”# 查看当前区域的 Rich Rulessudo firewall-cmd --list-rich-rules
# 删除 Rich Rulesudo firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="10.0.0.50" drop'
# 使配置生效sudo firewall-cmd --reloadDirect Rules(直接规则)
Section titled “Direct Rules(直接规则)”Direct Rules 允许你直接向 iptables/nftables 后端插入规则,适用于 Rich Rules 无法满足的复杂场景。
Direct Rules 基本语法
Section titled “Direct Rules 基本语法”sudo firewall-cmd --direct --add-rule ipv4 filter INPUT 0 <iptables规则参数>Direct Rules 示例
Section titled “Direct Rules 示例”限制 ICMP 频率
Section titled “限制 ICMP 频率”sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 4 -j ACCEPT记录所有被丢弃的数据包
Section titled “记录所有被丢弃的数据包”sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 99 -j LOG --log-prefix "DROPPED: " --log-level 4阻止特定 MAC 地址
Section titled “阻止特定 MAC 地址”sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -m mac --mac-source AA:BB:CC:DD:EE:FF -j DROP管理 Direct Rules
Section titled “管理 Direct Rules”# 查看所有 Direct Rulessudo firewall-cmd --direct --get-all-rules
# 删除 Direct Rulesudo firewall-cmd --permanent --direct --remove-rule ipv4 filter INPUT 0 -m mac --mac-source AA:BB:CC:DD:EE:FF -j DROP
sudo firewall-cmd --reloadFirewalld 内置了 public、trusted、dmz 等区域,但你也可以创建自定义区域来满足特殊需求。
创建自定义区域
Section titled “创建自定义区域”# 创建名为 webservers 的区域sudo firewall-cmd --permanent --new-zone=webserverssudo firewall-cmd --reload配置自定义区域
Section titled “配置自定义区域”# 设置区域描述sudo firewall-cmd --permanent --zone=webservers --set-description="Web Server Zone"
# 添加允许的服务sudo firewall-cmd --permanent --zone=webservers --add-service=httpsudo firewall-cmd --permanent --zone=webservers --add-service=httpssudo firewall-cmd --permanent --zone=webservers --add-port=8080/tcp
# 将网络接口绑定到自定义区域sudo firewall-cmd --permanent --zone=webservers --change-interface=eth1
# 将源地址绑定到区域sudo firewall-cmd --permanent --zone=webservers --add-source=10.0.1.0/24
sudo firewall-cmd --reload查看区域信息
Section titled “查看区域信息”# 查看所有区域sudo firewall-cmd --get-zones
# 查看特定区域的详细配置sudo firewall-cmd --zone=webservers --list-all
# 查看所有活动区域sudo firewall-cmd --get-active-zones
# 查看默认区域sudo firewall-cmd --get-default-zone删除自定义区域
Section titled “删除自定义区域”sudo firewall-cmd --permanent --delete-zone=webserverssudo firewall-cmd --reload端口转发可以将到达某个端口的流量重定向到另一个端口或另一台主机。
本地端口转发
Section titled “本地端口转发”将本机的 80 端口转发到 8080 端口:
sudo firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080sudo firewall-cmd --reload转发到远程主机
Section titled “转发到远程主机”将本机 80 端口的流量转发到另一台主机的 8080 端口:
# 需要先启用 masqueradesudo firewall-cmd --permanent --add-masquerade
# 添加端口转发规则sudo firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=192.168.1.100sudo firewall-cmd --reload使用 Rich Rules 做端口转发
Section titled “使用 Rich Rules 做端口转发”sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" forward-port port="443" protocol="tcp" to-port="8443" to-addr="192.168.1.100"'sudo firewall-cmd --reload查看端口转发规则
Section titled “查看端口转发规则”sudo firewall-cmd --list-forward-ports删除端口转发规则
Section titled “删除端口转发规则”sudo firewall-cmd --permanent --remove-forward-port=port=80:proto=tcp:toport=8080sudo firewall-cmd --reloadIP 伪装(Masquerading)
Section titled “IP 伪装(Masquerading)”Masquerading(IP 伪装)是一种特殊的 SNAT(源地址转换),通常用于让内网机器通过防火墙主机访问外网。
启用 Masquerade
Section titled “启用 Masquerade”sudo firewall-cmd --permanent --add-masqueradesudo firewall-cmd --reload检查 Masquerade 状态
Section titled “检查 Masquerade 状态”sudo firewall-cmd --query-masquerade在指定区域启用 Masquerade
Section titled “在指定区域启用 Masquerade”sudo firewall-cmd --permanent --zone=internal --add-masqueradesudo firewall-cmd --reload使用 Rich Rules 限制 Masquerade 范围
Section titled “使用 Rich Rules 限制 Masquerade 范围”只对特定源网段启用 NAT:
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" masquerade'sudo firewall-cmd --reload启用内核 IP 转发
Section titled “启用内核 IP 转发”Masquerade 和端口转发都需要内核的 IP 转发功能:
# 临时启用sudo sysctl -w net.ipv4.ip_forward=1
# 永久启用echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/ip_forward.confsudo sysctl -p /etc/sysctl.d/ip_forward.confIPSet 允许你定义 IP 地址集合,然后在防火墙规则中引用,适用于需要管理大量 IP 的场景。
创建 IPSet
Section titled “创建 IPSet”# 创建 IPv4 地址集合sudo firewall-cmd --permanent --new-ipset=blacklist --type=hash:ip
# 创建支持网段的集合sudo firewall-cmd --permanent --new-ipset=trusted_nets --type=hash:net添加 IP 到 IPSet
Section titled “添加 IP 到 IPSet”sudo firewall-cmd --permanent --ipset=blacklist --add-entry=203.0.113.50sudo firewall-cmd --permanent --ipset=blacklist --add-entry=198.51.100.0/24sudo firewall-cmd --permanent --ipset=trusted_nets --add-entry=10.0.0.0/8sudo firewall-cmd --reload从文件批量导入
Section titled “从文件批量导入”创建 IP 列表文件:
cat <<EOF > /tmp/blacklist.txt203.0.113.10203.0.113.20198.51.100.0/24EOF导入到 IPSet:
sudo firewall-cmd --permanent --ipset=blacklist --add-entries-from-file=/tmp/blacklist.txtsudo firewall-cmd --reload在 Rich Rules 中使用 IPSet
Section titled “在 Rich Rules 中使用 IPSet”# 封禁黑名单中所有 IPsudo firewall-cmd --permanent --add-rich-rule='rule source ipset="blacklist" drop'
# 允许白名单中的 IP 访问 SSHsudo firewall-cmd --permanent --add-rich-rule='rule source ipset="trusted_nets" service name="ssh" accept'
sudo firewall-cmd --reload管理 IPSet
Section titled “管理 IPSet”# 查看所有 IPSetsudo firewall-cmd --get-ipsets
# 查看 IPSet 内容sudo firewall-cmd --ipset=blacklist --get-entries
# 移除条目sudo firewall-cmd --permanent --ipset=blacklist --remove-entry=203.0.113.50
# 删除 IPSetsudo firewall-cmd --permanent --delete-ipset=blacklistsudo firewall-cmd --reload防火墙日志对于安全审计和故障排查至关重要。
使用 Rich Rules 记录日志
Section titled “使用 Rich Rules 记录日志”# 记录被拒绝的 SSH 连接sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" service name="ssh" log prefix="SSH-ACCESS: " level="notice" limit value="3/m" accept'
# 记录被丢弃的流量sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" log prefix="FW-DROP: " level="warning" limit value="10/m" drop'
sudo firewall-cmd --reload| 级别 | 说明 |
|---|---|
emerg | 紧急 |
alert | 警报 |
crit | 严重 |
error | 错误 |
warning | 警告 |
notice | 通知 |
info | 信息 |
debug | 调试 |
限制日志频率
Section titled “限制日志频率”limit value 防止日志泛滥导致磁盘写满:
| 频率格式 | 说明 |
|---|---|
1/s | 每秒 1 条 |
5/m | 每分钟 5 条 |
10/h | 每小时 10 条 |
100/d | 每天 100 条 |
查看防火墙日志
Section titled “查看防火墙日志”# 通过 journalctl 查看sudo journalctl -k | grep "FW-DROP"
# 通过 dmesg 查看sudo dmesg | grep "SSH-ACCESS"
# 查看 messages 日志sudo grep "FW-DROP" /var/log/messages设置 LogDenied
Section titled “设置 LogDenied”Firewalld 可以全局记录所有被拒绝的连接:
# 查看当前设置sudo firewall-cmd --get-log-denied
# 启用(可选值:all, unicast, broadcast, multicast, off)sudo firewall-cmd --set-log-denied=all完整实战:构建 Web 服务器防火墙策略
Section titled “完整实战:构建 Web 服务器防火墙策略”以下示例为一台 Web 服务器配置完整的防火墙策略,包含自定义区域、IPSet 白名单、端口转发和日志记录。
-
创建管理 IPSet:
Terminal window sudo firewall-cmd --permanent --new-ipset=admin_ips --type=hash:ipsudo firewall-cmd --permanent --ipset=admin_ips --add-entry=192.168.1.10sudo firewall-cmd --permanent --ipset=admin_ips --add-entry=192.168.1.11 -
配置基本的 public 区域规则:
Terminal window # 允许 HTTP 和 HTTPSsudo firewall-cmd --permanent --add-service=httpsudo firewall-cmd --permanent --add-service=https# 移除默认的 SSH 服务(后面用 Rich Rule 限制)sudo firewall-cmd --permanent --remove-service=ssh -
添加 Rich Rules:
Terminal window # 仅允许管理员 IP 通过 SSHsudo firewall-cmd --permanent --add-rich-rule='rule source ipset="admin_ips" service name="ssh" accept'# 记录并丢弃其他 SSH 尝试sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" service name="ssh" log prefix="SSH-DENIED: " level="warning" limit value="3/m" drop'# 记录 HTTP 访问(采样)sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" service name="http" log prefix="HTTP: " level="info" limit value="1/m" accept' -
配置端口转发(HTTP 转发到后端应用):
Terminal window sudo firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080 -
应用并验证:
Terminal window sudo firewall-cmd --reloadsudo firewall-cmd --list-allsudo firewall-cmd --list-rich-rules
通过灵活运用 Rich Rules、IPSet、端口转发和日志功能,可以构建出精细化的防火墙安全策略,在保障业务正常运行的同时有效防御网络威胁。