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)

改动说明:允许在 mapsettypeof 中指定 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-joindss 等自描述常量。 示例

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. 下载

2. 依赖项

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