16
2024
12
14:16:36

OpenWrt 中的 MSS 钳制是干什么用的

老早之前就看到 OpenWrt 防火墙中的 MSS钳制选项,一直没有过多思考其作用,可以在防火墙 ->wan-> 常规设置中找到,wan 区域中该选项默认是开启的,其他区域默认没有。这里以发现问题 -> 解决问题的思路来探讨这个选项的意义及作用。

MTU 问题

  这个问题很常见,当 Don't Fragment 标志被设置在 IPv4 头中,且 IP 数据包大小超过接口 MTU 时,就会因为无法分片而被丢弃。典型的状况就是,DNS 解析正常、可以 ping 通目标、HTTP 访问正常、部分网站 HTTPS 异常。这是由于 TLS 握手时服务端会响应一个包含证书的远超 MTU 大小的数据包,该包很大程度上 (当服务端发出时就被设置了 DF 标志) 会被丢弃,导致 HTTP 网站无法打开,Wireshark 可以观察到 TCP previous segment not captured 消息。

  这次碰到的情况的简易网络拓扑可以如下显示:

1
2
3
4
PC <---> (LAN) OpenWrt (Wireguard) <---> (Wireguard) Server (WAN)
LAN MTU = PC MTU = 1500
Wireguard MTU = 1400
WAN MTU = 9000

  可以确信各自的 MTU 都合法,网络通信均正常,但是仍旧发生了 MTU 问题。在 PC 和 Server 处进行抓包,可以观察到 PC->Server 的 TCP 第一次握手的 MSS 值为 1460,Server->PC 的 TCP 第二次握手的 MSS 值为 1436,显然 TCP 数据段在经过 Wireguard 隧道的时候,PMTU (路径 MTU 发现) 机制没有正常工作,导致过大的数据包被丢弃。接下来是思考和解决的过程:

  1. 再次检查 Wireguard 两端的 MTU 配置,均正常

  2. 怀疑 OpenWrt 路由表的配置,该路由条目为手动添加,怀疑 MTU 错误,发现路由默认 MTU 即为接口 MTU,正常

  3. 怀疑 nftable 出现了问题,因为该路由是通过规则来决定使用的,即对于某些数据包设置标记 0x8888,然后添加一个规则,有 0x8888 标记的数据包使用 0x8888 号路由表

  4. 尝试在设置 0x8888 标记时,强制缩小 TCP 的 MSS 值,这个专业术语叫做 TCP MSS Clamping,看到 Clamping 这个单词还有点陌生,一查夹紧的意思,顿时恍然大悟,这不就是 TCP钳制的意思

  5. 所以只要将 Wireguard 接口对应区域的 TCP钳制选项打上勾,这个问题便迎刃而解,握手时 MSS 值将会被缩小到 1360 (1400-IP 头 - TCP 头),从而可以顺利通过 Wireguard 隧道

TCP 钳制

  用白话文概括一下:这个选项就是在 TCP 三次握手的时候,将 MSS 值匹配至接口的 MTU 值。这个选项理应默认就打开,不知为何默认是关闭的状态,因为会产生性能消耗?或者说会使硬件 NAT 机制失效?话说回来一般家庭网络情况也较为简单,WAN 区域的 TCP钳制选项打开即可应对大多数情况。




推荐本站淘宝优惠价购买喜欢的宝贝:

image.png

本文链接:https://hqyman.cn/post/8714.html 非本站原创文章欢迎转载,原创文章需保留本站地址!

分享到:
打赏





休息一下~~


« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

请先 登录 再评论,若不是会员请先 注册

您的IP地址是: