跳转到内容
搜索 RunEntLinux 文档

仅搜索 RunEntLinux 通用文档,各发行版文档使用各自的搜索入口。

    浏览当前文档目录

    Firewalld 进阶

    Firewalld 是 RHEL/CentOS 系列的默认防火墙管理工具。本文将深入介绍 Rich Rules、Direct Rules、自定义区域、端口转发、IP 伪装、ipset 等进阶功能,帮助你构建精细化的网络安全策略。

    Rich Rules 提供了比简单的 --add-port/--add-service 更强大、更灵活的规则定义能力,可以基于源地址、目标地址、端口等条件进行精细控制。

    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]
    Terminal window
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port port="3306" protocol="tcp" accept'
    Terminal window
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.50" drop'
    Terminal window
    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 并记录日志”
    Terminal window
    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'
    Terminal window
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" port port="8080-8090" protocol="tcp" accept'
    Terminal window
    # 查看当前区域的 Rich Rules
    sudo firewall-cmd --list-rich-rules
    # 删除 Rich Rule
    sudo firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="10.0.0.50" drop'
    # 使配置生效
    sudo firewall-cmd --reload

    Direct Rules 允许你直接向 iptables/nftables 后端插入规则,适用于 Rich Rules 无法满足的复杂场景。

    Terminal window
    sudo firewall-cmd --direct --add-rule ipv4 filter INPUT 0 <iptables规则参数>
    Terminal window
    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
    Terminal window
    sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 99 -j LOG --log-prefix "DROPPED: " --log-level 4
    Terminal window
    sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -m mac --mac-source AA:BB:CC:DD:EE:FF -j DROP
    Terminal window
    # 查看所有 Direct Rules
    sudo firewall-cmd --direct --get-all-rules
    # 删除 Direct Rule
    sudo 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 --reload

    Firewalld 内置了 public、trusted、dmz 等区域,但你也可以创建自定义区域来满足特殊需求。

    Terminal window
    # 创建名为 webservers 的区域
    sudo firewall-cmd --permanent --new-zone=webservers
    sudo firewall-cmd --reload
    Terminal window
    # 设置区域描述
    sudo firewall-cmd --permanent --zone=webservers --set-description="Web Server Zone"
    # 添加允许的服务
    sudo firewall-cmd --permanent --zone=webservers --add-service=http
    sudo firewall-cmd --permanent --zone=webservers --add-service=https
    sudo 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
    Terminal window
    # 查看所有区域
    sudo firewall-cmd --get-zones
    # 查看特定区域的详细配置
    sudo firewall-cmd --zone=webservers --list-all
    # 查看所有活动区域
    sudo firewall-cmd --get-active-zones
    # 查看默认区域
    sudo firewall-cmd --get-default-zone
    Terminal window
    sudo firewall-cmd --permanent --delete-zone=webservers
    sudo firewall-cmd --reload

    端口转发可以将到达某个端口的流量重定向到另一个端口或另一台主机。

    将本机的 80 端口转发到 8080 端口:

    Terminal window
    sudo firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080
    sudo firewall-cmd --reload

    将本机 80 端口的流量转发到另一台主机的 8080 端口:

    Terminal window
    # 需要先启用 masquerade
    sudo firewall-cmd --permanent --add-masquerade
    # 添加端口转发规则
    sudo firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=192.168.1.100
    sudo firewall-cmd --reload
    Terminal window
    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
    Terminal window
    sudo firewall-cmd --list-forward-ports
    Terminal window
    sudo firewall-cmd --permanent --remove-forward-port=port=80:proto=tcp:toport=8080
    sudo firewall-cmd --reload

    Masquerading(IP 伪装)是一种特殊的 SNAT(源地址转换),通常用于让内网机器通过防火墙主机访问外网。

    Terminal window
    sudo firewall-cmd --permanent --add-masquerade
    sudo firewall-cmd --reload
    Terminal window
    sudo firewall-cmd --query-masquerade
    Terminal window
    sudo firewall-cmd --permanent --zone=internal --add-masquerade
    sudo firewall-cmd --reload

    使用 Rich Rules 限制 Masquerade 范围

    Section titled “使用 Rich Rules 限制 Masquerade 范围”

    只对特定源网段启用 NAT:

    Terminal window
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" masquerade'
    sudo firewall-cmd --reload

    Masquerade 和端口转发都需要内核的 IP 转发功能:

    Terminal window
    # 临时启用
    sudo sysctl -w net.ipv4.ip_forward=1
    # 永久启用
    echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/ip_forward.conf
    sudo sysctl -p /etc/sysctl.d/ip_forward.conf

    IPSet 允许你定义 IP 地址集合,然后在防火墙规则中引用,适用于需要管理大量 IP 的场景。

    Terminal window
    # 创建 IPv4 地址集合
    sudo firewall-cmd --permanent --new-ipset=blacklist --type=hash:ip
    # 创建支持网段的集合
    sudo firewall-cmd --permanent --new-ipset=trusted_nets --type=hash:net
    Terminal window
    sudo firewall-cmd --permanent --ipset=blacklist --add-entry=203.0.113.50
    sudo firewall-cmd --permanent --ipset=blacklist --add-entry=198.51.100.0/24
    sudo firewall-cmd --permanent --ipset=trusted_nets --add-entry=10.0.0.0/8
    sudo firewall-cmd --reload

    创建 IP 列表文件:

    Terminal window
    cat <<EOF > /tmp/blacklist.txt
    203.0.113.10
    203.0.113.20
    198.51.100.0/24
    EOF

    导入到 IPSet:

    Terminal window
    sudo firewall-cmd --permanent --ipset=blacklist --add-entries-from-file=/tmp/blacklist.txt
    sudo firewall-cmd --reload
    Terminal window
    # 封禁黑名单中所有 IP
    sudo firewall-cmd --permanent --add-rich-rule='rule source ipset="blacklist" drop'
    # 允许白名单中的 IP 访问 SSH
    sudo firewall-cmd --permanent --add-rich-rule='rule source ipset="trusted_nets" service name="ssh" accept'
    sudo firewall-cmd --reload
    Terminal window
    # 查看所有 IPSet
    sudo firewall-cmd --get-ipsets
    # 查看 IPSet 内容
    sudo firewall-cmd --ipset=blacklist --get-entries
    # 移除条目
    sudo firewall-cmd --permanent --ipset=blacklist --remove-entry=203.0.113.50
    # 删除 IPSet
    sudo firewall-cmd --permanent --delete-ipset=blacklist
    sudo firewall-cmd --reload

    防火墙日志对于安全审计和故障排查至关重要。

    Terminal window
    # 记录并放行 SSH 连接(规则以 accept 结尾,记的是「被允许」的连接,不是被拒绝的)
    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调试

    limit value 防止日志泛滥导致磁盘写满:

    频率格式说明
    1/s每秒 1 条
    5/m每分钟 5 条
    10/h每小时 10 条
    100/d每天 100 条
    Terminal window
    # 通过 journalctl 查看
    sudo journalctl -k | grep "FW-DROP"
    # 通过 dmesg 查看
    sudo dmesg | grep "SSH-ACCESS"
    # 查看 messages 日志
    sudo grep "FW-DROP" /var/log/messages

    Firewalld 可以全局记录所有被拒绝的连接:

    Terminal window
    # 查看当前设置
    sudo firewall-cmd --get-log-denied
    # 启用(可选值:all, unicast, broadcast, multicast, off)
    sudo firewall-cmd --set-log-denied=all

    完整实战:构建 Web 服务器防火墙策略

    Section titled “完整实战:构建 Web 服务器防火墙策略”

    以下示例为一台 Web 服务器配置完整的防火墙策略,包含自定义区域、IPSet 白名单、端口转发和日志记录。

    1. 创建管理 IPSet:

      Terminal window
      sudo firewall-cmd --permanent --new-ipset=admin_ips --type=hash:ip
      sudo firewall-cmd --permanent --ipset=admin_ips --add-entry=192.168.1.10
      sudo firewall-cmd --permanent --ipset=admin_ips --add-entry=192.168.1.11
    2. 配置基本的 public 区域规则:

      Terminal window
      # 允许 HTTP 和 HTTPS
      sudo firewall-cmd --permanent --add-service=http
      sudo firewall-cmd --permanent --add-service=https
      # 移除默认的 SSH 服务(后面用 Rich Rule 限制)
      sudo firewall-cmd --permanent --remove-service=ssh
    3. 添加 Rich Rules:

      Terminal window
      # 仅允许管理员 IP 通过 SSH
      sudo 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'
    4. 配置端口转发(HTTP 转发到后端应用):

      Terminal window
      sudo firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080
    5. 应用并验证:

      Terminal window
      sudo firewall-cmd --reload
      sudo firewall-cmd --list-all
      sudo firewall-cmd --list-rich-rules

    通过灵活运用 Rich Rules、IPSet、端口转发和日志功能,可以构建出精细化的防火墙安全策略,在保障业务正常运行的同时有效防御网络威胁。