MSS 钳制解决什么问题
隧道或跨网段路径上,两端主机的 MTU 往往大于路径实际可承载的尺寸,而中间设备又阻断 ICMP 差错报文时,就会出现「小包通、大包卡死」的经典现象。给每台主机逐个降 MTU 既不现实也不彻底。更标准的做法是在网关或防火墙上对经过的 TCP SYN 做 MSS 钳制:把双方协商的最大分段长度改到安全值,从源头避免超尺寸报文。
基本信息
| 适用平台 | Linux 网关(iptables/nftables)、思科 IOS、华为 VRP、H3C |
|---|---|
| Linux 做法 | iptables -t mangle 的 TCPMSS 目标,或 nftables 的 maxseg 设置 |
| 网络设备做法 | 接口下配置 tcp adjust-mss / tcp mss |
| 作用范围 | 只影响 TCP 的 MSS 协商,不影响 UDP 与 ICMP |
| 协议依据 | RFC 879:TCP Maximum Segment Size |
典型使用场景
- IPsec/SSL VPN 隧道内业务大包卡死:用钳制替代逐台改 MTU
- GRE 或 VXLAN 封装导致有效负载变小:在网关统一处理
- 跨运营商或跨云链路存在 MTU 差异:集中在出口设备解决
- PPPoE 拨号链路上网异常:确认是否需要对 TCP SYN 钳制
- IPv6 环境(不支持中间分片):钳制更为必要
Linux 网关实现
Linux 网关实现
# iptables:对经过的 TCP SYN 按已知 PMTU 钳制 MSS
sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
# 也可以指定固定值(隧道场景常用 1400 以下)
sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1360
# nftables 等价写法
# nft add rule ip mangle forward tcp flags syn tcp option maxseg size set rt mtu
# 验证钳制是否命中:看 mangle 表计数
sudo iptables -t mangle -L FORWARD -nv | head网络设备侧配置
网络设备侧配置
# 思科 IOS
interface GigabitEthernet0/1
ip tcp adjust-mss 1400
# 华为 VRP
interface GigabitEthernet0/0/1
tcp adjust-mss 1400
# H3C
interface GigabitEthernet1/0/1
tcp mss 1400方案对照
| 方案 | 优点 | 局限 |
|---|---|---|
| 网关钳制 MSS | 一次配置覆盖所有主机,无需改动应用 | 只对 TCP 生效,UDP 与 ICMP 不受影响 |
| 逐台降低接口 MTU | 对所有协议生效 | 运维成本高,容易遗漏,弹性差 |
| 应用侧分片 | 可控性强 | 需要改代码,通用性差 |
| 固定 MSS 值 | 结果可预测,便于跨厂商对齐 | 目标值选错会导致性能损失或问题依旧 |
| 按 PMTU 钳制 | 自适应路径实际尺寸 | 依赖本机已知的 MTU,隧道接口配置错误会连带钳错 |
MSS 钳制只作用于 TCP:UDP 大包与 ICMP 仍需依赖正确的路径 MTU 发现机制,或由应用层控制报文尺寸。