最近因为 iKuai 的安全漏洞问题,一直在推进路由往 OpenWRT 切换,但自从切换到 OpenWRT 到就一直出现卡顿、网页白屏、图片无法加载(或者要等很久)、应用连接超时、公众号文章加载不出来、TapTap 授权加载不出来等各种诡异网络问题。更见鬼的是问题出现一会儿就会自己消失,排障的时候完全不知道自己修好了没有。虽然持续时间很短,但这么一会儿就足够让人抓狂了。
另一方面,游玩 CS2 之类的基于 UDP 的网游却丝滑流畅,完全不丢包。完全不像有问题的样子。
为了进行故障排除,我卸载了所有安装的插件,甚至重刷了系统,不幸的是问题依旧存在。而切换到原本的 iKuai 却完全没问题。
环境
ImmortalWrt 25.12.2, 也试过官方的 FriendlyWrt。
IPV4 + IPV6 双栈,PPPoE 桥接拨号。IPV6 已启用。
MTU 默认,DNS 运营商默认,无额外调整,其他全部 ImmortalWrt 默认。
使用 Ping 命令进行 MTU 测试,为标准 1500 – PPPoE 的包头,1492 MTU。
原因
该问题实际上是 IPV6 的 MTU 问题,而且只有 IPV6 受影响。由于 IPV6 的 PMTUD 机制的探测只有 10 分钟有效期,每隔 10 分钟就要重复探测一次,在这期间就会出现明显的网络问题。知乎上有一篇文章讲的不错,可以移步那里了解背后的故事。
对于 IPV4 协议栈,OpenWrt 自动减去了 PPPoE 协议的包头,将 MTU 降低到了 1492,这没问题,这也是为什么走 IPV4 协议的应用都没事。
而 IPV6 不知道 OpenWrt 是怎么处理的,默认 RA MTU 似乎是 1500,这显然会带来问题。不过如果 PMTUD 正常工作的话,设备应该会很快调整过来。但不幸的是 PMTUD 依赖 ICMP 协议工作,如果你的防火墙干掉了 ICMP,那就直接进入了 MTU 黑洞。
而 Windows 的 Ping 命令好巧不巧不支持测试 IPV6 的 MTU 的情况,这也是导致一开始没排查出来的关键。
解决方案
最推荐的方案是在 LAN 接口上直接写死 IPV6 RA 报文的 RA MTU,在一开始的时候就阻止 IPV6 自己去探测,如下图所示,我调整为了 1416:

另一种方式就是修好 ICMP,但 ICMP 出问题的原因可太多了,在移动设备上这可能并不由我说了算……
另一方面,在 LAN(WAN也要开,这两个分工不同) 接口上开启 MSS Clamping 可能也能缓解这个问题,但是通过 IPV6 的 UDP 包可能也会有问题。但这对路由器负载较大,而且 UDP 包通过 IPV6 传输大包可能也会有问题。
综上,还是直接改 RA MTU 好一些。在修改之后,也是顺利的解决了这次的问题,恢复了正常上网。OpenWrt 在成为是真正成熟好用的路由系统上还有很长的路要走。


