Linux客户端无法连接,服务器和TCP Windows Size / Timestamps问题

我们有一个问题,许多客户端(所有Linux Ubuntu)有时无法通过SSH连接到远程服务器。 如果发生问题,Windows客户端没有这个问题,可以连接就好了。

我发现这个问题有一个类似的问题: 为什么服务器不会发送SYN / ACK数据包来响应SYN数据包

禁用服务器上的TCP时间戳确实可以解决问题,但是我想知道真正的问题是什么。 我不明白为什么这会导致任何问题,绝对不是在build立连接时。

使用Wireshark时,我发现Windows客户端使用8192的窗口大小,而Linux客户端使用29200的窗口大小.Windows客户端接收SYN_ACK,而Linux客户端不接收。 是否有可能这个较高的初始窗口大小负责不发送服务器的SYN_ACK? 我不能拿出一个明智的解释,为什么它可能会导致给定的问题,但由于它是唯一的(在我看来)的差异,它看起来是这样的。 我错过了什么吗?

***编辑经过更多的search,思考和一些巫术魔法,我想我可能会拿出一个合理的解释。 确实需要一些假设和具体条件,但我相信在这种特殊情况下这些可能是可能的。

这两个用户都在同一个NAT设备后面(在我们的例子中是一个Fortigate防火墙)。 这个防火墙将把它的外部接口/ IP上的本地端口分配给每个NAT连接。 如果该端口已经被其他用户使用,则被跳过。 如果连接closures,端口将被释放并返回到NAT池。 如果该端口被分配给另一个用户,但服务器仍然有连接的某个logging(TIME_WAIT,最终的FIN / ACK没有收到),并且数据包的时间戳低于以前的连接数据包,默默地被偷听。

好的,如果在那里有很多,但是… – 这两个用户正在同一个网站上开发,所以他们将与同一个远程服务器进行大量连接 – 防火墙(Fortigate)显然保留了一个顺序计数器每个源IP / destinationIP / destinationPort的NAT端口。 如果两个用户的计数器接近彼此,考虑到两个目的地IP作为端口是相同的,那么与该服务器的两个连接发生这种“冲突”的可能性并非不可能。 这就可以解释为什么这个问题只是零星地发生。

这个理论唯一的问题是,我无法在服务器端find任何证据。 在TIME_WAIT或类似的东西中没有任何连接,我假设一旦它们从netstat输出中消失,服务器就已经忘记了它们。

我相信最初的窗口大小在这个方面并不起作用,所以我正在打击这个名单中的一个。

所以,如果Windows客户端没有问题,我猜测他们没有要求TCP时间戳,而是Linux时间戳。 您可以通过再次查看这两个示例中的Wireshark捕获来validation这一点。

要开始排除时间戳问题的根本原因,首先要确保客户端和服务器同步到NTP服务器。 如果他们只有一个自由运行的时钟,那很可能是问题的原因。 例如:

# ntpq -p remote refid st t when poll reach delay offset jitter ======================================================================== *utcnist2.colora .ACTS. 1 u 92 1024 377 50.242 2.041 1.847 +time-c.timefreq .ACTS. 1 u 623 1024 377 55.413 -1.781 0.418 

确保至less有一个在前面有星号。 这意味着它同步。 看到TCP会话在一开始就停滞不前了。 人们会期望它在几个包与时间戳值已被交换后停顿。 更确切地说,当一个数据包的时间戳值看起来是从前一个数据包的时间倒退的时候。