8.7. 示例:使用 nftables 脚本保护 LAN 和 DMZ


使用 RHEL 路由器上的 nftables 框架来编写和安装防火墙脚本,来保护内部 LAN 中的网络客户端和 DMZ 中的 Web 服务器免受来自互联网和其他网络的未授权访问。

重要

这个示例仅用于演示目的,描述了一个具有特定要求的场景。

防火墙脚本高度依赖网络基础架构和安全要求。当您为自己的环境编写脚本时,请使用此示例了解 nftables 防火墙的概念。

8.7.1. 网络条件

本例中的网络具有以下条件:

  • 路由器连接到以下网络:

    • 互联网通过接口 enp1s0
    • 内部 LAN 通过接口 enp7s0
    • DMZ 通过 enp8s0
  • 路由器的互联网接口分配了静态 IPv4 地址(203.0.113.1)和 IPv6 地址(2001:db8:a::1)。
  • 内部 LAN 中的客户端仅使用范围 10.0.0.0/24 中的专用 IPv4 地址。因此,从 LAN 到互联网的流量需要源网络地址转换(SNAT)。
  • 内部 LAN 中的管理员 PC 使用 IP 地址 10.0.0.10010.0.0.200
  • DMZ 使用范围 198.51.100.0/242001:db8:b::/56 中的公共 IP 地址。
  • DMZ 中的 Web 服务器使用 IP 地址 198.51.100.52001:db8:b::5
  • 路由器为 LAN 和 DMZ 中的主机充当缓存 DNS 服务器。

8.7.2. 防火墙脚本的安全要求

以下是示例网络中 nftables 防火墙的要求:

  • 路由器必须能够:

    • 递归解析 DNS 查询。
    • 在回环接口上执行所有连接。
  • 内部 LAN 中的客户端必须能够:

    • 查询运行在路由器上的缓存 DNS 服务器。
    • 访问 DMZ 中的 HTTPS 服务器。
    • 访问互联网上的任何 HTTPS 服务器。
  • 管理员的 PC 必须能够使用 SSH 访问 DMZ 中的路由器以及每个服务器。
  • DMZ 中的 Web 服务器必须能够:

    • 查询运行在路由器上的缓存 DNS 服务器。
    • 访问互联网上的 HTTPS 服务器以下载更新。
  • 互联网上的主机必须能够:

    • 访问 DMZ 中的 HTTPS 服务器。
  • 另外,存在以下安全要求:

    • 应丢弃未明确允许的连接尝试。
    • 应记录丢弃的数据包。

8.7.3. 配置将丢弃的数据包记录到文件

默认情况下,systemd 会将内核消息如,丢弃的数据包,记录到日志中。另外,您可以配置 rsyslog 服务,来将此类条目记录到单独的文件中。为确保日志文件不会无限增长,请配置轮转策略。

先决条件

  • rsyslog 软件包已安装。
  • rsyslog 服务正在运行。

流程

  1. 使用以下内容创建 /etc/rsyslog.d/nftables.conf 文件:

    :msg, startswith, "nft drop" -/var/log/nftables.log
    & stop
    Copy to Clipboard Toggle word wrap

    使用这个配置,rsyslog 服务会将丢弃的数据包记录到 /var/log/nftables.log 文件,而不是 /var/log/messages

  2. 重启 rsyslog 服务:

    # systemctl restart rsyslog
    Copy to Clipboard Toggle word wrap
  3. 使用以下内容创建 /etc/logrotate.d/nftables 文件,以便在大小超过 10 MB 时轮转 /var/log/nftables.log

    /var/log/nftables.log {
      size +10M
      maxage 30
      sharedscripts
      postrotate
        /usr/bin/systemctl kill -s HUP rsyslog.service >/dev/null 2>&1 || true
      endscript
    }
    Copy to Clipboard Toggle word wrap

    maxage 30 设置定义了 logrotate 在下一次轮转操作过程中删除超过 30 天的轮转日志。

8.7.4. 编写并激活 nftables 脚本

本例是运行在 RHEL 路由器上的一个 nftables 防火墙脚本,其保护内部 LAN 中的客户端以及 DMZ 中的 Web 服务器。有关示例中使用的防火墙的网络和要求的详情,请参阅 网络条件对防火墙脚本的安全要求

警告

nftables 防火墙脚本仅用于演示目的。不要在未经调整为适合您环境和安全要求的情况下使用它。

前提条件

流程

  1. 使用以下内容创建 /etc/nftables/firewall.nft 脚本:

    # Remove all rules
    flush ruleset
    
    
    # Table for both IPv4 and IPv6 rules
    table inet nftables_svc {
    
      # Define variables for the interface name
      define INET_DEV = enp1s0
      define LAN_DEV  = enp7s0
      define DMZ_DEV  = enp8s0
    
    
      # Set with the IPv4 addresses of admin PCs
      set admin_pc_ipv4 {
        type ipv4_addr
        elements = { 10.0.0.100, 10.0.0.200 }
      }
    
    
      # Chain for incoming trafic. Default policy: drop
      chain INPUT {
        type filter hook input priority filter
        policy drop
    
        # Accept packets in established and related state, drop invalid packets
        ct state vmap { established:accept, related:accept, invalid:drop }
    
        # Accept incoming traffic on loopback interface
        iifname lo accept
    
        # Allow request from LAN and DMZ to local DNS server
        iifname { $LAN_DEV, $DMZ_DEV } meta l4proto { tcp, udp } th dport 53 accept
    
        # Allow admins PCs to access the router using SSH
        iifname $LAN_DEV ip saddr @admin_pc_ipv4 tcp dport 22 accept
    
        # Last action: Log blocked packets
        # (packets that were not accepted in previous rules in this chain)
        log prefix "nft drop IN : "
      }
    
    
      # Chain for outgoing traffic. Default policy: drop
      chain OUTPUT {
        type filter hook output priority filter
        policy drop
    
        # Accept packets in established and related state, drop invalid packets
        ct state vmap { established:accept, related:accept, invalid:drop }
    
        # Accept outgoing traffic on loopback interface
        oifname lo accept
    
        # Allow local DNS server to recursively resolve queries
        oifname $INET_DEV meta l4proto { tcp, udp } th dport 53 accept
    
        # Last action: Log blocked packets
        log prefix "nft drop OUT: "
      }
    
    
      # Chain for forwarding traffic. Default policy: drop
      chain FORWARD {
        type filter hook forward priority filter
        policy drop
    
        # Accept packets in established and related state, drop invalid packets
        ct state vmap { established:accept, related:accept, invalid:drop }
    
        # IPv4 access from LAN and internet to the HTTPS server in the DMZ
        iifname { $LAN_DEV, $INET_DEV } oifname $DMZ_DEV ip daddr 198.51.100.5 tcp dport 443 accept
    
        # IPv6 access from internet to the HTTPS server in the DMZ
        iifname $INET_DEV oifname $DMZ_DEV ip6 daddr 2001:db8:b::5 tcp dport 443 accept
    
        # Access from LAN and DMZ to HTTPS servers on the internet
        iifname { $LAN_DEV, $DMZ_DEV } oifname $INET_DEV tcp dport 443 accept
    
        # Last action: Log blocked packets
        log prefix "nft drop FWD: "
      }
    
    
      # Postrouting chain to handle SNAT
      chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;
    
        # SNAT for IPv4 traffic from LAN to internet
        iifname $LAN_DEV oifname $INET_DEV snat ip to 203.0.113.1
      }
    }
    Copy to Clipboard Toggle word wrap
  2. /etc/sysconfig/nftables.conf 文件中包括 /etc/nftables/firewall.nft 脚本:

    include "/etc/nftables/firewall.nft"
    Copy to Clipboard Toggle word wrap
  3. 启用 IPv4 转发:

    # echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf
    # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
    Copy to Clipboard Toggle word wrap
  4. 启用并启动 nftables 服务:

    # systemctl enable --now nftables
    Copy to Clipboard Toggle word wrap

验证

  1. 可选:验证 nftables 规则集:

    # nft list ruleset
    ...
    Copy to Clipboard Toggle word wrap
  2. 尝试执行防火墙阻止的访问。例如,尝试使用 SSH 从 DMZ 访问路由器:

    # ssh router.example.com
    ssh: connect to host router.example.com port 22: Network is unreachable
    Copy to Clipboard Toggle word wrap
  3. 根据您的日志记录设置,搜索:

    • 阻塞的数据包的 systemd 日志:

      # journalctl -k -g "nft drop"
      Oct 14 17:27:18 router kernel: nft drop IN : IN=enp8s0 OUT= MAC=... SRC=198.51.100.5 DST=198.51.100.1 ... PROTO=TCP SPT=40464 DPT=22 ... SYN ...
      Copy to Clipboard Toggle word wrap
    • 阻塞的数据包的 /var/log/nftables.log 文件:

      Oct 14 17:27:18 router kernel: nft drop IN : IN=enp8s0 OUT= MAC=... SRC=198.51.100.5 DST=198.51.100.1 ... PROTO=TCP SPT=40464 DPT=22 ... SYN ...
      Copy to Clipboard Toggle word wrap
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat