在我们的教堂,我们通过友好邻居的 WiFi 获得互联网上行链路。起初一切似乎(至少)都很好,但几周以来,一般的“互联网稳定性问题”增多,大约 2 周以来,我现场的 Raspberry Pi 无法与互联网建立 SSH 链接。
我还不明白根本原因,但解决方法是:将 MTU 设置为 1452在客户端上。
我不想降低整个网络的 MTU,而且我非常想了解实际情况。
总体问题是:为什么将 MTU 设置为 1452 可以解决任何 Internet 连接问题以及如何解决根本原因?
这是一种网络图:
Vodafone -------------- Kabelbox ) ) ) ( ( ( NanoStation loco m5 -------------- Linux client
DS-Lite over PPPoE 192.168.0.0/24 192.168.157.0/24
Default MTU:
1452 2286 1500
从左到右
- 沃达丰互联网服务提供商
- 通过电视线使用 PPPoE 进行 DS-Lite
- “Kabelbox”(德国市场名称接线盒,组合电缆调制解调器+路由器+WiFi AP)
- WiFi 5GHz 链路(Kabelbox 提供单独的“Backbone” SSID)
- Ubiquity NanoStation loco m5(WiFi 客户端、IPv4 路由器、基于 Linux 2.6.32.71 的操作系统)
- 以太网电缆
- Linux 客户端(通常是交换机 + Raspberry Pi,用于调试使用 Debian Stretch 直接连接到笔记本电脑)
这很难调试,因为问题不是确定性的,至少看起来不是永久性的。我还没有找到一个最小的测试来证明这个问题。
症状
- 树莓派多天都无法建立 SSH 连接
- Raspberry Pi 多天无法发送系统管理邮件
- DNS 解析有时会失败
- 网页有时无法加载(即使是相同的 URL 有时可以加载,有时又不能加载)
- Signal 桌面版和 Android 应用程序无法连接/更新(实际上我发现的最可靠的测试)
以上所有问题超时问题。程序会尝试但永远不会收到响应,因为请求或响应数据包/帧被丢弃。
我的研究
经过一番摸索,我发现这可能与 MTU 有关。偶然将 MTU 设置为 1200 消除了症状。
我已经检查了默认的 MTU 值:
ip link
Linux 客户端上显示 1500(以我的经验来看,这是相当标准的)ip link
NanoStation 显示 LAN 为 1500,WiFi 为 2268(对于 802.11 来说是可以的)traceroute --mtu www.daniel-boehmer.de
显示 Kabelbox 和 Vodafone 之间有 1452 个似乎是 PPPoE 上 DS-Lite 的默认设置)
据我所知,NanoStation 和 Kabelbox 路由器应该透明地对大于下一跳 MTU 的数据包进行分段。我可以证明 Kabelbox 至少有时可以正确执行此操作(在 NanoStation 上运行命令):
XW.v6.3.2-cs.33267.200715.1627# ip link set mtu 1500 dev ath0
XW.v6.3.2-cs.33267.200715.1627# ping www.daniel-boehmer.de -c1 -s 1472
PING www.daniel-boehmer.de (185.142.180.110): 1472 data bytes
1480 bytes from 185.142.180.110: seq=0 ttl=52 time=38.633 ms
--- www.daniel-boehmer.de ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 38.633/38.633/38.633 ms
我也非常确定 NanoStation 确实正确分段。如果DF
设置了,它会返回错误:
root@linux:~# ip li set mtu 1500 dev wlp3s0
root@linux:~# ping www.daniel-boehmer.de -c1 -s 1472 -M dont
PING www.daniel-boehmer.de (185.142.180.110) 1472(1500) bytes of data.
1480 bytes from lists.christallin.net (185.142.180.110): icmp_seq=1 ttl=51 time=38.8 ms
--- www.daniel-boehmer.de ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 38.756/38.756/38.756/0.000 ms
root@linux:~# ping www.daniel-boehmer.de -c1 -s 1472 -M do
PING www.daniel-boehmer.de (185.142.180.110) 1472(1500) bytes of data.
From 192.168.157.1 (192.168.157.1) icmp_seq=1 Frag needed and DF set (mtu = 1452)
--- www.daniel-boehmer.de ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
那么是什么导致了这些问题呢?
我尝试将 MTU 设置为1200在 NanoStation 的所有接口上,但这对 Linux 客户端没有影响,例如 Signal 无法连接。
一旦我将 MTU 设置为 1452在客户端上,信号已接通。所有症状消失。
我很困惑。(我希望我的笔记仍然可以理解。)
为什么需要在客户端上设置 MTU,并且两个路由器都不透明地进行分段?
答案1
TCP/IP 协议栈通常使用自由度(“不要碎片化”)少量找出路径的 MTU,以便完全避免碎片化(相当低效)。ICMP变得至关重要,因为信号在某些路径的网络接口上“需要分段”,人们往往不知道这一点,在盲目阻止所有 ICMP 时会中断该信号。作为进一步的解决方法,Linux TCP/IP 堆栈有支持对于路径 mtu 探测:
tcp_mtu_probing - INTEGER
Controls TCP Packetization-Layer Path MTU Discovery. Takes three values:
0 - Disabled
1 - Disabled by default, enabled when an ICMP black hole detected
2 - Always enabled, use initial MSS of tcp_base_mss.
因此,如果设置 MTU 1452 可以解决问题,则意味着上游 Kabelbox 不会报告它具有窄 PPPoE 上行链路,或者没有听到它的报告。
我将 sysctl 设置net.ipv4.tcp_mtu_probing
为 1 (甚至 2) 。然后检查整个链条,看看哪里出了问题。