Nftables 更新 1.1.2
nftables 1.1.2 – Commodore Bullmoose #3
nftables 1.1.2(“Commodore Bullmoose #3”)于 2025 年 4 月 14 日发布。这个版本继续延续了1.1 的版本名字,加了 #3
, 与之前预测一样,按照 #1
, #2
, #3
发布了多个小版本。
新版本主要改进了集合(sets)和映射(maps)的表达能力,引入更灵活的按位运算与范围表达,优化了自动合并逻辑,并增强了对 MPTCP、流表(flowtable)事件及 JSON 输出的支持。此外,nft monitor 现可报告流表事件,工具内存占用进一步降低,命令行体验更为一致。
下面根据官方的 Announce 梳理下具体更新的新功能.
nftables 1.1.2 改动详解
1. 协议依赖的集合(Protocol Dependency on Sets)
改动说明:允许在集合定义中使用 typeof meta l4proto
,以仅匹配指定的第 4 层协议。
示例:
table inet filter {
set allowed_protos {
typeof meta l4proto
elements = { tcp, udp }
}
chain prerouting {
type filter hook prerouting priority 0; policy accept;
meta l4proto @allowed_protos tproxy to :1088
}
}
2. 高级按位运算支持(Advanced Bitwise Operations)
改动说明:语句中可使用更复杂的位运算,如与(&
)、或(|
)、左移(<<
)等,但需 Linux 6.13 或更高内核。
示例:
chain prerouting {
# 将连接跟踪标记高 16 位与 低 16 位结合入 meta mark
ct mark set ct mark & 0xffff0000 | meta mark & 0xffff
# 使用 CPU 核心编号作为标志位之一
meta mark set meta mark & 0xffff0000 | meta cpu << 8 | iif
}
3. 自动合并时跳过带超时/过期元素(Auto‑merge Skips Timeout/Expiration)
改动说明:当集合元素含有超时(timeout
)或失效(expiration
)属性时,自动合并逻辑不再将其与其它元素合并。
示例:
table ip example {
set ephemeral {
type ipv4_addr
flags timeout
elements = { 10.0.0.1 timeout 1m, 10.0.0.2 timeout 2m }
}
}
# nft 自动合并时,两个带 timeout 的元素将被分别保留,不合并成区间
4. 在 typeof 中使用 queue(Queue with typeof)
改动说明:允许在 map
或 set
的 typeof
中指定 queue
类型,以便直接将数据包排入指定队列。
示例:
table inet t {
map get_qid {
typeof ip saddr . ip daddr . tcp dport : queue
elements = {
127.0.0.1 . 127.0.0.1 . 22 : 1,
127.0.0.1 . 127.0.0.2 . 22 : 2
}
}
chain test {
queue flags bypass to ip saddr . ip daddr . tcp dport map @get_qid
}
}
5. 内存占用优化(Memory Footprint Reduction)
改动说明:内部重构集合元素存储结构,显著降低用户空间库在处理大量元素时的内存占用。 示例:在大量 IP 前缀集合场景下,相比 1.1.1,内存使用降低约 30%。
6. nft monitor 报告流表事件(Flowtable Events in nft monitor)
改动说明:nft monitor
新增对流表(flowtable)添加及删除事件的支持,便于调试及实时监控。
示例:
# 实时监控 flowtable 添加/删除
sudo nft monitor events flowtable
# OUTPUT:
# flowtable inet ft add id 1 size 1024
# flowtable inet ft del id 1
7. 列出集合命令一致性(Consistent “list sets” Command)
改动说明:新增 list sets inet foo
,无需再加 table
关键字,与其它对象命令保持一致。
示例:
# 旧版本需:
nft list sets table inet filter myset
# 1.1.2 可直接:
nft list sets inet filter myset
8. 按位掩码合并优化(Bitmask Matching Merge with ‑o/–optimize)
改动说明:使用 ‑o/--optimize
时,可将多条相同掩码的位运算规则合并为单条集合匹配表达式。
示例:
# nft ‑c ‑o ‑f ruleset.nft
# 将多条 “tcp flags & (…) == X” 规则合并为:
tcp flags & (fin|syn|rst|ack|urg) == { fin|ack|urg, fin|ack, … }
9. 范围表达式(Range Expression)
改动说明:以单个 [ range eq reg X Y ]
取代两条比较命令,提高可读性与执行效率。
示例:
- [ cmp gte reg 1 0x00005000 ]
- [ cmp lte reg 1 0x00005a00 ]
+ [ range eq reg 1 0x00005000 0x00005a00 ]
10. MPTCP 支持增强(MPTCP Subtype Symbol Table)
改动说明:为 TCP 可选头中的 MPTCP 子类型提供符号表,支持像 mp-join
、dss
等自描述常量。
示例:
set mptcp_opts {
typeof tcp option mptcp subtype
elements = { mp-join, dss }
}
# nft describe tcp option mptcp subtype
# … pre-defined constants:
# mp-join : 1
# dss : 2
11. 位域头部篡改(Bitfield Header Mangling)
改动说明:支持对协议头中位域字段(如 IP DSCP)进行按位或等操作。 示例:
chain prerouting {
# 在原 DSCP 基础上或入 0x1
ip dscp set ip dscp | 0x1
}
12. 单行打印多词描述集合元素(Single‑Line Multi‑Word Set Elements)
改动说明:对于带有映射、超时、注释、计数器等多词描述的元素,打印时合并为单行,提升可读性。 示例:
table ip x {
set y {
typeof ip saddr
counter
elements = {
192.168.10.35 counter packets 0 bytes 0,
192.168.10.101 counter packets 0 bytes 0,
192.168.10.135 counter packets 0 bytes 0
}
}
}
# 上述元素将被打印为三行,但每行完整展示所有属性
13. JSON 中支持 typeof(typeof in JSON)
改动说明:在 JSON 输出模式下可同样使用 typeof
定义集合和映射类型,便于与自动化工具集成。
示例:
nft --json list set inet filter myset | jq '.[] | select(.evaltype=="set") | .type'
# 输出将包含 "typeof ip saddr" 等字段
nftables 1.1.2 编译安装指引
1. 下载
-
官方下载页面:https://www.netfilter.org/projects/nftables/downloads.html
-
直接获取 1.1.1 源码包:
https://www.netfilter.org/pub/nftables/nftables-1.1.2.tar.xz
2. 依赖项
-
libnftnl ≥ 1.2.8:https://netfilter.org/projects/libnftnl/index.html
-
libmnl ≥ 1.0.4:https://netfilter.org/projects/libmnl/index.html
-
需要内核支持
nf_tables
(≥ Linux 3.14)。
3. 编译与安装
# 解压源码包
tar xf nftables-1.1.2.tar.xz
cd nftables-1.1.2
# 配置,指定安装前缀(可选)
./configure --prefix=/usr \
--sysconfdir=/etc \
--localstatedir=/var
# 编译并测试
make
make check
# 安装
sudo make install
提示:如需卸载,可在源码目录内运行
sudo make uninstall
。