nftables仅能匹配内核预解析的l2-l4及ct元数据字段,不解析应用层载荷;支持ether、ip、tcp/udp、icmp、ct state、meta等零拷贝字段匹配,但无法进行正则、跨包或偏移量动态解析。

nftables 本身不提取也不解析网络报文的内容,它只读取内核网络栈已解析并缓存的字段。所谓“匹配”,是基于这些预填充元数据做快速比对,不是逐字节解包或应用层扫描。
nftables 能直接匹配哪些报文字段?
它支持从链路层到传输层、再到连接跟踪上下文的结构化字段访问,全部零拷贝、无解析开销:
- 链路层:
ether saddr、vlan id、arp saddr ip - 网络层:
ip saddr、ip6 daddr、ip protocol - 传输层:
tcp dport、udp sport、tcp flags & syn == syn - ICMP/ICMPv6:
icmp type echo-request、icmpv6 type nd-neighbor-solicit - 连接状态:
ct state established、ct original ip saddr 10.0.0.5 - 元数据:
meta skuid 1000、meta mark 0x100、time hour 8-18
nftables 不能做什么?
它不处理应用层载荷(如 HTTP body、TLS SNI、DNS 查询名),也不支持:
- 解析未被内核预解析的字段(比如 TCP payload 第 24 字节)
- 正则匹配、字符串搜索、Base64 解码等动态内容分析
- 跨分片、跨包、上下文关联的深度检测(如识别一段密钥是否横跨两个 TCP 段)
想匹配载荷内容怎么办?
必须引入协同机制,nftables 只负责“分流+标记+动作执行”:
- 用
socket cgroupv2或meta skuid先筛选出目标进程(如 nginx、curl)的流量 - 用 eBPF 程序在内核中读取指定偏移(如
bpf_skb_load_bytes(ctx, 68, &buf, 4)),校验后写ct mark - nftables 规则里用
ct mark & 0x100 == 0x100快速跳转或丢弃 - 或由用户态工具(libpcap + 自定义解析)抓取首包,把特征注入
ipset或nft map,再用@ipset_name匹配
payload 表达式是个例外,但很受限
内核 ≥6.1 且启用 CONFIG_NF_TABLES_INET 时,可用 @nh,offset,len == value 做简单载荷指纹匹配:
- 仅限首包(非分片)、固定偏移、定长二进制值
- 示例:
tcp dport 80 @th,12,16 == 0x504f5354匹配 "POST" 字符串(大端 ASCII) - 不适合模糊匹配、可变长度字段或加密流量
不复杂但容易忽略










