curl 卡在 Client Hello 问题复盘:MSS/MTU 不匹配导致 PMTUD 黑洞
一、故障现象


卡在了这里。是因为【网络层 MTU 与 TCP MSS 不匹配】需要对方【修复(MSS Clamping)】。
执行命令:
curl -vk https://www.good.com/1234 -H 'Content-type:application/xml' -d 'asdf'
输出显示:
- TCP 连接成功:
Connected to 192.168.0.3 port 443 (#0) - ALPN 协商完成:
h2、http/1.1 - 卡在:
TLSv1.3 (OUT), TLS handshake, Client hello (1) - 后续无任何回包,直到超时。
同时测试:
telnet 192.168.0.3 443
可以成功建立连接。
二、现象分析
telnet成功:说明底层路由可达,TCP 三次握手正常(小包交互)。curl卡在 Client Hello:TCP 握手成功后,客户端发出第一个携带应用层数据的包(TLS Client Hello),但这个大包丢失,导致 TLS 握手无法继续。
三、根因分析

1. MTU 与 MSS 基础
- MTU:链路层最大传输单元,以太网默认 1500 字节。
- MSS:TCP 最大报文段长度。
MSS = MTU - IP头(20) - TCP头(20) = 1460(IPv4)。 - TCP 三次握手时,双方在 SYN/SYN-ACK 中通告各自 MSS,发送方取对端通告值和本地推算值中的较小值。
2. 为什么小包通、大包丢?
telnet和 TCP 握手包很小,不会触发 MTU 限制。- TLS Client Hello 包较大(包含 SNI、ALPN、加密套件、密钥共享等,可能 1000~1400 字节)。
- 若客户端通告 MSS 为 1460,则会尝试发送 payload 接近 1460 的 TCP 包,加上 IP/TCP 头总长约 1500。
- 实际路径 MTU 可能小于 1500(VPN 隧道、PPPoE、云专线等),大包在中间设备超限。
- 若包带
DF标志,中间路由器无法分片,丢弃该包,并期望返回 ICMPFragmentation Needed。 - PMTUD 黑洞 :若中间防火墙或安全组过滤了 ICMP 差错报文,客户端收不到反馈,以为网络拥塞,触发 TCP 重传;重传仍是大包,仍被丢,最终
curl卡死。

3. 为什么调整 MSS 能修复?
- 在网关或客户端执行 MSS Clamping(MSS 钳制),将 MSS 强制改小(如 1360 或 1400)。
- 客户端发出的 TLS Client Hello 被 TCP 层拆分成更小的段,加上头部后总长度小于路径 MTU。
- 小包顺利穿过中间链路,服务器收到 Client Hello,TLS 握手继续,问题修复。
四、验证与修复过程

1. 调整前抓包验证
sudo tcpdump -ni any host 192.168.0.3 and port 443 -vv
可看到客户端发出 Client Hello 后,对方没有 ACK,或客户端一直重传,但始终没有 Server Hello。
同时探测路径 MTU:
ping -M do -s 1472 192.168.0.3
可能 100% 丢包。
2. 实施修复(MSS Clamping)
Linux 网关示例:
# 限制经过网关的 TCP SYN 包 MSS 为 1360
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1360
本机发出的流量:
iptables -t mangle -A OUTPUT -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1360
1360 是较安全的通用值,尤其适合存在 VPN 或隧道封装的场景。
3. 调整后验证
- 再次执行
curl -vk ...,TLS 握手顺利完成。 - 抓包确认 Client Hello 被拆分为多个较小 TCP 段,不再超过路径 MTU。
- TCP 连接能正常传输大文件。
五、经验总结与预防措施
- PMTUD 黑洞是运维高频坑:云环境、VPN、PPPoE、GRE/IPIP 隧道中极其常见。特征:小包通、大包丢、TCP 握手成功、TLS/HTTP 卡死。
- 放行 ICMP 差错报文 :不要一刀切封禁所有 ICMP。必须放行:
- IPv4:
ICMP type 3 code 4(Fragmentation Needed) - IPv6:
ICMPv6 type 2(Packet Too Big)
- IPv4:
- 边缘网关标配 MSS Clamping :在出口路由器、防火墙或云网关上,建议全局开启
tcp adjust-mss或 iptablesTCPMSS --clamp-mss-to-pmtu,作为兜底方案。 - 排查工具箱 :
ping -M do -s <size>:探测路径 MTU。tracepath或mtr --mtu:探测每一跳 MTU。tcpdump:观察重传,特别是大包是否有去无回。
- 注意方向 :MSS 双向独立,MSS Clamping 记得同时处理
FORWARD链的入方向和出方向,确保 SYN 和 SYN-ACK 都被正确钳制。
六、结论
本次问题虽然表现为 TLS 握手失败,但本质是网络层 MTU 与 TCP MSS 不匹配的经典案例。调整 MSS 相当于给 TCP 层打了一个"截断补丁",让数据包绕过路径中的"窄门",从而恢复通信。