方永、南天紫云

道亦有道

WireGuard之MTU、MSS
2022年09月10日

UDP + socks5 改用 WireGuard 后灵活性提升了不少,速度也有提升(少了socks5的握手过程)。 但是,这个方案使用时遇到一个诡异的问题,就是访问某些网址时会超时,今天算是彻底解决了, 记录一下过程。

这个方案刚配置好时,所有连接都是超时的,逐渐调整MTU值,大部分网址可以用了。 但是,还是有一些网站会超时,分析是这些网站都用了fastly.net的CDN,用 drill 查看 DNS 解析,发现虽然这些网站的域名配置了ipset,但在 ipset list中并没有,对比发现是 smartdns的问题, 提了 issue ,最近包含该fix的版本在ArchLinux仓库 release了,于是更新后访问这些网址,问题照旧。

难道是 fastly.net 的 CDN 有什么特别之处?

看其官网,说是可以检测到VPN及代理,这是什么黑魔法?

openssl s_client 测试之,连接已建立后就没有再收到后续的数据了。而其它网站是可以的。

tcpdump VPS 上 WireGuard 的网卡,果然,TCP 三次握手后,只有 TLS 的 client hello,并没有收到 server hello。

用 VPS 上的 socks5 代理可以正常访问。

百思不得其解。

于是又 tcpdump VPS 的出口网卡,很惊讶地发现,居然有 server hello 回包。

在内核 NAT 转发到 WireGuard 的网卡之后,这个数据包就被丢弃了。至少,fastly的黑魔法作用之处不在敌方,而在内部。

于是查看 iptables几张表的配置,并无异常,查看sysctl网络相关配置,也无疑点。

再次分析 WireGuard 网卡上抓到的包,Client Hello 之后有 TCP Previous segment not capture ,查看其内容,正好是

Server Hello 的数据包,网上搜索 wireshark 的这个异常提示,很简单,就是 TCP 数据包的 Seq 不等于前续包的 Ack + Len 造成的。

分析 用 socks5 访问时的数据包,看到 Server Hello后的数据包有 TCP segment of a reassembled PDU,这个提示表示数据包 是重新组装的。

于是想到MTU,TCP协议也有类似的概念?就是 MSS 。

回头再看 TCP 的 SYN 数据包,果然正常访问的 TCP SYN 的 MSS 和超时的有区别,超时的MSS 显然大于 WireGuard 网卡的MTU了。

然后再找 modify MSS 相关, 有以下命令:

iptables -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

执行,问题解决。