ipsec mtu 问题

在虚拟机内作为 IPsec VPN 网关、网卡 MTU=1500 时,建议将隧道内/内网侧的最大 MTU 设为 1400,对应 TCP MSS 约 1350,可避免经 IPsec 封装后在公网路径上因超 MTU 而丢包或分片。


为什么是 1400/1350

  • 标准以太链路 MTU=1500;IPsec 隧道模式会新增外层 IP 头(20)+ ESP/AH 等开销,再叠加 NAT-T 等可能的 UDP 封装,总开销常达约 100 字节量级。
  • 为保证"封装后不超 1500",实践中普遍将隧道接口 MTU 设为 1400,并将 TCP MSS 钳位到约 1350,这也是 Azure 等环境的推荐配置。

快速计算公式(简版)

  • 隧道内/内网侧建议 MTU ≈ 1500 − 外层 IP 头(20)− IPsec 封装开销(≈80--100)≈ 1400。
  • TCP MSS ≈ 隧道内 MTU − 40(TCP 头 20 + IP 头 20)≈ 1360,实际常用 1350 以留余量。

常见模式与开销(影响隧道内 MTU)

  • ESP 隧道模式:新增外层 IP 头(20)+ ESP 等开销,约 80--100 字节级,取决于加密/认证算法与填充。
  • 带 NAT-T:再叠加 UDP 封装(≈8),总开销更大。
  • 带 GRE:先 GRE 再 IPsec,总开销更高,通常需将隧道内 MTU 调得更低。

操作建议

  1. 将隧道接口/内网侧 MTU 设为 1400(如 Linux:ip link set dev <tun_if> mtu 1400)。
  2. 在网关与内网主机上对 TCP 做 MSS 钳位(约 1350);Linux 可在隧道或相关路由上配置:iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu 1350。
  3. 验证路径 MTU:用带 DF 的 ping 逐段探测最小 MTU,确保两端与中间路径一致。

若不限制 DF,会怎样?

  • 可能在公网被丢弃或分片;分片会降低吞吐、增加时延与丢包重试,因此建议按 1400/1350 统一设置并钳位 MSS。

结论:在"网卡 1500 且做 IPsec 网关"的场景,隧道内/内网侧最大 MTU 设为 1400,TCP MSS 约 1350 是安全且通用的做法,可显著减少丢包与性能波动。

如果我内网侧就是 1500 呢? ipsec 封包前会进行切片么?

如果内网侧数据包的 MTU 是 1500(即原始IP包大小为 1500 字节),经过 IPsec 封装后总大小会超过 1500字节 ,此时是否会分片取决于两个核心因素:原始数据包的 DF(Don't Fragment)标志位 和 出口接口的 MTU 限制。

1. IPsec 封装的"额外开销"导致包体膨胀

内网侧 1500 字节的原始 IP 包(含 20 字节 IP 头),经过 IPsec 隧道模式封装后,会新增:

  • 外层 IP 头(20 字节);
  • ESP 头部(至少 20 字节,含 SPI、序列号等);
  • 加密算法的填充(如 AES-CBC 需要 16 字节对齐,可能增加 1-16 字节);
  • 认证尾(如 HMAC-SHA1 需要 12-16 字节)。

总额外开销通常在80-100字节左右 ,因此封装后的数据包大小会变成 1500 + 80100 = 15801600字节,超过了公网侧通常 1500 的MTU限制。

2. 是否分片的关键:DF 标志位与出口 MTU

IPsec 网关本身不会主动对"封装前的原始数据包"进行分片,分片逻辑由 IP 层(网络层)决定,遵循以下规则:

  • 如果原始数据包的 DF 位为 0(允许分片) :

    封装后的数据包(1580~1600字节)超过出口接口(公网侧网卡)的MTU(1500)时,IPsec 网关会对封装后的整个数据包 进行分片,分成多个小于等于 1500 字节的分片发送到公网。

    接收端会在 IP 层重组这些分片,再进行 IPsec 解密和处理。

  • 如果原始数据包的 DF 位为1(禁止分片) :

    封装后的数据包超过出口 MTU 时,IPsec 网关会直接丢弃该数据包 ,并向源端发送"ICMP不可达(需要分片但 DF 置位)"消息。

    此时源端若能处理 ICMP 消息,会减小后续发送的数据包大小;若不能处理(如部分应用屏蔽 ICMP ),则会导致通信中断(丢包)。

3. 内网侧用 1500 的问题:性能与可靠性风险

即使允许分片(DF=0),内网侧坚持用 1500 也会带来明显问题:

  • 分片增加延迟与丢包概率:分片后的数据包若有任何一个分片丢失,整个原始包都需要重传,在 VPN 场景中会显著降低吞吐量。
  • 部分场景无法分片:很多 TCP 应用(如HTTP、HTTPS)会默认设置 DF=1(配合 Path MTU Discovery 机制),此时封装后超 MTU 会直接丢包,导致连接超时或卡顿。
  • 加密场景分片更脆弱:IPsec 加密后的数据分片,在重组时若校验失败(如分片顺序错误、数据篡改),会直接丢弃整个包,比普通 IP 分片更敏感。

结论

内网侧强行使用 1500 的MTU时,IPsec 不会主动对封装前的原始包分片,但封装后的包会因超 MTU 而被动分片(DF=0时)或丢包(DF=1时),这两种情况都会导致性能下降或通信异常。

因此,**不建议内网侧保留 1500 的 MTU **,而是应根据 IPsec 的封装开销(通常减80100字节)将内网侧 MTU 调整为 14001420,从源头避免封装后超 MTU 的问题。

相关推荐
Bazingga10 小时前
Java16 record 完整拆解——语法、语义、限制、反射
java·后端
对象存储与RustFS10 小时前
网盘限速逼你开会员?用 RustFS 自己搭一个不限速的“私人网盘
服务器·后端·docker
Thneonl10 小时前
你写的 NetworkPolicy 可能一条都没生效
后端·架构
王中阳Go10 小时前
质保期第 90 天我翻了一遍日志目录:交付后真正会坏的 3 处
人工智能·后端·agent
卷无止境11 小时前
一人公司的全栈选型指南:让 AI Agent 写得快,也让生意跑得稳
后端·python
拖孩12 小时前
AI 帮我写的小程序「厨菜记」上线满月了,挣了两百块!!!
前端·后端·微信小程序
流烟默12 小时前
SSE 实战:在 SpringBoot + Vue 项目中零依赖实现轻量级实时消息推送
vue.js·spring boot·后端·sse
upala12 小时前
【仓颉语言入门 · 第二篇 第 9 课】
后端
Rain的Java大神之路13 小时前
别再死磕 MySQL 了:向量数据库与 RAG 生产落地实录(Java 工程师专场)
java·后端·面试
雨中飘荡的记忆13 小时前
SDD × Claude Code:先写清楚,再让 AI 写代码
后端