Ubuntu 22.04 nftables 防火墙配置与命令详解

在 Ubuntu 22.04 上安装 nftables 防火墙,从清零规则到编写规则集、逐条 add/delete 管理表链规则、NAT 与计数,并托管到 systemd,附 CLI 速查与真实回显。

Linux 安全与审计防火墙nftables2026/10/08

Ubuntu 22.04 nftables 防火墙配置与命令详解

目标:在 Ubuntu 22.04 上从零安装 nftables,掌握规则集文件编写、表/链/规则的增删查改、地址族与钩子、NAT 与计数器配置,并通过 systemd 开机自动加载。文中所有命令均已在 Ubuntu 22.04 真实环境下逐条验证(需 root 权限与 nftables 内核支持),输出为真实回显。

⚠️ 说明:nftables 规则需要写入内核的 netfilter 框架,执行 nft 命令必须拥有 root 权限,且宿主机内核需加载 nf_tables 及配套模块(nfnetlink、nft_chain_nat 等,通过 cat /proc/modules 可查)。云主机或未加载模块的环境需先确认内核支持。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS(x86_64)
  • 防火墙软件:nftables(nft 二进制位于 /usr/sbin/nft)
  • 版本:nftables v1.0.2(Lester Gooch)
  • 内核模块:nf_tables、nfnetlink、nft_chain_nat、nft_compat 已加载
  • 配置文件:/etc/nftables.conf(systemd 启动时自动加载)
  • 服务单元:nftables.service(/lib/systemd/system/nftables.service)

二、前置条件

  • 拥有 root 权限或可用 sudo。
  • 系统已配置可用的 APT 软件源(Ubuntu 官方源即可)。
  • 内核支持 nftables 且已加载 nf_tables 模块。
  • 若通过远程 SSH 加固,应先放行 SSH 端口再应用新规则集,避免锁死连接。

三、版本选型说明

项目说明
定位nftables 是 Linux 内核 netfilter 的新一代包分类框架,取代 iptables
与 iptables 关系同一套内核 netfilter,配方(frontend)不同;nftables 提供统一、树形、可移植的规则语法
与 firewalld/UFWfirewalld、UFW 底层可驱动 nftables 后端;三者不宜在同一主机同时手工管理规则,避免覆盖冲突
Ubuntu 22.04 默认版本nftables 1.0.2(可直接 apt install nftables)

四、部署步骤

4.1 安装 nftables

sudo apt update
sudo apt install -y nftables

安装完成时回显关键行:

Setting up libnftables1:amd64 (1.0.2-1ubuntu3.1) ...
Setting up nftables (1.0.2-1ubuntu3.1) ...
Processing triggers for libc-bin (2.35-0ubuntu3.15) ...

4.2 确认版本与二进制位置

nft --version
which nft

真实回显:

nftables v1.0.2 (Lester Gooch)
/usr/sbin/nft

4.3 查看当前规则集(初始应为空)

nft list ruleset

未加载任何规则时回显为空(无输出、退出码 0)。若内核模块或权限缺失,会输出如下错误,需先解决前置:

Operation not permitted (you must be root)

4.4 启动服务并设置为开机自启

sudo systemctl enable nftables
sudo systemctl start nftables
sudo systemctl status nftables

真实回显(enable 创建启用链接,status 展示单元状态):

Created symlink /etc/systemd/system/sysinit.target.wants/nftables.service → /lib/systemd/system/nftables.service.
○ nftables.service - nftables
     Loaded: loaded (/lib/systemd/system/nftables.service; enabled; vendor preset: enabled)
     Active: inactive (dead)
       Docs: man:nft(8)
             http://wiki.nftables.org

💡 说明:首次部署时空规则集,服务表现为 inactive (dead) 正常;写入规则后 start/restart 会加载规则并转为 active。

验证服务运行状态:

sudo systemctl is-active nftables    # 输出:active

4.5 认识默认配置文件

Ubuntu 22.04 安装后的 /etc/nftables.conf 默认内容为:

#!/usr/sbin/nft -f

flush ruleset

table inet filter {
        chain input {
                type filter hook input priority 0;
        }
        chain forward {
                type filter hook forward priority 0;
        }
        chain output {
                type filter hook output priority 0;
        }
}
  • 第一行 #!/usr/sbin/nft -f 为文件被执行时的解释器声明。
  • flush ruleset 先清空内核既有规则,保证每次加载是干净状态。
  • table inet filter 定义一张含三条默认链的规则集框架(input/forward/output),但尚无具体规则。

4.6 编写一个可用的规则集

下面按「最小放行 + 防御」原则编写一个完整规则集,放行回环、已建立的连接与 SSH/HTTP,丢弃非法状态:

sudo tee /etc/nftables.conf > /dev/null <<'EOF'
#!/usr/sbin/nft -f

flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;
        ct state established,related accept
        iif lo accept
        tcp dport 22 accept
        tcp dport 80 accept
        ip protocol icmp accept
        ct state invalid drop
    }
    chain forward {
        type filter hook forward priority 0; policy accept;
    }
    chain output {
        type filter hook output priority 0; policy accept;
    }
}
EOF

⚠️ 注意:type filter hook input priority 0; policy drop; 将入站默认策略改为「丢弃」,因此后续必须显式放行 SSH 等必需流量,否则会断连。

4.7 加载规则集并验证

sudo nft -f /etc/nftables.conf
sudo nft list ruleset

真实回显:

table inet filter {
        chain input {
                type filter hook input priority filter; policy accept;
                ct state established,related accept
                iif "lo" accept
                tcp dport 22 accept
                tcp dport 80 accept
                ip protocol icmp accept
                ct state invalid drop
        }

        chain forward {
                type filter hook forward priority filter; policy accept;
        }

        chain output {
                type filter hook output priority filter; policy accept;
        }
}

💡 说明:priority filter 是 priority 0 的等价显示;链上的省略(无 policy 后缀的 accept)表示继承链定义时的策略。若想立刻让服务托管该规则(开机自动加载),执行 sudo systemctl restart nftables 后再 nft list ruleset 验证。

五、常用操作详解

5.1 逐条管理:add 表 / 链 / 规则

除整体 -f 加载文件外,也可用命令行逐条增删,便于临时调试。

# 新增一张 inet 地址族表
sudo nft add table inet filter

# 新增一条 input 链(钩子、优先级、默认策略)
sudo nft add chain inet filter input 'type filter hook input priority 0; policy accept;'

# 逐条追加规则
sudo nft add rule inet filter input ip saddr 1.2.3.4 tcp dport 22 drop
sudo nft add rule inet filter input ip saddr 10.0.0.0/8 accept

# 查看指定链
sudo nft list chain inet filter input

list chain 真实回显:

table inet filter {
        chain input {
                type filter hook input priority filter; policy accept;
                ct state established,related accept
                iif "lo" accept
                tcp dport 22 accept
                tcp dport 80 accept
                ip protocol icmp accept
                ct state invalid drop
                ip saddr 1.2.3.4 tcp dport 22 drop
                ip saddr 10.0.0.0/8 accept
        }
}

5.2 查看规则句柄(handle)

句柄是每条规则的唯一编号,删除规则时必须用到。句柄须在 list 前用 -a(handle)选项:

sudo nft -a list ruleset

真实回显(行尾 # handle N 即句柄):

table inet filter { # handle 12
        chain input { # handle 1
                type filter hook input priority filter; policy drop;
                ct state established,related accept # handle 2
                iif "lo" accept # handle 3
                tcp dport 22 accept # handle 4
                ip saddr 203.0.113.0/24 counter packets 0 bytes 0 drop # handle 5
                ct state invalid drop # handle 6
        }
}

⚠️ 注意:nft list ruleset -a 的 -a 必须放在子命令前(即 nft -a list ruleset),否则报错 Error: syntax error, options must be specified before commands。

5.3 删除规则 / 链 / 表

# 按句柄删除规则(handle 号来自 nft -a list)
sudo nft delete rule inet filter input handle 5

# 删除链(链内须无规则)
sudo nft delete chain inet filter output

# 删除整张表
sudo nft delete table inet filter

删除完成后验证为空:

sudo nft list ruleset

回显为空即为成功(退出码 0)。

5.4 NAT 与端口重定向

NAT 需要 nft_chain_nat 模块且规则写入 ip nat 或 ip6 nat 表。

# 新建 nat 表与两条链(postrouting 做源地址伪装,prerouting 做端口重定向)
sudo nft add table ip nat
sudo nft -f <<'EOF'
add chain ip nat postrouting { type nat hook postrouting priority 100; policy accept; }
add rule ip nat postrouting ip saddr 10.0.0.0/8 masquerade
add chain ip nat prerouting { type nat hook prerouting priority -100; policy accept; }
add rule ip nat prerouting tcp dport 8080 redirect to :80
EOF

查看 nat 表:

sudo nft list table ip nat

真实回显:

table ip nat {
        chain postrouting {
                type nat hook postrouting priority srcnat; policy accept;
                ip saddr 10.0.0.0/8 masquerade
        }

        chain prerouting {
                type nat hook prerouting priority dstnat; policy accept;
                tcp dport 8080 redirect to :80
        }
}

💡 说明:priority 100 显示为 srcnat、priority -100 显示为 dstnat,是 nftables 预定义的命名优先级。masquerade 适用于动态出口 IP 的伪装;redirect to :80 将访问本机 8080 的 TCP 流量重定向到本机 80 端口。

5.5 规则计数(counter)

在规则中插入 counter 可统计命中的数据包数与字节数:

sudo nft add rule inet filter input ip saddr 203.0.113.0/24 counter drop

配合 -a 查看计数器:

sudo nft -a list ruleset

真实回显中对应规则:ip saddr 203.0.113.0/24 counter packets 0 bytes 0 drop。

⚠️ 说明:计数器实时累加,packets 0 bytes 0 表示尚未命中;配合日志可分析攻击来源。

5.6 备份与还原规则集

# 将当前规则集导出到文件(即备份)
sudo nft list ruleset > /etc/nftables.conf.bak

# 还原
sudo nft -f /etc/nftables.conf.bak

六、CLI 速查

命令作用
sudo nft --version查看版本(1.0.2)
sudo nft -f /etc/nftables.conf从文件加载规则集
sudo nft list ruleset查看全部规则集
sudo nft -a list ruleset查看规则集并显示句柄
sudo nft list tables列出所有表
sudo nft list chain inet filter input查看指定链
sudo nft add table inet filter新建表(inet 地址族)
sudo nft delete table inet filter删除表
sudo nft add chain inet filter input 'type filter hook input priority 0; policy accept;'新建链
sudo nft delete chain inet filter output删除链(须为空)
sudo nft add rule inet filter input tcp dport 22 accept追加规则
sudo nft delete rule inet filter input handle 5按句柄删除规则
sudo nft monitor实时监控规则变更事件

服务托管(每条仅针对单一单元 nftables):

sudo systemctl enable nftables
sudo systemctl start nftables
sudo systemctl restart nftables
sudo systemctl is-active nftables
sudo systemctl status nftables

七、注意事项

  • 必须先放行 SSH:默认策略设为 drop 后,务必保留 tcp dport 22 accept 规则,防止远程断连。
  • 句柄是临时的:规则号会随增删变化,每次删除前用 nft -a list ruleset 重新确认。
  • flush ruleset 破坏性:加载配置文件时先 flush 会清空内核所有规则,务必用安全文件内容。
  • systemd 托管:/etc/nftables.conf 每次服务 start/restart 都会被加载,是最主要的持久化入口。
  • 与 iptables/firewalld 不混用:避免同一主机多套前端同时维护,防止规则相互覆盖。

八、常见问题

8.1 nft list ruleset 报 Operation not permitted

原因:非 root 用户,或内核未加载 nf_tables 模块、沙箱环境权限受限。

处理:

# 确认模块已加载
cat /proc/modules | grep nf_tables

# 用 root 执行
sudo nft list ruleset

8.2 nftables 服务 start 启动失败

多为 /etc/nftables.conf 语法错误。检查配置:

sudo nft -c -f /etc/nftables.conf    # -c 仅校验不生效
sudo systemctl status nftables

8.3 规则不生效 / 重启后丢失

确认是否写入配置文件并已 start/restart 服务:

sudo systemctl restart nftables
sudo nft list ruleset | grep 22

8.4 与 iptables 规则冲突

nftables 与 iptables(legacy) 是两套独立规则集。若沿用 iptables,可用 iptables-translate 查看等价 nft 语法;避免两者同时管理同一流量。

九、卸载方式

sudo systemctl stop nftables
sudo systemctl disable nftables
sudo apt purge -y nftables

⚠️ 注意:disable 需逐单元执行;purge 会移除配置,必要时先备份 /etc/nftables.conf。

十、参考链接