Linux 防火墙是个老话题,但玩法变了:你可能还在敲 iptables,却不知道从 Ubuntu 20.10、Debian 10、RHEL 8 开始,主流发行版默认的防火墙后端早已换成了 nftables——你敲的 iptables 只是 nftables 的一个兼容翻译层。本文从「你的系统到底在用哪个后端」讲起,用三组可直接上手的实战(基础入站防护、集合防爆破、NAT 端口转发),带你完整走一遍现代 Linux 防火墙的正确姿势。
为什么 2026 年的 Linux 都在转向 nftables
先看清 iptables 的三个历史包袱:
- 工具分裂:iptables / ip6tables / arptables / ebtables 四套命令各管一摊,IPv4 和 IPv6 要维护两套规则;
- 中间态窗口:规则逐条加载,删旧加新的过程中存在"部分应用"的间隙,流量可能短暂放行不该放行的连接;
- 性能瓶颈:规则线性遍历,黑名单 IP 一多就拖慢整个转发路径。
nftables 是 netfilter 官方在 2014 年起推出的新一代框架,核心改进全部对症下药:
| 维度 | iptables | nftables |
|---|---|---|
| 命令工具 | iptables/ip6tables 等多套 | 单一 nft 命令 |
| IPv4/IPv6 | 两套规则分开维护 | inet 地址族统一处理 |
| 规则更新 | 逐条加载,有中间态窗口 | nft -f 原子加载整个规则集,零停机 |
| 大列表 | 依赖外部 ipset | 内置命名集合 set/map,哈希查询接近 O(1) |
| 表结构 | 预定义 filter/nat/mangle | 无预定义,按需创建、任意命名 |
2026 年现状:Ubuntu 20.10+、Debian 10+、RHEL 8+、Fedora 18+ 的默认防火墙后端都是 nftables;firewalld 自 0.6.0 起底层也是 nftables。新项目直接学 nft 语法回报最高。
先确认你的系统在用哪个后端
iptables -V 的输出里藏着答案:看到 nf_tables 字样,说明 iptables 命令只是 iptables-nft 兼容层,底层规则其实都在 nftables 里。
iptables -V
# iptables v1.8.10 (nf_tables) ← nf_tables 即 nftables 后端在 Ubuntu 24.04 服务器上的真实输出(本文所有演示均实测于该机):

三个要点:
nft --version显示 v1.0.9,Ubuntu 24.04 仓库自带版本;- 默认情况下
nft list ruleset并不是空的——本机装了 Docker,能看到 Docker 通过 iptables-nft 维护的nat表(fib daddr type local ... jump DOCKER)。nftables 与 Docker 天然共存,后面「常见坑」一节还会细说; /etc/nftables.conf已经存在,这是 nftables 服务开机加载的规则文件。
nftables 核心:表、链、规则
nftables 是标准的三层结构,全部靠一个 nft 命令操作:
表 table ──> 链 chain ──> 规则 rule- 表:按用途分组,如
filter(过滤)、nat(地址转换)、mangle(改动报文)。创建表时必须声明地址族,最常用inet(IPv4+IPv6 统一处理,强烈推荐)、ip、ip6; - 链:分为基础链(挂在内核 hook 上,声明
type/hook/priority才会真正生效)和普通链(类似函数,供 jump 跳转调用); - 规则:匹配表达式 + 动作,如
tcp dport 22 accept。
下面这套命令逐行演示三层结构的创建、查看与清理(实际执行于 Ubuntu 24.04):

对应命令解释:
# 1. 创建表(inet 地址族,IPv4/IPv6 通用)
nft add table inet demo
# 2. 创建基础链:type filter + hook input + priority 0,缺一不可
nft add chain inet demo input '{ type filter hook input priority 0; policy accept; }'
# 3. 添加规则:放行 22 端口(SSH)
nft add rule inet demo input tcp dport 22 accept
# 4. 原生支持多端口花括号,一条规则放行 80/443
nft add rule inet demo input tcp dport { 80, 443 } accept
# 5. 查看表中所有规则
nft list table inet demo
# 6. 不用了直接删整张表(连带其中所有链和规则)
nft delete table inet demo常用命令速查:
| 操作 | nft 命令 |
|---|---|
| 查看全部规则 | nft list ruleset |
| 查看带规则句柄(供删除定位) | nft list ruleset -a |
| 删除单条规则 | nft delete rule inet filter input handle 3 |
| 清空某条链 | nft flush chain inet filter input |
| 清空全部规则 | nft flush ruleset |
| 语法检查不生效 | nft -c -f /etc/nftables.conf |
| 原子加载规则文件 | nft -f /etc/nftables.conf |
重点:链只有声明了type、hook、priority才会被内核挂载执行,否则只是普通链——这是"规则加了却不生效"最常见的原因。挂载点主要有prerouting(入站最先)、input(发往本机)、forward(转发)、output(本机发出)、postrouting(出站最后)。
安装与开机自启
Ubuntu/Debian 系列:
sudo apt update && sudo apt install -y nftables
# 开机自启并立即启动(服务启动时会加载 /etc/nftables.conf)
sudo systemctl enable --now nftables
systemctl is-active nftables # active最重要的一个认知:nftables 不像 iptables 那样有 service 帮你存规则,默认重启即丢(nft list ruleset 出来的全是内存态)。规则必须写进 /etc/nftables.conf 并依赖 systemctl enable nftables 开机加载,或者改完规则后手动导出:
sudo nft list ruleset > /etc/nftables.conf实战一:基础入站防火墙(SSH + Web 服务器)
这是最常见的场景:公网服务器只开放 SSH 和 Web,其余入站全部拒绝。把下面内容写入 /etc/nftables.conf:
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iif "lo" accept # 回环放行
ct state established,related accept # 已建立/相关连接放行
ct state invalid drop # 非法状态包直接丢
tcp dport 22 accept # SSH
tcp dport { 80, 443 } accept # Web(原生多端口)
counter drop # 兜底:其余全部丢弃
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}逐条拆解关键行:
policy drop:链的默认策略。入站链默认丢包——白名单思路,比默认放行再封禁安全得多;ct state established,related accept:必须先放行已建立连接,否则出站请求的响应包会被自己的防火墙拦掉,表现为"能发不能收";ct state invalid drop:丢弃状态异常的包,抗常见协议攻击;counter drop:给兜底规则加计数器,之后能查每类规则的命中数,是排错利器。
应用并验证:
# 语法检查(强烈建议,防把自己锁在外面)
sudo nft -c -f /etc/nftables.conf
# 原子加载:要么全部生效,要么全部不生效,没有中间态
sudo nft -f /etc/nftables.conf
# 验证规则已加载
sudo nft list ruleset远程操作安全技巧:在服务器上远程改防火墙前,先设一个 5 分钟自动回滚的定时任务,万一配置把 SSH 挡了,5 分钟后自动恢复:
at now + 5 min <<< "nft flush ruleset"
实战二:命名集合与速率限制(防爆破)
iptables 时代防爆破要么写一长串规则,要么外挂 ipset;nftables 把集合内建了——一条规则 + 一个集合搞定 IP 白名单,还支持超时自动过期。
# 1. 创建命名集合(IPv4 地址集合)
nft add set inet demo ssh_admin '{ type ipv4_addr; }'
# 2. 往集合里加元素
nft add element inet demo ssh_admin '{ 192.168.1.10, 10.0.0.5 }'
# 3. 规则引用集合:仅集合内 IP 可访问 SSH
nft add rule inet demo input ip saddr @ssh_admin tcp dport 22 accept
# 4. 对 SSH 做速率限制:每分钟最多 5 次新连接,防爆破
nft add rule inet demo input tcp dport 22 limit rate 5/minute accept
# 5. 查看
nft list table inet demo实测输出:

配合 fail2ban 的动态黑名单更实用——集合支持 timeout 标志,封禁到期自动失效:
# 带超时的黑名单集合:元素 1 小时后自动过期
nft add set inet filter blacklist '{ type ipv4_addr; flags timeout; timeout 1h; }'
# 封禁一个 IP 3600 秒(fail2ban 的 nftables 后端就是往这种集合里插元素)
nft add element inet filter blacklist '{ 1.2.3.4 timeout 3600s }'
# 黑名单命中直接丢弃
nft add rule inet filter input ip saddr @blacklist drop实战三:NAT 与端口转发
NAT 走独立的 nat 表(不是 filter 表!),两条链各管一半:
prerouting(prioritydstnat,-100):入站目的地址改写——端口转发;postrouting(prioritysrcnat,100):出站源地址改写——内网出网 / 伪装。
table ip nat {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
# 公网 8080 端口 → 内网主机 10.0.0.10 的 80 端口
iifname "eth0" tcp dport 8080 dnat to 10.0.0.10:80
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
# 内网网段出网时伪装成 eth0 的地址(相当于传统 -t nat -j MASQUERADE)
oifname "eth0" ip saddr { 192.168.1.0/24, 10.0.0.0/24 } masquerade
}
}启用内核转发(NAT 场景必需,否则流量进来不转发):
sudo sysctl -w net.ipv4.ip_forward=1
echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf # 持久化从 iptables 平滑迁移
nftables 官方提供了规则自动翻译工具,老规则不用手抄:
# 1. 导出当前 iptables 规则
iptables-save > /tmp/iptables-rules.txt
# 2. 整文件翻译成 nftables 语法
iptables-restore-translate -f /tmp/iptables-rules.txt > /etc/nftables.conf
# 单条命令翻译用 iptables-translate,如:
# iptables-translate -A INPUT -p tcp --dport 22 -j ACCEPT
# 3. 审查并优化:把成片的多条 IP 规则合并成 set 集合
# 4. 语法检查 + 原子加载
sudo nft -c -f /etc/nftables.conf && sudo nft -f /etc/nftables.conf翻译结果只保证语义等价,不会自动做集合合并、结构优化,务必人工审查后再上线。
禁止混用两套规则:iptables 与 nftables 只是同一个内核防火墙的两种"遥控器",来回混用极易互相覆盖、策略混乱——有真实事故案例:某云厂商同时维护两套规则集,管理端口暴露遭 DDoS 攻击 72 小时。选定一套后(推荐原生 nft),就只用它管理。ufw 底层走 iptables-nft,也不建议和原生 nftables 规则并发使用。
常见坑与运维建议
- Docker 共存不用慌:Docker 通过 iptables-nft 维护自己的
DOCKER链(如前面实测截图所示),nft list ruleset会一并列出,二者可以共存。但注意 Docker 端口映射(-p)的流量走FORWARD链,不经 INPUT 链——想限制容器流量要在forward链上加规则; - 日志定位:兜底规则加
log prefix "nft drop: "后,用dmesg | grep "nft drop"或 journald 查看被丢弃的流量来源,是排查"谁在扫我"的标准姿势; - 计数器排错:在怀疑的规则上补
counter关键字,nft list ruleset直接显示每条规则的命中包数/字节数,快速判断规则是否真的被走到; - 规则上版本管理:规则文件是安全资产,纳入 Git 仓库 + Ansible 下发,比在服务器上徒手敲命令可靠得多;同时定期
nft list ruleset导出备份,灾备演练时把"5 分钟内重建防火墙"列为必测项; - 前端封装怎么选:规则简单图省事可以用 ufw 或 firewalld;规则复杂、规模大(IP 黑名单、多网段 NAT)直接写 nft 文件收益最高——本文所有内容都是原生 nft 语法,迁移到任何前端都不亏。
评论 (0)
暂无评论,快来抢沙发吧!