在运维圈子里,大家可能都遇到过这种奇怪的问题:
浏览器能打开 HTTP 网站,但一换成 HTTPS,页面就死活打不开。
前段时间,我们就碰到这么一个典型案例。
故障现象
某公司系统在 VPN 隧道里访问 HTTPS 服务,结果就是——打不开。HTTP 正常,HTTPS 全军覆没。
问题追踪
乍一看,以为是证书、TLS 加密、浏览器兼容性这些问题。结果一层层排查下来,真正的罪魁祸首居然是:MTU(最大传输单元)。
原来:
■ 正常情况下,链路 MTU=1500,TCP MSS=1460;
■ 但由于数据要经过 IPSec 隧道,报文额外多了 52 字节封装;
■ 最终数据包=1512 字节,超过了 MTU;
■ 偏偏 HTTPS 报文设置了 DF=1(禁止分片),所以一旦超出 MTU,报文直接被丢弃;
■ 结果就是:HTTPS 握手直接挂掉。
HTTPS 为啥不分片?
因为 HTTPS 的核心是安全和完整性。TLS 协议要求传输的数据必须完整,一旦分片就有被截获或篡改的风险,所以干脆一刀切:禁止分片。
这就导致——只要 MTU 出问题,HTTPS 就比 HTTP 更容易“翻车”。
解决方法
直接改设备 MTU/MSS
让服务器和客户端都用更小的报文,比如 1400。但设备多时不现实。
让中间设备帮忙调整 MSS(最优解)
很多防火墙/路由器都有类似功能:在 TCP 握手时,把 MSS 改小,提前避免超 MTU。
■ 思科的例子就是:ip tcp adjust-mss 1400
Linux 网关
也能用 iptables 干预 TCP MSS:
这个案例其实告诉我们:
■ HTTPS 故障,不一定是“证书问题”,可能是网络层的 MTU 问题;
■ VPN/隧道场景下尤其常见;
■ 最优雅的解决方案,是让中间设备在握手阶段就“帮忙改 MSS”,而不是等到业务挂掉才救火。
所以,下次再遇到 HTTPS 打不开,别急着骂浏览器,先想想是不是报文太大了!