nftables默认不重组IP分片,首片可匹配L3/L4字段,后续分片仅含IP头、无传输层头,需用ip frag-off和ip more-frag区分处理,避免策略绕过或误拦截。

nftables 默认不处理 IP 分片报文的重组,因此对分片报文(fragmented packets)的过滤需特别设计:规则在**首片(first fragment)上可匹配完整 L3/L4 字段,而后续分片(non-first fragments)仅含 IP 头、无传输层头,无法匹配 tcp dport 或 udp sport 等字段**。若未显式处理,容易造成策略绕过或误拦截。
识别并单独处理首片与后续分片
IP 分片由 IPv4 头中 Fragment Offset 和 More Fragments (MF) 标志位标识。nftables 提供 ip frag-off 和 ip more-frag 关键字进行判断:
-
首片:offset = 0 且 MF = 1 →
ip frag-off 0 ip more-frag 1 -
后续分片:offset > 0(无论 MF 是否置位)→
ip frag-off & 0x1fff != 0(推荐用掩码判断) - 末片(可能为单片):offset > 0 且 MF = 0 → 可合并到“后续分片”逻辑中统一处理
避免传输层字段误用导致规则失效
对非首片报文,tcp dport、udp sport、icmp type 等字段不可用,强行使用会触发 nft 解析错误或静默跳过匹配。正确做法是:
- 所有依赖 L4 字段的规则(如
tcp dport 22)必须前置ip frag-off 0或明确限定只作用于首片 - 若需放行/拦截整个分片流,应基于首片决策,并允许后续分片通过(因内核 conntrack 通常将整组分片视为同一连接)
- 示例安全写法:
nft add rule inet filter input ip frag-off 0 tcp dport 80 accept
结合连接跟踪(ct)实现有状态分片放行
现代内核(≥5.10)中,conntrack 可对分片报文做关联跟踪。启用 nf_conntrack_ipv4.nf_defrag_ipv4=1(默认开启)后,分片会在进入 conntrack 前被重组(或标记为同一 flow)。此时可安全使用:
-
ct state established,related放行响应类分片(包括后续片) -
ct status & 0x040 == 0x040匹配已跟踪的分片流(IPS_SEEN_REPLY标志) - 搭配默认 drop 策略时,建议顺序:先放通 lo、established/related;再按首片 + 端口白名单放行新连接;最后显式丢弃非法分片(如 offset 非零但无对应首片)
主动防御:限制分片滥用与碎片攻击
攻击者常利用分片绕过检测或发起 DoS(如 Teardrop、Ping of Death)。可添加防护规则:
- 丢弃明显异常的分片:
nft add rule inet filter input ip more-frag 0 ip frag-off & 0x1fff != 0 drop(末片 offset 非零但 MF=0) - 限速首片新建连接:
nft add rule inet filter input ip frag-off 0 ct state new limit rate 5/second burst 10 drop - 屏蔽已知恶意分片特征(如伪造 offset=1 的 TCP 片):
nft add rule inet filter input ip frag-off 1 tcp drop















