我在网络 A 上运行了一些主机,它们向网络 B 上位于 Internet 某处的服务器(不属于我)发出请求。不幸的是,许多请求都被破坏了。如果我通过未加密的 HTTP 发出请求,我会收到奇怪的错误,提示请求已损坏。如果我通过 HTTPS 发出请求,我会收到 SSL 级错误。我可以通过运行以下命令重现该问题:
sh -e -c 'while true; do curl $SERVER > /dev/null; sleep 1; done'
通常在 20 个请求内,curl 就会失败,并出现“未知 SSL 协议错误”或“tlsv1 警报解密错误”等错误。我可以在网络 A 中的多台主机上重现此情况,访问网络 B 上的多台服务器。但我无法从网络 A 复制到其他服务器,也无法从其他主机复制到网络 B。在这些情况下,循环会永远运行,没有任何错误。
因此很明显我的 TCP 流在 A 和 B 之间被破坏了。顺便说一句,这种情况已经持续了 3 天多了。
第一个问题:这怎么可能发生?TCP 具有数据包级校验和,通过校验和的损坏数据包应该比我看到的少得多。此外,如果我运行网络捕获,我看不到很多重新传输(根据 wireshark 的 tcp.analysis.retransmit 过滤器),如果数据包被损坏并且未通过 TCP 校验和,这是可以预料到的。我猜某些路由器一定在进行更高级别的数据损坏(NAT?透明代理?)并损坏数据但修复校验和?
第二个问题:有什么工具可以用来隔离问题吗?我找不到。如果我知道网络拓扑,并且可以找到 A 和 B 之间每一跳后面的 HTTPS 服务器,我就可以对它们进行测试。但我不知道。还有什么其他测试可以显示网络损坏?
我已经联系了网络 A 和网络 B 的所有者,但他们迄今为止还没有提供任何帮助。
更新:如果有人提出路径上可能有哪种有问题的设备,除了联系所有者之外,还有其他方法可以检测到吗?
答案1
首先,看看你是否可以使用 ping 而不是 TCP 来复制数据损坏,这将很有用。Ping 使用 ICMP 回显,发送已知负载(如果需要,你甚至可以指定),并在返回时报告负载损坏的情况。至少,这是手册页告诉我。
您可能希望使用较长的数据包大小(可能是 1400 字节左右),并查看是否可以指定较低的间隔,例如 0.1 秒,以便您可以在合理的时间内重现错误。这些设置将产生大约 15 kB/s 的往返服务器流量。(1400 字节/0.1 秒 + 开销)
那么为什么要使用 ping 而不是 TCP 连接呢?因为,您可能可以 ping 服务器和客户端之间的路径中的大多数主机,因此您可以仅测试部分路径。
首先测试完整路径(一直到您的服务器,以确定测试是否重现了您的问题)。有了跟踪路由后,您就可以只测试部分路径。您进行的每次测试都可以将您的搜索空间一分为二,经过几次测试后,您将能够找到导致问题的跳转。
警告:如果损坏发生在测试机器的返回路径上而不是前向路径上,则此方法不会按您预期的方式工作。Traceroute 只能告诉您数据包所走的路线到服务器,而不是数据包返回所采用的路径,并且这些路径不一定相同。不过,这应该足以让你到达某个地方。
祝你好运!
答案2
有没有人使用过 LAN/WAN 加速器?这些硬件有时会出问题,必须重新启动,并且可能是造成损坏和性能问题的根源。
答案3
网络中是否存在不稳定的 IDS/IPS/代理,导致数据包损坏仅有的到/从其他网络?这可以解释为什么它不能从不同的主机复制。