iptables处理分片报文需raw表提前拦截异常碎片、filter表基于连接状态放行,因仅首片含四层头且conntrack不跟踪后续片,须协同nf_defrag_ipv4控制与日志审计。

iptables 对分片报文的处理需格外谨慎,因为传统状态跟踪(如 conntrack)无法正确识别非首片分片,易导致规则绕过或连接异常。关键在于明确分片报文的特征、分离首片与后续片的处理逻辑,并结合 nf_defrag_ipv4 和 raw 表提前干预。
理解分片报文在 iptables 中的特殊性
IP 分片后,只有首片携带四层头(TCP/UDP 端口、协议字段等),后续片仅含 IP 头和分片偏移信息,无端口、标志位等。这意味着:
- 默认情况下,-p tcp --dport 80 这类规则对非首片完全不匹配,可能放行恶意后续片
- conntrack 模块只对首片创建连接记录,后续片以“RELATED”状态进入,但若首片被丢弃或未触发 conntrack,后续片会走 raw 表或 filter 默认链
- 内核 2.6.22+ 后,nf_defrag_ipv4 模块会在 PREROUTING 链早期对入向分片自动重组(仅限 IPv4),但该行为不可控且不适用于所有场景(如需深度检测或丢弃碎片)
在 raw 表中显式拦截可疑分片
raw 表优先级最高,绕过 conntrack,适合在连接跟踪前做初步过滤。常用策略包括:
- 丢弃明显异常的分片:如分片偏移非 8 字节整数倍(--fragid 匹配需配合 iprange 或 string 模块,但更可靠的是用 -m frag)
- 禁止非首片携带 TCP 标志位(SYN/FIN/RST/ACK):这类报文非法,可直接 DROP
- 限制单 IP 单位时间内的分片数量,防碎片洪水(需配合 hashlimit 模块)
示例规则:
iptables -t raw -A PREROUTING -f -m tcp --tcp-flags ALL ALL -j DROPiptables -t raw -A PREROUTING -f --fragmore -m hashlimit --hashlimit-above 10/sec --hashlimit-name frag_flood -j DROP
filter 表中安全放行合法分片流量
经 raw 表清洗后,在 filter 表中应基于连接状态决策,而非原始分片特征:
- 允许 ESTABLISHED,RELATED 流量(RELATED 已包含合法后续片)
- 对 NEW 连接只检查首片(此时已有完整四层信息),如 -p tcp --dport 22 --syn
- 避免在 filter 表中对 -f 单独设 ACCEPT,否则会绕过状态检查
典型配置片段:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPTiptables -A INPUT -p tcp --dport 22 -m state --state NEW --syn -j ACCEPT
iptables -A INPUT -j DROP
补充建议:禁用自动重组与日志审计
若需完全掌控分片处理流程(如 IDS/IPS 部署场景),可禁用内核自动重组:
- echo 0 > /proc/sys/net/ipv4/ip_forward_use_pmtu(影响路径 MTU 发现,慎用)
- 更稳妥方式是确保 nf_defrag_ipv4 模块未加载:modprobe -r nf_defrag_ipv4(需在系统启动早期执行)
- 对所有 -f 报文添加 LOG 目标,便于分析攻击模式:-t raw -A PREROUTING -f -j LOG --log-prefix "FRAG:"
分片攻击防御不是靠单一规则,而是 raw 过滤 + conntrack 依赖 + filter 状态驱动的三层协同。忽视任一环节都可能导致策略失效。










