15.6. 使用基于路由的 MTU 设置绕过路径 MTU 发现问题

对于发送批量数据,通常来说互联网在使用较大数据包时效果更好。每个数据包都意味着一次路由决策,当发送 1 兆字节的文件时,如果使用尽可能大的数据包,则意味着大约 700 个数据包,如果使用最小的默认数据包,则意味着 4000 个数据包。

然而,并非互联网的所有部分都支持每个数据包 1460 字节的完整有效载荷。因此,有必要尝试找到能够“适应”的最大数据包,以便优化连接。

这个过程称为“路径 MTU 发现”,其中 MTU 代表“最大传输单元”。

当路由器遇到一个过大的数据包而无法一次性发送,并且该数据包被标记了“禁止分片”位时,它会返回一个 ICMP 消息,声明由于此原因被迫丢弃了一个数据包。发送主机根据此提示发送较小的数据包,并通过迭代可以找到特定路径连接的最佳数据包大小。

这种方法过去运行良好,直到互联网被流氓发现,他们竭尽全力破坏通信。这反过来导致管理员要么阻止要么限制 ICMP 流量,这是为了在安全或互联网服务的稳健性方面进行误导性的改进尝试。

现在发生的情况是,路径 MTU 发现的效果越来越差,并且在某些路由上会失败,这会导致奇怪的 TCP/IP 会话在一段时间后终止。

虽然我没有证据证明这一点,但我曾经遇到此问题的两个站点都在受影响的系统之前运行了 Alteon Acedirectors - 也许更有知识的人可以提供线索,解释为什么会发生这种情况。

15.6.1. 解决方案

当您遇到遭受此问题的站点时,您可以通过手动设置来禁用路径 MTU 发现。 Koos van den Hout 略作编辑后写道:

以下问题:我将运行 ppp 的租用线的 mtu/mru 设置为 296,因为它只有 33k6,并且我无法影响另一端的队列。在 296 的情况下,对按键的响应在合理的时间范围内。

而且,在我这边我有一个运行中的 masqrouter(当然)是 Linux。

最近我拆分了“服务器”和“路由器”,因此大多数应用程序在与路由发生的机器不同的机器上运行。

然后我遇到了登录 irc 的问题。非常恐慌!一些挖掘工作发现我已连接到 irc,甚至在 irc 上显示为“已连接”,但我没有收到来自 irc 的 motd。我检查了可能出错的地方,并注意到我之前在访问某些与 MTU 相关的网站时遇到了一些麻烦,因为当 MTU 为 1500 时我没有遇到访问它们的问题,只有当 MTU 设置为 296 时问题才出现。由于 irc 服务器阻止了几乎所有对其即时操作不需要的流量,它们也阻止了 icmp。

我设法说服了一个网络服务器的运营商,这是问题的原因,但是 irc 服务器运营商不打算修复这个问题。

因此,我必须确保传出的伪装流量以较低的外部链路 mtu 开始。但是我想让本地以太网流量具有正常的 mtu(用于诸如 nfs 流量之类的东西)。

解决方案

ip route add default via 10.0.0.1 mtu 296

(10.0.0.1 是默认网关,伪装路由器的内部地址)

一般来说,可以通过设置特定的路由来覆盖 PMTU 发现。例如,如果只有某个子网出现问题,这应该会有所帮助

ip route add 195.96.96.0/24 via 10.0.0.1 mtu 1000