为什么 GitHub 不喜欢我的 MTU
让我来告诉你我花了一整天与我的 WireGuard VPN 搏斗的挫败经历, 以及为什么 GitHub 成了唯一一个不配合的网站。我希望我的经验, 特别是如果你像我一样在 microk8s 环境中运行 WireGuard,能帮你省去一些麻烦。
环境:microk8s、Ubuntu 和 WireGuard
我的环境有点复杂。 我有一个运行在 Ubuntu 24.04.2 LTS 服务器节点(GNU/Linux 6.8.0-54-generic x86_64)上的 microk8s 集群。 我将我的 WireGuard VPN 服务器作为 pod 在这个 microk8s 集群中运行。这增加了一层我最初没有考虑到的网络复杂性。
问题:GitHub 无法访问(但其他一切都很好)
一切似乎都很好。我可以通过我的 WireGuard VPN 访问大多数网站。
Google、YouTube、Twitter——都没问题。但是 https://github.com
就是无法加载。
curl https://github.com
无限期地挂起。我挠着头,想知道是 DNS 问题、防火墙问题,还是其他什么问题。
调试:深入网络
初始测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
curl github.com # 有效!返回 301 重定向到 HTTPS curl -v github.com * Host github.com:80 was resolved. * IPv4: 20.27.177.113 * Trying 20.27.177.113:80... * Connected to github.com (20.27.177.113) port 80 > GET / HTTP/1.1 > Host: github.com > User-Agent: curl/8.5.0 > Accept: */* > < HTTP/1.1 301 Moved Permanently < Content-Length: 0 < Location: [https://github.com/](https://github.com/) < * Connection #0 to host github.com left intact curl [https://github.com](https://github.com) # 挂起...
这令人难以置信地困惑。HTTP 有效,但 HTTPS 无效。 但是 Google 和 Twitter 等其他 HTTPS 网站都很好。这表明问题特定于 HTTPS,并且可能与 GitHub 有关。
MTU 调查:罪魁祸首出现
我怀疑是 MTU 问题,因为 HTTPS 连接存在问题。因此,我检查了我的 WireGuard 客户端接口:
然后,我连接到在我的 microk8s 集群中运行的 WireGuard pod,并检查了服务器端接口:
发现不同的 MTU,这很可能是问题的根源。
MTU 调整和测试:解决方案
我开始系统地降低客户端配置上的 MTU,以匹配 pod 内服务器端 MTU。
重新启动我的 WireGuard 连接后,我再次尝试
curl https://github.com
。1
curl -v [https://github.com](https://github.com) # 成功!
GitHub 在浏览器中也可以正常加载。
为什么会发生这种情况:深入了解网络
- 路径分片和 microk8s: microk8s 网络设置与 WireGuard 的封装相结合,增加了潜在分片的层数。
- TLS 握手和 GitHub: GitHub 的 TLS 握手,可能由于其大小或网络路径,对路径分片特别敏感。
- 本地与路径分片: 通过降低 MTU,我强制进行本地分片(由我的操作系统控制),而不是依赖不可预测的路径分片。
理解 MTU 和分片
MTU 是可以在网络接口上传输的最大 IP 数据包大小,而无需分片。当数据包超过网络链路的 MTU 时,会发生分片,导致其被分成更小的片段。虽然本地分片(发送设备进行的分片)通常是可管理的,但路径分片(网络路径上的路由器进行的分片)可能导致数据包丢失、重新排序,甚至被防火墙阻止。
分片对 TLS 握手的影响
TLS 握手是建立客户端和服务器之间安全加密连接的关键过程。它涉及交换消息,包括证书和加密密钥。如果由于分片而丢失了握手数据包的任何部分,则整个握手都可能失败,从而导致连接问题。
为什么 GitHub 受到影响而其他网站没有
估计是因为不同的网站具有不同的特性,包括:
- 数据包大小: 具有较大内容(如 GitHub)的网站更有可能生成较大的数据包,从而增加分片的风险。
- CDN 和服务器差异: 不同的网站使用不同的 CDN 和服务器,它们可能具有不同的 MTU 设置和网络路径。
- TLS 握手差异: 网站之间的 TLS 握手过程可能不同,从而影响数据包大小和对分片的敏感性。
解决问题:降低 MTU
根本原因是我的 WireGuard 客户端和在我的 microk8s 集群中作为 pod 运行的 WireGuard 服务器之间的 MTU 不匹配。 通过将客户端的 MTU 设置为与服务器相同的值(1370),我解决了问题。
通过降低 WireGuard 客户端和服务器上的 MTU,用户可以控制分片发生的位置。 本地分片通常比路径分片更可靠,因为它由发送设备处理。这确保数据包被分片成可以遍历网络路径而无需进一步分片的大小,防止数据包丢失并确保成功的 TLS 握手。
主要收获
- MTU 和分片会显著影响网络性能和可靠性,尤其是对于 TLS 等敏感协议。
- 理解 MTU 和分片的细微差别对于排除网络连接问题至关重要。
- 通过仔细调整 MTU 设置和控制分片,可以确保平稳可靠的网络通信。
- 如果你在像 microk8s 这样的容器化环境中运行 WireGuard,请密切关注 MTU 设置。
- 始终检查并匹配 WireGuard 客户端和在其容器环境中的服务器之间的 MTU 设置。
- 使用
curl -v
、ip link show
和tcpdump
(如果需要)来调试网络问题。 - 请记住,你的客户端、你的 microk8s 服务器节点和 Internet 之间的网络路径可能具有许多不同的 MTU 值。
我希望这篇博文能为你提供有关排除与 MTU 和分片相关的 WireGuard VPN 问题的思路.