服务器在几次正常连接之后停止发送SYN ACK

我有一个NAT后面的几千台设备与两台服务器通话。 每个设备都在本地路由器(思考调制解调器/路由器)的后面,在这个路由器上,这些路由器将NAT转换到拥有数千个这些设备的专用networking,并且在这个专用networking的网关上,来自这些设备的TCP会话获得NAT过载/dynamic地PAT到单个全局IP地址上的端口。 这意味着,设备1将与服务器通话,连接将来自global_ip_of_the_router:port_number_1。 一旦设备1完成通话,并且NAT关联被移除,则当设备2想要与同一服务器交谈时,远程路由器可以向设备2分配相同的全局端口,即服务器可以看到来自global_ip_of_the_router:port_number_1的新的TCP连接

这些设备本身启动一个TCP连接,做一个小文件的HTTP POST,断开TCP连接,为下一个文件build立一个新的连接等。这适用于〜20个文件,之后在SYN上,设备从服务器取回没有SYN的ACK。 ACK具有与SYN上的序列号完全不同的ACK号。 设备立即发送一个RST,在1秒后退出并从同一个源端口尝试一个SYN,仍然只是ACK,所以在放弃之前它会保持退后3,6,12,24,48秒。 在设备的RST上,似乎是使用ACK中的SEQ,试图closures旧的连接(从服务器的angular度来看)

远程主机是AWS ELB。 以下是我们所做的假设和我们所尝试的:

远程路由器必须处理TCP会话死亡,并且超时NAT,并且比目标服务器(ELB)更快地重新使用全局端口。 这可能会导致ELB处于TCP_TIME_WAIT状态,这就是为什么它使用ACK来响应SYN。 由于ELB的TCP TIME WAIT不是已知的,假设它是Linux内核默认的标准60秒,它将匹配远程路由器上的FIN / RST后NAT超时。 不过,我们在路由器上将其更改为70秒,以避免任何竞争条件。 这并没有使问题消失。 我们认为,如果远程路由器更快地杀死了NAT,则会在设备进行退避时为SYN重试分配新的NAT。 如果dest服务器上的问题与远程路由器上使用的全局端口号绑定,那么看到新的SYN来自路由器IP上的新的全局端口应该会导致它离开奇怪的状态。 现在,虽然我们可以看到这个工作,但是看起来新分配的NAT端口在服务器上也遇到了同样的问题,它返回了一个假ACK,但是又有一个不同的ACK号。 另一种假设是,这只是在SYN上的SEQ比在远程路由器上使用相同的全局端口的最后一次连接上的序列号低时发生的。 即伪ACK上的ACK编号将总是高于SYN上的SEQ。 (我们将Wireshark切换到绝对序列号来查看)。 然而事实certificate,我们看到SYN SEQ比假ACK上的ACK号更多的情况。 所以这个理论走到了一边。 我们现在对这里可能发生的事情感到不知所措。 我们的怀疑是在新连接获得与旧连接相同的全局端口,但是,如果是这样的话,(a)通过使路由器保持更长的NAT,应该阻止它,并且(b)通过使路由器先closuresNAT,然后为同一连接尝试分配一个不同的NAT,这应该避开这个问题。

在这里理解行为的任何帮助将非常非常感激。

Wireshark跟踪: http : //www.filedropper.com/traffictrace-anonymizedandpacketswithpayloadremoved

请注意,跟踪已被匿名(IP和MAC被replace),所有带有有效载荷的TCP数据包已被删除。 问题的第一个实例始于分组129,第二实例分组382,然后是463,699,816,1120,1278,1323等

查看跟踪中最后一个实例,这是我们缩短了路由器上NAT后FIN / RST超时的地方。 你可以看到,前四次,ACK的AKC号码是2899295595.但是在第5号,ACK是3102149417.在第6号,它是4158039292.这是因为在这里,路由器被设置为超时的NAT所以这些尝试来自路由器上不同的全局端口。 如果问题与全局端口和以前使用全局端口的连接有关,则应该停止它。 但问题依然存在,这导致我们认为这不是源端口相关的,而是由TCP SYN本身产生的。


昨天,我们尝试将NAT后FIN / RST定时器设置为300秒,这些断开的连接就消失了。 我的猜测是我们把端口重用延迟到了ELB丢弃了以前连接的某个点。 我们想知道,如果ELB上的空闲超时设置为295秒,那么TCP_TIME_WAIT的值也是相同的,即使在FIN之后,连接也是有效的。 虽然如果是这样的话,我们应该看到更多的连接失败,因为路由器上的端口复用非常猖獗。 很高兴知道到底发生了什么。