IP 分片是什么
当报文长度超过出接口的 MTU,IPv4 路由器可以把它切成若干分片:每片带同一个标识(ID),用 MF 标志表示「后面还有」,用片偏移表示它在原报文中的位置。重组只在目的主机进行,中途任何一片丢失都会导致整个原始报文被丢弃并重传全部。IPv6 则不允许路由器分片,只能由源端处理。
基本信息
| 触发条件 | 报文长度超过出接口 MTU |
|---|---|
| 关键字段 | 标识 ID、DF 禁止分片、MF 更多分片、片偏移 |
| 重组位置 | 仅目的主机,中间路由器不重组 |
| IPv6 差异 | 路由器不分片,强制由源端处理(RFC 8200) |
| 规范 | RFC 791 §3.2、RFC 8900(分片攻击性分析) |
| 相关机制 | PMTUD 路径 MTU 发现 |
典型使用场景
- 排查「小包能通、大包全丢」的 MTU 黑洞问题
- 隧道场景(GRE/IPsec/VXLAN)估算额外头部开销后重设 MTU
- 理解 PMTUD 依赖的 ICMP 差错消息为何不能随意屏蔽
- 抓包时识别分片,判断是否有设备在错误地重组或丢弃碎片
- 安全方向:评估分片绕过检测与碎片攻击的风险面
测试与抓包
测试与抓包
# 1472 + 8(ICMP 头)+ 20(IP 头)= 1500,禁止分片
traceroute --mtu 目标地址 # 沿路径探测各跳 MTU
ping -M do -s 1472 10.0.0.9 # Linux:-M do 即设置 DF
ping -D -s 1472 10.0.0.9 # BSD/macOS 写法
ping -s 3000 10.0.0.9 # 允许分片,观察是否丢包
tcpdump -nn -v 'ip[6:2] & 0x1fff != 0' -c 5 # 抓取片偏移非 0 的分片
sysctl net.ipv4.ipfrag_high_thresh # 重组队列上限字段读法
| 字段 | 含义 | 注意点 |
|---|---|---|
| 标识 ID | 同一原始报文的分片组号 | 重组依据,不同组的 ID 可重复使用 |
| DF | 禁止分片标志 | 置位时超 MTU 会回送 ICMP 需要分片 |
| MF | 更多分片标志 | 最后一片为 0,前面的片都为 1 |
| 片偏移 | 该片在原始报文中的位置 | 以 8 字节为单位,非 8 的倍数属非法 |
| 重组超时 | 等待所有分片的时限 | Linux 默认约 30 秒,超时丢弃全部碎片 |
PMTUD 的工作原理是:发送方设置 DF 位探测路径,收到「需要分片但 DF 置位」的 ICMP 消息后调小报文长度并缩小本机 PMTU 缓存。因此屏蔽这类 ICMP 会让大包传输直接黑洞化。
分片会放大攻击面:碎片可用于绕过部分检测设备、构造重叠分片欺骗,以及大量碎片耗尽重组队列内存(分片洪水)。边界设备通常对分片有速率限制甚至直接拒绝。