背景
近期在配置某专用链路时,通过Wireguard转发三层数据包,遇到了一个较为隐蔽的问题:
从本地路由通过 WireGuard 接入专用链路出网后,部分网站无法访问。
问题表现具有明显的迷惑性:
- 同一条出口链路;
- 同一台主机;
- 有些网站完全正常,有些却始终无法打开;
- 失败的网站以 GitHub、部分海外 HTTPS 站点为主。
初看非常像 DNS、封锁、TLS 或证书问题,但最终发现根因其实非常基础:WireGuard 隧道 MTU 设置不当。
本文记录一次完整的排障过程。
一、问题现象
以 GitHub 为例,访问表现如下:
- 浏览器长时间 loading;
- 不报明确错误;
- 命令行工具也无法返回结果。
curl 表现
curl -v https://www.github.com
输出卡在 TLS 握手阶段:
* Trying 20.27.177.113:443...
* Connected to www.github.com (20.27.177.113) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
可以明确看到:
- DNS 解析成功;
- TCP 443 已连接;
- ClientHello 已发送;
- TLS 握手卡死,无任何 ServerHello 返回。
二、初步排除:不是 TCP、不是 DNS
为了进一步确认 TLS 层问题,使用 openssl s_client:
openssl s_client -connect github.com:443 -servername example.com
CONNECTED(00000003)
以及直接指定 IP:
openssl s_client -connect 20.27.177.113:443
CONNECTED(00000003)
CONNECTED 表示:
- TCP 连接在内核层面完全正常;
- 但 TLS 协商无法继续。
至此可以基本排除:
- DNS 错误;
- 路由不可达;
- 防火墙阻断 443;
- 服务器端口不可用。
三、WireGuard 接口抓包分析
既然业务流量全部经由 WireGuard 隧道出网,问题极有可能发生在隧道层。
于是直接在 WireGuard 接口 wg0 上抓包:
tcpdump -i wg0 | grep 20.27.177.113
1. TCP 三次握手完全正常
10.100.1.10 > 20.27.177.113: SYN
20.27.177.113 > 10.100.1.10: SYN, ACK
10.100.1.10 > 20.27.177.113: ACK
说明隧道双向连通性没有问题。
2. TLS ClientHello 成功发送
Flags [P.], seq 1:318, length 317
ClientHello 包体积较小,顺利通过隧道。
3. 服务端返回大包后异常
Flags [P.], seq 2849:3619, length 770
这是服务端返回的第一批 TLS 握手数据(ServerHello + 证书等)。
紧接着客户端行为异常:
Flags [.], sack {2849:3619}
Flags [R.]
表现为:
- 出现 SACK(选择确认);
- 连接被异常 reset。
这是 MTU / 分片问题的典型特征:
小包能过,大包在隧道或中间链路被丢弃或破坏。
四、为什么“只有部分网站”受影响?
这是该问题最具迷惑性的地方。
原因在于:
- 不同站点 TLS 握手阶段返回数据大小不同;
- GitHub 等站点证书链较长、TLS 扩展较多;
- 返回方向第一批 TLS 数据更容易超过实际可用 MTU;
- 一旦发生分片,而链路又不支持或错误处理分片,就会直接失败。
因此表象上看是“随机网站异常”,实际上是确定性的 MTU 边界触发问题。
五、根因确认:WireGuard MTU 设置不合理
WireGuard 默认 MTU 为 1420,但在以下场景中容易出问题:
- 专线 / MPLS / GRE / 二次隧道;
- 运营商或中间设备不支持分片;
- 额外封装导致有效 MTU 进一步下降。
当前链路实际可用 MTU 明显小于 WireGuard 默认值。
六、解决方案
在 WireGuard 接口中显式设置较小 MTU:
[Interface]
MTU = 1280
重启 WireGuard 后验证:
curl可完整返回 HTTP 响应;openssl s_client能正确输出证书链;wg0抓包中 TLS 返回包正常;- 不再出现异常 SACK 或 RST。
问题彻底消失。
七、经验总结 / Checklist
当出现以下现象时,应优先怀疑 MTU 问题:
- TCP 能连,TLS 卡死;
curl停在Client hello;- 只影响 HTTPS、大站点更容易失败;
- ICMP 不可达或 PMTU 发现被屏蔽;
- 使用隧道(WireGuard / IPsec / GRE / VXLAN)。
排查顺序建议:
curl -v看卡在哪一层openssl s_client验证 TLS- 在隧道接口抓包观察包大小
- 临时降低 MTU 验证结论