ESP 报文的组成
ESP(封装安全载荷)是 IPsec 承载业务数据的协议,IP 协议号 50。它的结构可以按「头、载荷、尾」三段来记:头部有 SPI 和序列号,SPI 与目的地址一起在接收端定位属于哪个安全联盟,序列号用于抗重放检查;中间是被加密的原始载荷,密文长度会因块加密填充而增加;尾部有填充长度、下一头部类型,最后是完整性校验值 ICV。理解这个结构对排障很有用:抓包时能看到的只有 SPI、序列号和长度,载荷是密文,而重放与校验失败的判断依据正是序列号与 ICV。
基本信息
| 协议号 | IP 协议 50 |
|---|---|
| SPI | 32 位安全参数索引,与目的地址联合定位 SA |
| 序列号 | 32 位递增,配合抗重放窗口 |
| ICV | 完整性校验值,覆盖载荷与报文头部字段 |
| 传输模式 | 保留原 IP 头,仅保护载荷,常用于主机间 |
| 隧道模式 | 整体封装新 IP 头,网关场景常用 |
典型使用场景
- 抓包排障:确认是 ESP 还是被 NAT-T 封装进 UDP 4500
- 定位重放丢弃:核对序列号是否出现回退或重复
- 校验失败排查:ICV 校验不过多与两端参数或中间改写有关
- 分析分片问题:隧道模式使报文变长,需评估 MTU 影响
- 与安全审计沟通:说明可见字段与不可见字段的边界
抓包观察要点
抓包观察要点
# 观察 ESP 报文形态(Wireshark 过滤示例)
# esp || udp.port == 4500
# 关注字段:SPI、Sequence Number、报文长度是否突增
# 判断是否被 NAT-T 封装
tcpdump -ni eth0 'udp port 4500' | head -20
# 直接看裸 ESP
tcpdump -ni eth0 'proto 50' | head -20
# 设备侧查看 SA 的 SPI 与计数
show crypto ipsec sa | include spi|pkts字段读法
| 字段 | 位置 | 作用与异常表现 |
|---|---|---|
| SPI | 头部 | 定位 SA;两端不一致则无法解密,计数不增长 |
| 序列号 | 头部 | 抗重放;回退或重复会被丢弃 |
| 填充 | 尾部 | 块加密对齐;分析长度时需扣除 |
| 下一头部 | 尾部 | 指明载荷类型(常见为 TCP/UDP) |
| ICV | 尾部 | 完整性校验;算法不匹配则校验失败 |
存在 NAT 时裸 ESP 无法穿过地址转换,报文会被封装进 UDP 4500,此时抓包看到的是 UDP 而不是协议 50;这是判断链路是否走 NAT-T 的直接证据。
隧道模式下 ESP 会额外增加外层 IP 头与 ESP 头尾开销,计算 MTU 与 MSS 时必须把这些字节算进去,否则会出现大包不通。