记一次跨机房 IPSec VPN 大包分片黑洞导致应用超时但小包正常的排查实录

机房搬迁后跨机房 IPSec VPN 大包分片黑洞,应用小包正常但大包超时,PMTUD 黑洞 + MSS 钳制缺失导致。

问题背景

2026 年 8 月底,公司完成核心机房搬迁,从 A 机房整体迁移至 B 机房。跨机房业务通过 IPSec VPN 隧道互通,承载 ERP、OA、监控平台等关键系统。搬迁后初期测试小包 ping、SSH 登录、Web 页面打开均正常,但部分批量数据同步、报表导出、大文件上传等大包业务出现间歇性超时或失败。小包正常、大包异常的症状持续数日,严重影响搬迁后的业务验收。

故障现象

  • 小包(641400 字节)ping、SSH、HTTP GET 小页面全部正常,延迟稳定在 812ms。
  • 大包(>1500 字节)业务(如 ERP 批量同步、报表导出、对象存储上传)经常超时或中途断开,TCP 重传明显增多。
  • tcpdump 抓包显示,客户端发出的大包在隧道入口被正确封装,但对端无响应或仅返回 ICMP Fragmentation Needed(Type 3 Code 4),部分被静默丢弃。
  • traceroute -F 大包路径在隧道入口后即断,-I 小包可达。
  • 业务日志中频繁出现 Connection reset by peerRead timed outBroken pipe

排查过程

第一步:确认 MTU 基线

在 A、B 两端分别执行:

1
2
3
ping -M do -s 1472 10.10.20.1   # 期望 1500 - 28 = 1472
ping -M do -s 1400 10.10.20.1   # 成功
ping -M do -s 1452 10.10.20.1   # 失败 → ICMP Fragmentation Needed

确认路径 MTU 实际为 1422 字节(含 IPSec 封装后),但业务端仍以 1500 字节 MTU 发送。

第二步:抓包定位分片黑洞

在 IPSec 隧道入口(FortiGate)抓包:

1
diagnose sniffer packet any "host 10.10.20.1 and greater than 1400" 4 0 a

发现:

  • 客户端发出 1500 字节 TCP 数据包 → FortiGate 封装后 1528 字节。
  • 对端无 ACK,只有偶尔的 ICMP Type 3 Code 4(Fragmentation Needed,Next-Hop MTU=1422)。
  • 部分 ICMP 被策略丢弃或未触发客户端 PMTUD 回退。

第三步:检查 PMTUD 与 MSS 钳制

1
2
3
4
5
6
7
# FortiGate 端
config vpn ipsec phase1-interface
    edit "to-B-DC"
        set pmtu-discovery enable
        set tcp-mss 1380          # ← 关键缺失!
    next
end

发现 tcp-mss 未配置,pmtu-discovery 虽开,但对端防火墙策略将 ICMP 差错报文拦截,导致 PMTUD 黑洞。

第四步:业务端验证

在 Windows 业务服务器上:

1
2
netsh interface ipv4 show interface
netsh interface ipv4 set subinterface "以太网" mtu=1400 store=persistent

临时降低 MTU 后大包业务恢复,确认是路径 MTU 发现失败导致的分片黑洞。

解决方案

  1. 强制钳制 TCP MSS(最有效):
1
2
3
4
5
config vpn ipsec phase1-interface
    edit "to-B-DC"
        set tcp-mss 1380
    next
end
  1. 放行 ICMP Fragmentation Needed
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
config firewall policy
    edit 100
        set name "Allow-ICMP-PMTUD"
        set srcintf "wan"
        set dstintf "IPSec-to-B"
        set srcaddr "all"
        set dstaddr "all"
        set service "ICMP_DESTINATION_UNREACHABLE"
        set action accept
    next
end
  1. 业务端统一降低 MTU(兜底):
1
2
3
4
# Linux
ip link set dev eth0 mtu 1400
# Windows(持久化)
netsh interface ipv4 set subinterface "以太网" mtu=1400 store=persistent
  1. 验收测试
1
2
ping -M do -s 1372 10.10.20.1   # 成功
iperf3 -c 10.10.20.1 -t 30 -P 4 # 大包吞吐正常,无重传

根因分析

  • 机房搬迁后 IPSec 隧道路径 MTU 下降(新增加密封装 + 可能中间链路 MTU 限制)。
  • PMTUD 依赖 ICMP Type 3 Code 4,但对端防火墙默认拦截或未放行。
  • tcp-mss 未配置,客户端 TCP 握手 SYN 不携带 MSS 钳制,导致大包进入隧道后被静默分片或丢弃,形成经典 PMTUD 黑洞。

预防措施

  1. 所有跨机房/跨云 IPSec VPN 必须显式配置 tcp-mss(建议 1380~1400)。
  2. 防火墙策略模板中默认放行 ICMP_DESTINATION_UNREACHABLE,并建立定期审计机制。
  3. 新建链路验收 Checklist 增加「大包 MTU 验收」门禁:ping -M do -s 1372 + iperf3 大包测试。
  4. 业务镜像/基线脚本统一设置 mtu=1400,避免单点依赖 PMTUD。
  5. 监控增加「隧道路径 MTU 漂移告警」(定期大包 ping 失败即触发)。

总结

一次看似「小包正常、大包异常」的跨机房 VPN 问题,本质是经典的 PMTUD 黑洞。机房搬迁改变了路径 MTU,而防火墙策略与 IPSec 配置的双重缺失导致 ICMP 差错被拦截、MSS 未钳制,最终形成大包静默丢弃。通过强制 MSS 钳制 + 放行 ICMP + 验收 Checklist 三层防护,可彻底杜绝此类问题再次发生。

使用 Hugo 构建
主题 StackJimmy 设计