vault backup: 2026-05-27 23:01:37
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
---
|
||||
tags: [计算机网络, IPv4, IP首部, TTL, MTU, 分片]
|
||||
tags: [计算机网络, IPv4, IP首部, TTL, MTU, 分片, ECN, PMTUD, IP Options]
|
||||
create time: 2026-05-17 23:40
|
||||
---
|
||||
|
||||
@@ -12,19 +12,19 @@ IPv4 数据包是互联网的基本传输单元。理解其首部结构,有助
|
||||
## IPv4 首部格式(32-bit fields)
|
||||
|
||||
```
|
||||
Version(4b) │ IHL(4b) │ DSCP/ECN(8b) │ Total Length(16b) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ Identification(16b) │DF│ MF │Offset(13b)│
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ TTL(8b) │ Protocol(8b) │ Header Checksum │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ Source Address (32b) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ Destination Address (32b) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ Options (variable) │
|
||||
│ ...padding... │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
Version(4b) │ IHL(4b) │ DSCP(6b) │ ECN(2b) │ Total Length(16b) │
|
||||
├───────────────────────────────────────────────────────────────────────┤
|
||||
│ Identification(16b) │Rsv│DF│MF│ Offset(13b) │
|
||||
├───────────────────────────────────────────────────────────────────────┤
|
||||
│ TTL(8b) │ Protocol(8b) │ Header Checksum(16b) │
|
||||
├───────────────────────────────────────────────────────────────────────┤
|
||||
│ Source Address (32b) │
|
||||
├───────────────────────────────────────────────────────────────────────┤
|
||||
│ Destination Address (32b) │
|
||||
├───────────────────────────────────────────────────────────────────────┤
|
||||
│ Options (variable, 0-40B) │
|
||||
│ ...padding... │
|
||||
└───────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 各字段详解
|
||||
@@ -33,9 +33,11 @@ Version(4b) │ IHL(4b) │ DSCP/ECN(8b) │ Total Length(16b) │
|
||||
|------|------|------|
|
||||
| **Version** | 4 bit | 版本号,IPv4 = `0100` |
|
||||
| **IHL** (Internet Header Length) | 4 bit | 首部长度,单位 4 bytes。**最小值 5**(20 bytes),最大 15(60 bytes) |
|
||||
| **DSCP** (Differentiated Services Code Point) | 6 bit | QoS 优先级标记;前 3 bit 为 ECN(Explicit Congestion Notification)|
|
||||
| **DSCP** (Differentiated Services Code Point) | 6 bit | QoS 优先级标记,替代早期的 ToS 字段前 6 位 |
|
||||
| **ECN** (Explicit Congestion Notification) | 2 bit | 显式拥塞通知。末 2 bit 用于在不丢包的情况下通知端主机网络拥塞(`00`=不支持, `10`/`01`=支持 ECN, `11`=拥塞已经历) |
|
||||
| **Total Length** | 16 bit | 整个 IP 包总长(含首部),最大 65535 字节 |
|
||||
| **Identification** | 16 bit | 唯一标识符。同一原始包的分片共享此 ID |
|
||||
| **Reserved** | 1 bit | 保留位,必须为 0 |
|
||||
| **DF** (Don't Fragment) | 1 bit | 置 1 则禁止分片;路由器不能分片的包如果 DF=1,直接丢弃并返回 ICMP "Fragmentation Needed" |
|
||||
| **MF** (More Fragments) | 1 bit | 置 1 表示后面还有分片;最后一个分片 MF=0 |
|
||||
| **Fragment Offset** | 13 bit | 该分片在原始数据中的偏移量(以 8 字节为单位) |
|
||||
@@ -55,11 +57,46 @@ Version(4b) │ IHL(4b) │ DSCP/ECN(8b) │ Total Length(16b) │
|
||||
受限于链路 MTU: 通常 1500B Payload → 最大常用包 1520 bytes
|
||||
```
|
||||
|
||||
> [!tip] 为什么 IHL 最大值是 15?
|
||||
> IHL 以 4 字节为单位,最大值 15 × 4 = 60 bytes。去掉固定首部 20 bytes,Options 最多 **40 bytes**。这就是为什么 Options 字段上限是 40B。
|
||||
|
||||
### Options 字段(可选,0-40 bytes)
|
||||
|
||||
Options 是 IPv4 首部中最容易被忽略的部分,但在网络诊断和特殊场景中依然重要:
|
||||
|
||||
| 选项类型 | 说明 | 典型用途 |
|
||||
|---------|------|---------|
|
||||
| **Record Route** | 记录包经过的每一跳路由器 IP | 路由追踪(类似 traceroute) |
|
||||
| **Timestamp** | 每个路由器记录到达时间戳 | 测量延迟、时钟同步分析 |
|
||||
| **Strict Source Route** | 指定完整路径,逐跳严格匹配 | 诊断路由问题(现代网络几乎禁用) |
|
||||
| **Loose Source Route** | 指定必须经过的中间节点,其余自由路由 | 绕路测试 |
|
||||
|
||||
> [!warning] 安全注意
|
||||
> 现代路由器和防火墙通常**丢弃包含 Options 的 IP 包**,因为 Source Route 曾被用于 IP 欺骗攻击。这也是为什么正常流量中你几乎看不到 Options。
|
||||
|
||||
### Header Checksum 逐跳重算
|
||||
|
||||
与 L2 CRC 和 TCP/UDP Checksum 不同,IP Header Checksum **每经过一个路由器都要重新计算**——因为 TTL 会递减。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["路由器收到包"] --> B["TTL -= 1"]
|
||||
B --> C["重新计算 Checksum"]
|
||||
C --> D["转发到下一跳"]
|
||||
|
||||
style A fill:#87CEEB,color:#000
|
||||
style D fill:#98FB98,color:#000
|
||||
```
|
||||
|
||||
> [!question] 为什么 IP Checksum 只校验首部?
|
||||
> 早期设计为减轻路由器负担——只校验 20 bytes 首部远比校验整个 64KB 包高效。数据完整性由上层协议(TCP/UDP Checksum)保证。这也是 IP 被称为"尽力而为"协议的原因之一。
|
||||
|
||||
## TTL 深度解析
|
||||
|
||||
### TTL 的常见误解
|
||||
|
||||
很多人以为 TTL 的单位是秒。其实在 IPv4 中它是**跳数计数器**——每经过一个路由器(三层转发节点)减 1,不是按时间递减。
|
||||
> [!question] TTL 是时间吗?
|
||||
> 很多人以为 TTL 的单位是秒——这其实是 IPv6 的 Hop Limit 的前身历史遗留误解。在 IPv4 中 TTL 是**跳数计数器**——每经过一个路由器(三层转发节点)减 1,不是按时间递减。名字容易误导,但行为很简单:减到 0 就丢弃。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
@@ -109,10 +146,10 @@ MTU(Maximum Transmission Unit)是链路层允许的最大 IP 包载荷大小
|
||||
|----------|---------|-------------|
|
||||
| Ethernet | 1500 bytes | 9000 bytes |
|
||||
| Wi-Fi (802.11n/ac/ax) | 1500 | ❌ 不支持 |
|
||||
| PPPoE (宽带拨号) | 1492 (预留 8B PPPoE头) | — |
|
||||
| IPv6 | 1280 (硬性最小) | 可选 |
|
||||
| GRE 隧道 | 1476 (预留 24B GRE头) | — |
|
||||
| VXLAN | 1450 (预留 50B VxLAN头) | — |
|
||||
| PPPoE (宽带拨号) | 1492 (8B PPPoE 头开销) | — |
|
||||
| IPv6 | 1280 (硬性最小 MTU) | 可选 |
|
||||
| GRE 隧道 | 1476 (24B GRE 头开销) | — |
|
||||
| VXLAN | 1450 (50B VXLAN 头开销) | — |
|
||||
|
||||
### 分片规则
|
||||
|
||||
@@ -138,10 +175,39 @@ MTU(Maximum Transmission Unit)是链路层允许的最大 IP 包载荷大小
|
||||
| — | 攻击者可以利用分片做碎片攻击(Teardrop 等) |
|
||||
| — | IPv6 已取消中间路由器分片,改由端到端 PMTUD |
|
||||
|
||||
### Wireshark 中识别分片
|
||||
|
||||
实战排查时,抓包识别分片是最常见需求:
|
||||
|
||||
```bash
|
||||
# tcpdump 过滤分片包(offset > 0 或 MF=1 的包)
|
||||
$ tcpdump -i eth0 'ip[6:2] & 0x3fff != 0' -nn
|
||||
|
||||
# Wireshark 显示过滤器
|
||||
# ip.frag_offset > 0 → 非首片
|
||||
# ip.flags.mf == 1 → 还有后续分片
|
||||
# ip.id == 0x1234 → 按 Identification 追踪同组分片
|
||||
```
|
||||
|
||||
> [!tip] 分片重组技巧
|
||||
> Wireshark 默认会自动重组分片。如果需要查看原始分片:`Edit → Preferences → IPv4 → 去勾选 "Reassemble fragmented IPv4 datagrams"`。
|
||||
|
||||
### 常见分片攻击
|
||||
|
||||
| 攻击手法 | 原理 | 防御 |
|
||||
|---------|------|------|
|
||||
| **Teardrop** | 构造重叠偏移的分片,重组时内核缓冲区溢出 | 更新内核补丁(已修复) |
|
||||
| **Ping of Death** | 分片重组后 IP 包 > 65535 bytes,触发整数溢出 | 现代系统已防御 |
|
||||
| **Rose Attack** | 发送大量不完整的分片,消耗重组缓冲区 | 设置重组超时、限制并发分片数 |
|
||||
| **Fragment Overlap** | 后续分片覆盖前片数据,绕过基于首片的防火墙规则 | 防火墙需做完整分片重组后再检测 |
|
||||
|
||||
### PMTUD(Path MTU Discovery)
|
||||
|
||||
现代网络推荐使用 **路径 MTU 发现**而非分片:
|
||||
|
||||
> [!warning] PMTUD Black Hole
|
||||
> 如果中间路由器**静默丢弃**了 DF=1 的大包,但不返回 ICMP,源主机会一直重传失败——这就是 PMTUD Black Hole。常见于错误配置的防火墙(拦截了 ICMP "Fragmentation Needed")。TCP 的对策是 `net.ipv4.tcp_mtu_probing`(值设为 2),主动探测合适的 MSS。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Src as 源主机
|
||||
@@ -152,8 +218,8 @@ sequenceDiagram
|
||||
Note over Src: DF(Do Not Fragment)=1
|
||||
R->>R: MTU=1400 < 1500, DF=1 → 无法分片!
|
||||
R->>Src: ICMP Type 3 Code 4 "Fragmentation Needed"
|
||||
Note over Src: Path MTU = 1400 - IP头(20) - Eth(14) = 1366
|
||||
Src->>Dst: IP Packet (size=1366, DF=1) ✅
|
||||
Note over Src: Path MTU = 1400, Max IP Payload = 1400 - 20(IP头) = 1380
|
||||
Src->>Dst: IP Packet (size=1400, DF=1) ✅
|
||||
Dst-->>Src: ACK ✅
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user