1. Netfilter与nftables概述
Linux 内核中的包过滤能力并不是由某一个独立程序提供的,而是由内核里的 Netfilter 框架与用户态的配置工具共同组成。理解 Netfilter 的架构,是理解 iptables、nftables、conntrack、NAT 等一切上层工具的前提。本节先建立整体图景:Netfilter 在内核中处于什么位置、由哪些机制构成,nftables 为什么会出现,它与 iptables 的差异体现在哪里,以及在实际工程中应当如何选择。
Netfilter 框架的架构
Netfilter 是 Linux 2.4 起引入的内核网络子系统,它在协议栈的关键路径上预置了一系列钩子点(hook),允许内核模块在这些位置注册回调函数,对经过的数据包进行检查、修改、丢弃或放行。它本身不定义具体规则,只提供“在何处可以干预”的机制;iptables、nftables、conntrack、bridge 过滤等都建立在这套机制之上。
IPv4 协议栈中共有五个钩子点,按数据包的处理顺序排列:
- PREROUTING:数据包刚进入网卡、尚未做路由判断之前,常用于 DNAT、连接跟踪的初始识别。
- INPUT:路由判断后确认发往本机的数据包。
- FORWARD:路由判断后确认需要转发到其他主机的数据包。
- OUTPUT:本机进程产生的数据包,在路由选择之后。
- POSTROUTING:数据包即将离开网卡之前,常用于 SNAT、MASQUERADE。
每个钩子点上可以挂载多个优先级不同的处理函数,内核按优先级依次调用。优先级数值越小越先执行,例如连接跟踪(conntrack)通常运行在 -200,而 NAT 的 SNAT 在 POSTROUTING 上运行于 100。这种“钩子 + 优先级”的设计,使得不同功能模块可以有序协作,而不必互相修改代码。
与钩子机制配套的还有几个关键组件:连接跟踪(conntrack)记录每条流的状态,使有状态过滤和 NAT 成为可能;表(table)、链(chain)、规则(rule)是用户态工具对钩子点的抽象组织方式;匹配(match)与目标(target)则描述“什么包”和“怎么处理”。
nftables 的诞生背景
iptables 长期承担 Linux 防火墙的主力角色,但随着规则规模增长,它的结构性问题逐渐暴露。iptables 为 IPv4、IPv6、ARP、网桥分别提供了 iptables、ip6tables、arptables、ebtables 四套命令,语法相似但不通用;每条规则在内核中对应一个独立的结构体,规则数量大时匹配是线性遍历,性能随规则数下降;修改规则需要整体替换某条链,无法做到原子性的增量更新;NAT、过滤、mangle 等功能分散在不同表中,规则重复书写。
nftables 自 Linux 3.13 引入,目标是用一套统一的框架取代上述多套工具。它把 IPv4/IPv6/ARP/网桥的过滤统一到同一套语法中,采用类似虚拟机的字节码执行模型,支持集合(set)、映射(map)、字典等数据结构,规则可以增量、原子地更新,并且在内核中共享同一套表达式求值逻辑。
核心优势与 iptables 对比
| 对比维度 | iptables | nftables |
|---|---|---|
| 命令工具 | iptables / ip6tables / arptables / ebtables 各自独立 | 统一使用 nft 命令 |
| 内核匹配方式 | 每条规则一个结构体,线性遍历 | 字节码 + 集合/映射,支持高效查找 |
| 规则更新 | 整链替换,非原子 | 支持原子事务,可增量更新 |
| 集合与区间 | 需 ipset 配合 | 原生支持 set、map、区间、前缀 |
| IPv4/IPv6 | 两套规则分别维护 | 可用 inet 家族同时处理 |
| 规则可读性 | 语法冗长,重复多 | 语法紧凑,可复用变量与集合 |
需要强调的是,nftables 并不是在 Netfilter 之外另起炉灶,它仍然使用同一套钩子点、同一套 conntrack 机制。区别在于用户态表达方式和内核中的规则表示形式。因此,掌握 Netfilter 的钩子与优先级模型,对学习 nftables 同样关键。
适用场景与选择建议
在实际工程中,选择 iptables 还是 nftables,通常取决于内核版本、既有运维体系和规则规模。若内核低于 3.13,只能使用 iptables;若系统已使用 firewalld 且后端为 nftables,则底层实际是 nft;若规则数量达到数千条以上、需要频繁动态增删、或需要同时处理 IPv4 与 IPv6,nftables 的优势会非常明显。