多层隧道中MTU黑洞的排查:30KB/s scp之谜
内容提要
跨区域GPU集群通过WireGuard+IPsec双层隧道互联,因安全合规禁用ICMP。出现单向故障:B到A的scp大文件传输速度仅30KB/s。排查确认为PMTUD黑洞——中间节点需回ICMP通知包过大,但ICMP被禁,发送方持续重传超大包。解决方案为MSS Clamping,在网关强制改写MSS,以少量效率损失换取百倍稳定性。
延伸解读
为何单向故障是MTU问题的典型信号
文章指出,A到B全速而B到A仅30KB/s,这种单向症状常指向路径MTU发现(PMTUD)黑洞。因为隧道封装可能只在一个方向增加开销,或中间节点对ICMP的处理策略不同,导致发送方无法获知包过大。排查时应优先怀疑MTU,而非带宽限制或协议缺陷。
无ICMP环境下的诊断思路
由于ICMP被禁,无法用ping测试路径MTU。作者通过iperf3进行TCP默认测试、UDP对照测试和TCP MSS步进测试来定位。UDP正常说明链路本身无碍,而TCP在MSS 1400时崩溃、1350时恢复,直接锁定PMTUD黑洞。这种方法依赖TCP行为指纹,适合ICMP不可用的场景。
MSS Clamping:权衡与实施要点
在网关强制改写TCP SYN包的MSS值,可避免发送方使用过大包。文章示例对转发流量设MSS 1280,本地流量设1350,并关闭TSO/GSO/GRO以减少CPU开销。这种方案牺牲少量有效载荷,但换来百倍稳定性。需注意,MSS Clamping只对TCP有效,且需在正确的链路上配置。
根治方案与临时措施的选择
理想方案是放行必要的ICMP类型(IPv4 Type 3 Code 4,IPv6 Type 2),让PMTUD正常工作。若安全策略不允许,可降低隧道接口MTU或采用MSS Clamping。文章选择后者,因其不依赖ICMP且部署灵活。读者应根据自身合规要求,在根治与缓解之间权衡。
Q&A
为什么在禁用ICMP的网络中,scp大文件传输速度会骤降到30KB/s?
这是因为PMTUD黑洞:发送方根据默认MSS发送大包,中间节点发现包过大需要回ICMP通知,但ICMP被禁用,发送方收不到通知,误以为拥塞而持续重传超大包,导致吞吐量被重传拖垮。
在没有ICMP的情况下,如何诊断MTU黑洞问题?
可以通过TCP行为指纹来诊断:先用iperf3默认TCP测试观察带宽和重传;再用UDP测试确认链路正常;最后进行TCP MSS步进测试,例如从-M 1400开始,若带宽崩溃则逐步降低MSS,直到找到能恢复带宽的值(如-M 1350)。
什么是MSS Clamping,它如何解决MTU黑洞问题?
MSS Clamping是在网关处强制改写TCP SYN包中的MSS值,使其小于路径MTU,从而避免发送过大的数据包。这样即使ICMP被禁用,也能防止黑洞,因为发送方从一开始就使用较小的MSS。
在多层隧道(如WireGuard+IPsec)中,MTU和MSS的关系是怎样的?
TCP MSS是TCP段的最大有效载荷,受路径MTU限制。IPv4中,MSS ≈ MTU - 20(IP头) - 20(TCP头) - 选项。标准以太网MTU 1500对应MSS约1460。但在多层隧道中,封装头会消耗MTU,导致默认的大MSS成为过载包。
除了MSS Clamping,还有哪些解决MTU黑洞的方法?
理想方法是允许必要的ICMP类型:IPv4的ICMP Type 3 Code 4(需要分片)和IPv6的ICMPv6 Type 2(包太大)。另一种变通方法是降低WireGuard或IPsec接口的MTU,以停止出血。
如何具体实施MSS Clamping?请给出iptables命令示例。
可以使用iptables的TCPMSS目标。例如,对转发流量设置MSS为1280:iptables -t mangle -I FORWARD -p tcp -d 10.0.0.0/24 --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1280;对本地流量设置MSS为1350:iptables -t mangle -I OUTPUT -p tcp -d 10.0.0.0/24 --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1350。