AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 500448
Accepted
Kevin
Kevin
Asked: 2013-04-18 19:33:14 +0800 CST2013-04-18 19:33:14 +0800 CST 2013-04-18 19:33:14 +0800 CST

来自网关 VM 的神秘“需要碎片化”拒绝

  • 772

我一直在解决严重的 WAN 速度问题。我修复了它,但为了其他人的利益:

通过 WireShark、日志记录和简化配置,我将其缩小到从对内部网络上的服务器执行 DNAT 的网关的一些奇怪行为。网关(一个 CentOS 机器)和服务器都在同一个 VMware ESXi 5 主机上运行(事实证明这很重要)。

这是发生的事件序列 - 非常一致 - 当我尝试使用直接连接到网关 WAN 端的测试客户端(绕过此处通常使用的实际互联网连接)从 DNAT 后面的 HTTP 服务器下载文件时:

  1. 通常的 TCP 连接建立(SYN、SYN ACK、ACK)正常进行;网关以两种方式正确地重新映射服务器的 IP。

  2. 客户端发送带有 HTTP GET 的单个 TCP 段,这也被正确地 DNAT 到目标服务器。

  3. 服务器通过网关发送一个 1460 字节的 TCP 段,其中包含 200 响应和文件的一部分。线路上帧的大小为 1514 字节 - 有效载荷为 1500。该段应该穿过网关但没有。

  4. 服务器通过网关发送第二个 1460 字节的 TCP 段,继续文件。同样,链接有效负载为 1500 字节。该段也不穿过网关,也从未被考虑在内。

  5. 网关将 ICMP 类型 3 代码 4(目标无法到达 - 需要分段)数据包发送回服务器,引用事件 3 中发送的数据包。ICMP 数据包指示下一跳 MTU 为 1500。 这似乎是荒谬的,因为网络是 1500 字节干净的,并且 3 和 4 中的链接有效负载已经在规定的 1500 字节限制内。服务器可以理解地忽略此响应。(最初,ICMP 已被过分热心的防火墙丢弃,但已修复。)

  6. 经过相当长的延迟(在某些配置中,来自服务器的重复 ACK),服务器决定重新发送事件 3 中的数据段,这次是单独发送。除了 IP 标识字段和校验和之外,该帧与事件 3 中的帧相同。它们的长度相同,并且新帧仍然设置了 Don't Fragment 标志。 然而,这一次,网关愉快地将段传递给客户端 - 整体 - 而不是发送 ICMP 拒绝。

  7. 客户端对此进行确认,并且传输继续进行,尽管速度非常慢,因为后续段经历大致相同的被拒绝、超时、重新发送然后通过的模式。

如果客户端移动到局域网直接访问服务器,则客户端和服务器可以正常工作。

这种奇怪的行为会根据目标服务器看似无关的细节发生不可预测的变化。

例如,在 Server 2003 R2 上,如果启用了 Windows 防火墙(即使它允许 HTTP 和所有 ICMP),7MB 的测试文件将花费 7 小时来传输,而问题根本不会出现,而且矛盾的是永远不会被拒绝如果禁用了 Windows 防火墙,则首先由网关发送。另一方面,在 Server 2008 R2 上,禁用 Windows 防火墙没有任何效果,但传输虽然仍然受到影响,但比在启用防火墙的 Server 2003 R2 上快得多。(我认为这是因为 2008 R2 使用了更智能的超时启发式算法和 TCP 快速重传。)

更奇怪的是,如果目标服务器上安装了 WireShark,问题就会消失。因此,为了诊断问题,我必须在单独的 VM 上安装 WireShark 以观察 LAN 端网络流量(出于其他原因,这可能是一个更好的主意。)

ESXi 主机版本为 5.0 U2。

networking
  • 4 4 个回答
  • 11175 Views

4 个回答

  • Voted
  1. David Schwartz
    2013-04-18T20:08:06+08:002013-04-18T20:08:06+08:00

    您不能丢弃需要 ICMP 分段的消息。它们是 pMTU 发现所必需的,而 pMTU 发现是 TCP 正常工作所必需的。请 LART 防火墙管理员。

    根据透明度规则,充当防火墙的包过滤路由器允许带有不分片 (DF) 位设置的传出 IP 数据包不得阻止传入的 ICMP 目标不可达/需要分片错误发送以响应出站数据包到达防火墙内的主机,因为这会破坏生成合法流量的主机对路径 MTU 发现的符合标准的使用。-- 防火墙要求 - RFC2979(强调原文)

    十多年来,这种配置已被公认为根本上已被打破。ICMP 不是可选的。

    • 7
  2. Best Answer
    Kevin
    2013-04-22T02:30:02+08:002013-04-22T02:30:02+08:00

    我终于弄清楚了。结果证明是 VMware 在目标服务器的虚拟 NIC 中实现 TCP 分段卸载的问题。

    服务器的 TCP/IP 堆栈将向 NIC 发送一个大块,并期望 NIC 将其分解为限制为链路 MTU 的 TCP 段。然而,VMware 决定将其留在一个大的部分中,直到——好吧,我不确定什么时候。

    当它到达网关 VM 的 TCP/IP 堆栈时,它似乎实际上停留了一大段,这引发了拒绝。

    在生成的 ICMP 数据包中隐藏了一条重要线索:被拒绝数据包的 IP 标头指示大小为 2960 字节 - 比它似乎拒绝的实际数据包大得多。如果 TCP 段合并了迄今为止发送的两个段的数据,那么这也正是 TCP 段在网络上的大小。

    使问题很难诊断的一件事是,传输的数据实际上被分成 1500 字节的帧,只要运行在另一个 VM 上的 WireShark(连接到一个单独的混杂端口组上的同一 vSwitch)可以看到。我真的不确定为什么网关 VM 看到一个数据包而 WireShark VM 看到两个。FWIW,网关没有启用大量接收卸载 - 如果启用了我能理解。WireShark 虚拟机运行的是 Windows 7。

    我认为 VMware 延迟分段的逻辑是,如果数据要传出物理 NIC,则可以利用 NIC 的实际硬件卸载。然而,它确实看起来有问题,它在发送到另一个 VM 之前无法分段,并且就此而言不一致。我在其他地方看到这种行为是作为 VMware 错误提到的。

    解决方案只是关闭目标服务器中的 TCP 分段卸载。该过程因操作系统而异,但 fwiw:

    在 Windows 中,在连接属性的“常规”选项卡或“网络”选项卡上,单击适配器旁边的“配置...”,然后查看“高级”选项卡。对于 Server 2003 R2,它被指定为“IPv4 TCP 分段卸载”。对于 Server 2008 R2,它是“大型发送卸载 (IPv4)”。

    这个解决方案有点麻烦,可以想象在某些环境中会影响性能,所以我仍然会接受任何更好的答案。

    • 3
  3. Rob Fisher
    2014-08-03T14:16:25+08:002014-08-03T14:16:25+08:00

    我有同样的症状,问题原来是这个内核错误:https ://bugs.debian.org/cgi-bin/bugreport.cgi?bug=754294

    • 1
  4. user127779
    2015-06-24T14:52:22+08:002015-06-24T14:52:22+08:00

    我在 Linux 主机上看到了同样的问题。

    解决方案是在网关计算机的网络驱动程序 (vmxnet) 上停用大型接收卸载 (LRO)。

    引用 VMware 知识库:

    LRO 将传入的网络数据包重新组装到更大的缓冲区中,并将生成的更大但更少的数据包传输到主机或虚拟机的网络堆栈。与禁用 LRO 时相比,CPU 必须处理更少的数据包,这会降低其网络利用率。

    请参阅http://kb.vmware.com/kb/2055140

    因此,到达网关机器的数据包被网络驱动程序合并并发送到网络堆栈,将它们丢弃为大于 MTU ...

    • 0

相关问题

  • 谁能指出我的 802.11n 范围扩展器?

  • 我怎样才能得到一个网站的IP地址?

  • 在一个 LAN 中使用两台 DHCP 服务器

  • 如何在 Linux 下监控每个进程的网络 I/O 使用情况?

  • 为本地网络中的名称解析添加自定义 dns 条目

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve