首页/网络/抓包与流量分析速查/MSS Clamping 的抓包验证
TCP 流分析82 条

MSS Clamping 的抓包验证

隧道环境常在出口做 MSS clamping(改写 TCP 的 MSS 选项):抓包对比改写前后 SYN 的 mss_val 即可确认策略是否生效。

MSS 收敛是怎么发生的

MSS 是 TCP 声明的单个报文段能承载的最大数据量,由两端在握手时通过选项互相告知。隧道、PPPoE 这类封装会额外占用字节,使实际可用载荷小于端到端路径能通过的尺寸,于是出口设备常主动把 MSS 改小(MSS clamping)。抓包对比改写前后的握手选项,就能确认策略是否真的落地,而不是只在配置里写了。

基本信息

抓包字段tcp.options.mss_val,过滤表达式为 tcp.options.mss
出现位置SYN 与 SYN-ACK 中各出现一次,方向不同值可能不同
验证方法在改写设备前后各抓一份,对比同一连接的 MSS 值
合理取值按封装开销核算,常见是在标准值基础上减去封装头长度
影响范围只作用于 TCP;UDP 大包问题需按路径 MTU 单独处理
关注重点两端与路径各段口径是否一致,避免大包进入后被丢弃

典型使用场景

  • 隧道接入验证:确认 VPN 或 GRE 出口确实改写了 MSS,避免大包被静默丢弃
  • 上线核对:新链路启用后对比两端 MSS,确认改写方向与数值符合设计
  • 故障复现:确认小包正常、大包失败的场景是否与 MSS 未被收敛有关
  • 策略回归:变更防火墙或负载均衡配置后,验证是否又引入了新的改写
  • 跨厂商对接:不同厂商对 MSS 的处理策略不同,用抓包对齐双方实际行为

对比与核对

对比与核对
# 改写设备前(发端)看到的 MSS
tshark -r before.pcap -Y 'tcp.flags.syn == 1 && tcp.flags.ack == 0' -T fields -e ip.src -e tcp.options.mss_val
# 改写设备后(隧道出口或对端)看到的同一个 SYN
tshark -r after.pcap -Y 'tcp.flags.syn == 1 && tcp.flags.ack == 0' -T fields -e ip.src -e tcp.options.mss_val
# 两侧数值不同即为存在改写, 结合拓扑确认是哪台设备做的
# 顺带核对 SYN-ACK 中服务端声明的 MSS 是否也被改写
tshark -r after.pcap -Y 'tcp.flags.syn == 1 && tcp.flags.ack == 1' -T fields -e ip.src -e tcp.options.mss_val

MSS 取值参考

场景常见 MSS 量级说明
标准以太网1460 左右1500 减去 IP 与 TCP 头长度
PPPoE 接入1452 左右接入层额外封装导致的缩减
IP 隧道封装按开销核算,常见 1400 上下封装头越长, 可用载荷越小
仅 IP 头带选项比标准值再小若干字节选项占用也计入头部长度
两端不一致SYN 与 SYN-ACK 数值不同方向不同属正常, 需按方向分别核对
MSS 只约束 TCP,而且只约束对端发送的报文段尺寸;UDP 或 ICMP 大包被丢弃属于路径 MTU 问题,改 MSS 不会有任何效果。
改写方向写错时,会出现一端声明的 MSS 很小而另一端很大的情况,表面看连接正常,实际大包仍会在路径上被丢弃;对照时按每一段逐项核对,而不是只看最终值。

易错点

  • 在隧道出口只做单向改写,另一端仍按大 MSS 发送,大包被丢弃却表现为「偶发卡顿」,抓包时需两端对照才能发现
  • 把 MSS 收敛当成故障:在封装链路上收敛 MSS 是标准优化,判断前先算清封装开销
  • 只核对配置没核对实际抓包,配置生效与否、被后置策略覆盖都可能,验证必须落到报文上
  • 用 MSS 收敛去解决 UDP 大包问题,方向完全错误,应改查路径 MTU 与分片行为

数据来源与参考

  • RFC 6691(MSS)
  • RFC 4459(MTU/MSS 问题)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌