如何调试 TCP 数据包中的失败校验和/翻转位?

如何调试 TCP 数据包中的失败校验和/翻转位?

我们维护的一个 Web 应用程序最近遇到了一个非常奇怪的问题:两台物理主机上的四台虚拟机中有三台无法通过 HTTPS 连接到我们的支付提供商的服务器。调试这个问题让我对 OSI 堆栈进行了一次有趣的探索:

  1. 在应用程序级别,HTTPS 请求似乎超时了。
  2. 使用openssl s_client,我发现 SSL 握手失败
  3. 使用 tcpdump 转储流量并使用 Wireshark 检查,我注意到,对于失败的握手,初始 SYN/ACK 之后来自服务器的所有数据包都具有无效的 TCP 校验和。将数据包内容与成功握手进行比较,我发现至少有一位发生了翻转。然后,服务器尝试重新传输数据包(再次使用无效的校验和)并在 60 秒后关闭连接。

我们的支付提供商和托管公司都无法帮助我们诊断这个问题。幸运的是,这个问题在几个小时后就消失了。

然而,这个“解决方案”让我很不开心。我想知道:

  1. 造成这种行为的可能原因是什么?
  2. 如果将来再次出现此问题,如何进一步诊断?

虚拟机在 KVM 上运行 Debian 7。

答案1

因此以这篇文章作为参考:https://www.networkdatapedia.com/single-post/2017/09/13/TCP-Checksum-Error-Case-Study

我将尽力回答并澄清:

  1. 造成这种行为的可能原因是什么?

可能的原因如下:

  • TCP 校验和卸载。如前所述 - 这是一种 CPU 不计算 TCP 校验和而将其留给 NIC 的技术。NIC 可能会计算错误。
  • 有故障的 3 层设备。这需要位于 3 层,因为在成功进行以太网 CRC 校验后可能会出现 TCP 校验和错误 - 而 CRC 校验比 TCP 校验和更可靠。因此,您可以排除有故障的电缆或连接器。
  • 中间人对数据包有效载荷进行操纵。这种情况不太可能发生,因为中间人能够计算出正确的 TCP 校验和并将其放入数据包中。
  1. 如果将来再次出现此问题,如何进一步诊断?

使用提到的文章作为参考,您应该设置至少两个流量捕获位置,其中应包括虚拟机以及裸机/路由器接口。

根据网络架构,您可能会发现 L3 网络组件存在故障。不幸的是,网络上游可能存在故障,因此请确保在数据包离开和进入受控环境时捕获它们以确保无误。

就我个人的网络经验而言,完全饱和的网络可能会导致 SSH 或 HTTPS 等协议无法建立连接。确保有足够的可用带宽,并且相关主机能够及时响应。

相关内容