Linux 中 nftables 防火墙的安装与使用指南

本文详细介绍了现代 Linux 包过滤框架 nftables 的安装与配置。与传统 iptables 相比,nftables 提供了统一、高效的防火墙管理方式,支持 IPv4、IPv6 等多种协议,简化了规则编写,提升了性能。文章涵盖了安装步骤、基本命令、核心概念(表、链、钩子、策略)、基本规则配置、NAT与端口转发,以及高级规则设置与规则持久化,旨在帮助中文开发者轻松掌握 nftables,增强 Linux 服务器网络安全。

nftables 简介

nftables 是一个现代的 Linux 内核包过滤框架,旨在取代传统的 iptables。它提供了一种统一且高效的方式来管理 IPv4、IPv6、ARP 等多种协议的防火墙规则。相较于 iptables,nftables 具备更优异的性能和更简洁的配置,因为它通过一个单一接口而非多个独立工具来管理所有规则。

本文将指导您如何在 Linux 系统中安装和配置 nftables,设置基本的防火墙规则,管理网络流量,并实现常见的安全策略。

先决条件

在开始之前,您需要:

  • 拥有一台 Linux 实例,并且可以使用非 root 用户执行 sudo 命令。
  • 对网络协议和防火墙规则管理有基本的了解。

nftables 与 iptables:新旧防火墙对比

iptables 作为 Linux 上标准的防火墙管理工具,长期以来承担着关键角色。然而,它的局限性日益凸显,例如复杂的规则结构、在大型规则集下的性能瓶颈,以及需要使用多个不同的工具来处理不同协议(如 IPv4 使用 iptables,IPv6 使用 ip6tables,ARP 使用 arptables 等)。为了解决这些问题,nftables 应运而生,作为 iptables 的替代方案,在功能、性能和易用性方面都带来了显著改进。

下表对比了 nftables 和 iptables,突出了它们在功能、性能和可用性方面的关键差异,解释了为何 nftables 是更优选的方案。

特性(Feature) iptables nftables
包过滤(Packet Filtering) 需要多个独立工具管理不同协议(iptables, ip6tables, arptables) 使用统一方法,通过命名表(tables)和链(chains)进行管理
规则语法(Rule Syntax) 强制用户编写复杂、多条目的链式规则 提供现代化、基于表的语法,简化规则编写
性能(Performance) 顺序处理规则,可能降低大型规则集的性能 使用优化的规则评估,减少开销
原子规则更改(Atomic Rule Changes) 修改规则集需要清空并重新加载整个规则集 支持原子规则更新,防止中断
日志记录(Logging) 使用旧式日志目标(LOG 和 ULOG 框架) 提供内置日志功能和高级追踪选项(meta nftrace, log)
连接跟踪(Connection Tracking) 需要外部 conntrack 模块 直接集成连接跟踪到系统中
多协议支持(Multi-protocol Support) 每个协议需要不同的命令 通过单个命令集管理所有协议
资源使用(Resource Usage) 通过复制规则消耗更多内存 通过统一规则集高效管理内存
脚本与自动化(Scripting & Automation) 依赖 Shell 脚本和手动规则管理 支持 JSON 格式的规则定义和直接脚本集成
兼容性(Compatibility) 在所有发行版上运行,但遵循旧式架构 在现代系统上原生工作,并支持 iptables 转换

在 Linux 中安装 nftables

根据您使用的 Linux 发行版,按照以下步骤安装 nftables。

在 Ubuntu 和 Debian 上安装 nftables

  1. 更新服务器的包索引:

    sudo apt update
    
  2. 使用 APT 包管理器安装 nftables:

    sudo apt install nftables -y
    

在 Rocky Linux, AlmaLinux 上安装 nftables

  1. 更新 DNF 包索引:

    sudo dnf update
    
  2. 安装 nftables:

    sudo dnf install -y nftables
    

在 Arch Linux 上安装 nftables

  • 使用 Pacman 安装 nftables:

    sudo pacman -S nftables
    

nft 命令语法速查

nft 命令是 nftables 的命令行接口,用于管理和配置防火墙规则。

nft [ -nNscaeSupyjtT ] [ -I directory ] [ -f filename | -i | cmd ... ]

常用选项说明:

  • -n: 在输出中显示规则编号。
  • -N: 打印更详细的规则输出。
  • -s: 显示规则的统计信息。
  • -c: 显示每条规则的链名称。
  • -a: 打印带地址族(Address Family)和协议的规则。
  • -e: 展开规则详情。
  • -S: 打印规则集(配置)。
  • -u: 启用更新模式以进行动态更改。
  • -p: 以可解析格式(parseable format)打印当前规则集。
  • -y: 显示详细的对象类型。
  • -j: 以 JSON 格式输出。
  • -t: 以表格(table)格式显示输出。
  • -T: 显示标记化(tokenized)的输出。
  • -I directory: 使用指定目录作为配置文件。
  • -f filename: 从文件加载规则。
  • -i: 交互模式,直接修改规则。
  • cmd ...: 操作 nftables 规则的命令参数。

管理 nftables 系统服务

nftables 服务管理您的防火墙规则并确保系统重启后规则的持久性。请按照以下步骤在您的系统上启用和启动 nftables 服务。

  1. 启用 nftables 服务开机自启动:

    sudo systemctl enable nftables
    
  2. 启动 nftables 服务:

    sudo systemctl start nftables
    
  3. 验证服务状态:

    sudo systemctl status nftables
    

    输出应类似如下:

    ● nftables.service - Netfilter Tables
         Loaded: loaded (/usr/lib/systemd/system/nftables.service; enabled; preset: disabled)
         Active: active (exited) since Mon 2025-03-31 17:52:35 UTC; 5s ago
           Docs: man:nft(8)
        Process: 1838 ExecStart=/sbin/nft -f /etc/sysconfig/nftables.conf (code=exited, status=0/SUCCESS)
       Main PID: 1838 (code=exited, status=0/SUCCESS)
            CPU: 11ms
    
    Mar 31 17:52:35 nftables-03 systemd[1]: Starting Netfilter Tables...
    Mar 31 17:52:35 nftables-03 systemd[1]: Finished Netfilter Tables.
    

nftables 核心概念:表、链与策略

在 nftables 中,规则被组织成表(tables),表则包含定义流量如何处理的链(chains)。每个链都关联一个钩子(hook)(INPUT, OUTPUT, FORWARD),用于确定何时评估该链。链还具有策略(policies),用于定义当没有明确规则匹配数据包时的默认操作。

地址族(Address Families)

nftables 支持多种地址族来处理不同的网络协议:

  • inet: 统一处理 IPv4 和 IPv6 流量。
  • ip: 仅 IPv4 过滤。
  • ip6: 仅 IPv6 过滤。
  • arp: ARP 数据包过滤。
  • bridge: 以太网桥数据包过滤。
  • netdev: 网络设备层面的数据包过滤。

链钩子(Chain Hooks)

nftables 中的每个链都链接到特定的流量类型:

  • input: 控制发往本地机器的数据包。
  • output: 管理离开本地机器的数据包。
  • forward: 处理通过本地机器路由(转发)的数据包。

策略(Policies)

策略指的是当没有明确规则匹配数据包时,链所采取的默认操作。链的默认策略决定了当流量不匹配任何特定规则时,是接受、丢弃还是拒绝。

  • policy accept: 默认允许所有流量(适用于测试或初始配置)。
  • policy drop: 默默丢弃不匹配的数据包(最安全,常用于生产环境)。
  • policy reject: 向源发送拒绝通知(提供信息,但可能暴露服务器存在,安全性不如 drop)。

[!WARNING] 将 accept 作为默认策略不建议用于生产环境,因为它会允许所有流量,除非明确阻止。

管理默认 nftables 配置

按照以下步骤查看服务器上的默认 nftables 配置。

  1. 查看现有 nftables 表的列表:

    sudo nft list tables
    

    输出应类似如下:

    table ip filter
    table ip6 filter
    
  2. 查看默认 nftables 配置文件内容:

    cat /etc/nftables.conf
    

    输出应类似如下:

    #!/usr/sbin/nft -f
    
    flush ruleset
    
    table inet filter {
        chain input {
            type filter hook input priority 0; policy accept;
        }
        chain forward {
            type filter hook forward priority 0; policy accept;
        }
        chain output {
            type filter hook output priority 0; policy accept;
        }
    }
    

配置基本 nftables 防火墙规则

按照以下步骤配置和管理 nftables 规则以控制 Linux 机器上的网络流量。

创建初始表和链

  1. 为 IPv4 和 IPv6 流量创建新的防火墙表:

    sudo nft add table inet my_table
    

    此命令创建一个名为 my_table 的新表,它可以同时处理 IPv4 和 IPv6 数据包。inet 族允许您使用一套规则管理这两种协议。

    [!NOTE] 本文中使用了 my_table 作为表名。您可以将其替换为您喜欢的任意表名。

  2. 添加一个默认策略为 accept 的 input 链:

    sudo nft add chain inet my_table input { type filter hook input priority 0 \; }
    

    此命令创建一个应用于传入流量的过滤链。type filter 选项将其指定为过滤链,而 hook input 确保它处理传入数据包。priority 0 设置决定了执行顺序,值越小越先执行。

  3. 创建默认策略为 accept 的 forward 链:

    sudo nft add chain inet my_table forward { type filter hook forward priority 0\; }
    

    此命令创建一个应用于转发流量的过滤链。type filter 选项将其指定为过滤链,而 hook forward 确保它处理转发的数据包。priority 0 设置决定了执行顺序,值越小越先执行。

  4. 允许已建立(established)和相关(related)的连接保持现有通信:

    sudo nft add rule inet my_table input ct state established,related accept
    

    此规则使用连接跟踪(Connection Tracking,ct)来管理流量。ct state 选项启用连接跟踪,而 established 允许来自现有连接的数据包,related 则允许与现有连接相关的数据包(如 FTP 数据连接)。

添加、列出和删除规则

按照以下步骤添加、列出和删除 nftables 规则以控制网络访问。

  1. 添加规则以阻止来自特定 IP 地址的传入流量:

    sudo nft add rule inet my_table input ip saddr 192.0.2.10 drop
    

    此命令在 my_table 表中添加一条规则,阻止来自 IP 地址 192.0.2.10 的传入流量。该规则应用于 inet 族的 input 链。

  2. 查看所有活动的 nftables 规则集以验证配置:

    sudo nft list ruleset
    

    此命令列出所有活动的 nftables 规则,方便您验证配置。

  3. 列出带有句柄编号(handle number)的规则:

    sudo nft list chain inet my_table input
    

    此命令列出 my_table 表中 input 链的所有规则,并显示其对应的句柄编号,以便您可以引用特定规则进行删除。

    输出应类似如下:

    table inet my_table {
            chain input {
                    type filter hook input priority filter; policy accept;
                    ct state established,related accept # handle 0
                    ip saddr 192.0.2.10 drop # handle 1
            }
    }
    
  4. 从输出中识别句柄编号并删除相应的规则:

    sudo nft delete rule inet my_table input handle 0
    

    此命令从 my_table 表的 input 链中删除句柄编号为 0 的规则。

实施常见安全策略

  1. 允许 SSH 访问您的服务器:

    sudo nft add rule inet my_table input tcp dport 22 accept
    

    此命令添加一条规则,匹配 TCP 协议数据包并将其目标端口设置为 22(默认 SSH 端口)。它接受匹配的数据包,从而允许 SSH 连接。

  2. 阻止显示可疑活动的特定 IP 地址:

    sudo nft add rule inet my_table input ip saddr 192.0.2.10 drop
    

    此命令添加一条规则,匹配来自指定源 IP 地址的数据包,在不通知发送方的情况下丢弃它们,并阻止来自该 IP 地址的任何访问。

  3. 允许端口 80 上的 HTTP 流量:

    sudo nft add rule inet my_table input tcp dport 80 accept
    

    此命令添加一条规则,匹配目标端口 80(默认 HTTP 端口)的 TCP 协议数据包。它接受匹配的数据包,允许 Web 流量到达服务器。

  4. 允许端口 443 上的 HTTPS 流量:

    sudo nft add rule inet my_table input tcp dport 443 accept
    

    此命令添加一条规则,允许端口 443(HTTPS 默认端口)上的 TCP 流量。它确保加密的 Web 流量被允许,同时阻止该端口上的其他类型的流量。

  5. 默认丢弃所有其他传入流量(设置一个drop的默认策略,或者在链尾添加一个drop规则):

    sudo nft add rule inet my_table input drop
    

    或者将链的默认策略设置为 drop (更推荐的方式,但需要在创建链时就指定,或通过 nft alter chain 修改)。 如果链的策略是 accept,则需要添加一个 drop 规则作为链的最后一条规则。 为了更精确地记录被丢弃的包,可以添加 counter:

    sudo nft add rule inet my_table input counter drop
    

    此命令添加一条规则,默认丢弃所有不匹配之前规则的传入流量,只允许预先配置的规则(SSH、HTTP、HTTPS)。它有效地阻止了不需要的访问。

启用 NAT 与端口转发

  1. 通过使用任何文本编辑器(例如 vim)编辑 /etc/sysctl.conf 文件来启用 Linux 内核中的 IP 转发功能,这是 NAT 的先决条件:

    sudo vim /etc/sysctl.conf
    
  2. 取消注释以下行(或添加该行):

    ...
    # Uncomment the next line to enable packet forwarding for IPv4
    net.ipv4.ip_forward=1
    ....
    

    保存并关闭文件。

  3. 应用更改,使 sysctl.conf 中的配置立即生效:

    sudo sysctl -p
    
  4. 创建一个新的 nat 表来处理服务器的网络地址转换 (NAT):

    sudo nft add table nat
    

    此命令创建一个新的 nat 表,您可以在其中定义用于转换出站流量地址的 NAT 规则。

  5. 在 nat 表中创建一个 postrouting 链来处理路由后的数据包:

    sudo nft add chain nat postrouting { type nat hook postrouting priority 100 \; }
    
  6. 为您的内部网络添加一条伪装(masquerade)规则以启用互联网连接共享:

    sudo nft add rule nat postrouting ip saddr 192.0.2.0/24 oif enp1s0 masquerade
    

    此规则告诉 nftables 对来自 192.0.2.0/24 网络的出站流量执行 NAT(伪装)。oif enp1s0 部分指定该规则适用于离开 enp1s0 接口的流量,enp1s0 通常是连接到互联网的网络接口。请将 enp1s0 替换为您的实际网络接口名称。

重启后持久保存规则

在本节中,您将通过将 nftables 规则保存到配置文件中,使其在系统重启后保持持久性。

  1. 将当前防火墙配置保存到 /etc/nftables.conf 文件:

    sudo nft list ruleset | sudo tee  /etc/nftables.conf
    

    此命令将当前的 nftables 规则存储到 /etc/nftables.conf 文件中,确保它们可以在系统重启后恢复。

  2. 从 /etc/nftables.conf 配置文件应用已保存的规则:

    sudo nft -f /etc/nftables.conf
    

    此命令重新加载保存的配置文件(/etc/nftables.conf)中的防火墙规则。

  3. 重启 nftables 服务以确保所有更改都被加载并生效:

    sudo systemctl restart nftables
    

    这会重新加载防火墙规则并确保它们在重启后保持持久性。

高级 nftables 规则配置

  1. 为 SSH 连接实施速率限制,以防止暴力破解攻击:

    sudo nft add rule inet my_table input tcp dport 22 limit rate 3/minute accept
    

    此命令添加一条规则,目标为 SSH 流量(端口 22),将连接尝试限制为每分钟 3 次,并接受在限制范围内的连接,以帮助防止暴力破解攻击。

  2. 配置 Web 流量的端口转发:

    1. 在 nat 表中创建 prerouting 链(如果不存在):

      sudo nft add chain ip nat prerouting { type nat hook prerouting priority 0 \; }
      
    2. 添加端口转发规则:

      sudo nft add rule nat prerouting tcp dport 80 dnat to 192.0.2.10
      

      此命令添加一条规则,捕获传入的 HTTP 流量(目标端口 80),将其目标地址转换为内部服务器(192.0.2.10),并启用托管内部 Web 服务。请将 192.0.2.10 替换为您的实际内部服务器 IP 地址。

  3. 启用丢弃数据包的日志记录:

    sudo nft 'add rule inet my_table input log prefix "nftables-drop: " drop'
    

    此命令添加一条规则,在丢弃数据包之前记录它们,并添加一个自定义前缀("nftables-drop: ")以便于过滤。这有助于排除连接问题,并将日志存储在系统日志中(通常是 /var/log/syslog 或 journalctl 可查看)。

  4. 清空所有 nftables 规则:

    sudo nft flush ruleset
    

    [!WARNING]

    清空规则集时请务必小心,因为这将删除所有现有的 nftables 规则,从而有效地重置您的防火墙配置。

总结

通过本文的指导,您已经成功在 Linux 系统上安装并配置了 nftables。您了解了 nftables 的核心概念,包括如何创建表(tables)、设置带有不同策略的链(chains),以及管理防火墙规则。nftables 框架通过提供 IPv4 和 IPv6 流量的统一管理、原子规则更新和通过优化数据包处理提高性能,从而现代化了数据包过滤。凭借连接跟踪(Connection Tracking)和高级日志记录(Logging)功能等内置特性,nftables 简化了网络安全管理的复杂任务。如需获取更多信息和高级配置,请访问 官方 nftables wiki。

关于

关注我获取更多资讯

月球基地博客公众号二维码,扫码关注获取更多 AI 与编程资讯
📢 公众号
月球基地博客作者个人微信二维码,扫码交流 AI 与编程话题
💬 个人号
使用 Hugo 构建
主题 Stack 由 Jimmy 设计