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

Dan*_*per 5 networking linux ssl tcp

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

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

无论是我们的支付提供商还是我们的托管公司都对诊断此问题没有很大帮助。幸运的是,问题在几个小时后消失了。

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

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

虚拟机在 KVM 上运行 Debian 7。

小智 0

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

我将尝试回答并澄清:

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

可能的原因有以下几种:

  • TCP 校验和卸载。正如已经提到的 - 是一种 CPU 不计算 TCP 校验和而是将其留给 NIC 的技术。NIC 可能计算不正确。
  • 三层设备故障。这需要在第 3 层进行,因为成功的以太网 CRC 检查后可能会出现 TCP 校验和错误 - 这比 TCP 校验和更稳健。因此,您可以消除有故障的电缆或连接器。
  • 中间人数据包有效负载操作。这是不太可能的,因为中间人能够计算出正确的 TCP 校验和并将其放入数据包中。
  1. 如果以后再次出现这个问题,如何进一步诊断?

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

根据网络架构 - 您可能会发现有故障的 L3 网络组件。不幸的是,上游网络可能出现故障,因此请确保在数据包离开并进入受控环境时对其进行捕获,以确保安全。

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