Ubuntu 22.04 nftables 防火墙配置与命令详解
在 Ubuntu 22.04 上安装 nftables 防火墙,从清零规则到编写规则集、逐条 add/delete 管理表链规则、NAT 与计数,并托管到 systemd,附 CLI 速查与真实回显。
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/UFW | firewalld、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。
十、参考链接
- nftables 官网:https://nftables.org/
- Netfilter 内核文档:https://www.netfilter.org/documentation/
- Ubuntu man 手册:
man nft