来自该网络的所有连接都卡在 SYN_RECV 状态,来自我家或手机的连接正确建立

Yuj*_*ita 6 networking debugging tcp apache-2.2

我的服务器(一个 linode VPS)昨天突然开始在每次请求时超时。

我在网络方面非常缺乏经验,很想学习调试这些连接问题的过程。

让我感到困惑的是,昨天,有些人(我的手机、我在家、家里的朋友)可以一直访问该站点,我看到netstat已经建立了连接。我禁用了防火墙并将 iptables 设置为接受所有连接,以排除将我们的 IP 列入黑名单的任何奇怪的自动规则。我不确定它是否相关,但是来自本地网络的 traceroute 超时 - 来自外部某些机器的 traceroute 找到了我的服务器。

通过与运行正常的开发服务器上的设置进行比较,我确认了各种设置是正确的。

以下文件与我的开发环境匹配(除了它们各自的 ip 地址):

/etc/hosts 
/etc/hosts.allow
/etc/hosts.deny
/etc/networking/interfaces 
ifconfig
Run Code Online (Sandbox Code Playgroud)

Apache 正在侦听端口 80,设置看起来与我正在运行的服务器完全相同。

# server that doesn't work:
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      22008/apache2
tcp        0      0 69.164.201.172:80       71.56.137.10:57487      SYN_RECV    -

# server that does work
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      3334/apache2
tcp        0      0 72.14.189.46:80         71.56.137.10:57490      ESTABLISHED 20931/apache2
Run Code Online (Sandbox Code Playgroud)

我的理解尝试

每次加载页面时,都会netstat -an | grep :80显示处于 SYN_RECV 状态的所有连接。

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
tcp        0      0 69.164.201.172:80       71.56.137.10:56657      SYN_RECV
tcp        0      0 69.164.201.172:80       71.56.137.10:56669      SYN_RECV
tcp        0      0 69.164.201.172:80       71.56.137.10:56671      SYN_RECV
Run Code Online (Sandbox Code Playgroud)

所以这SYN_RECV意味着服务器正在等待ACK从客户端发回。
如何调试是否正在发回 ACK?如何调试此通信失败的地方?

这是我尝试加载一次页面时 tcpdump 的样子。

在下面的粘贴中,我的服务器不断向客户端发送数据包而没有得到响应。

这是什么意思?客户端没有得到响应?或者也许我正在服务器中的某个地方吞下响应?我怎么知道进一步缩小罪魁祸首的范围?

tcpdump -i eth0 -n -tttt port 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
2011-05-25 20:12:54.627417 IP 71.56.137.10.57160 > 69.164.201.172.80: Flags [S], seq 382527960, win 8192, options [mss 1460,nop,wscale 2,nop,nop,sackOK], length 0
2011-05-25 20:12:54.627512 IP 69.164.201.172.80 > 71.56.137.10.57160: Flags [S.], seq 1330600505, ack 382527961, win 14600, options [mss 1460,nop,nop,sackOK,nop,wscale 6], length 0
2011-05-25 20:12:54.814463 IP 69.164.201.172.80 > 71.56.137.10.57157: Flags [S.], seq 604630211, ack 496040070, win 14600, options [mss 1460,nop,nop,sackOK,nop,wscale 6], length 0
2011-05-25 20:12:55.214482 IP 69.164.201.172.80 > 71.56.137.10.57158: Flags [S.], seq 998358186, ack 2224730755, win 14600, options [mss 1460,nop,nop,sackOK,nop,wscale 6], length 0
2011-05-25 20:12:57.624737 IP 71.56.137.10.57160 > 69.164.201.172.80: Flags [S], seq 382527960, win 8192, options [mss 1460,nop,wscale 2,nop,nop,sackOK], length 0
2011-05-25 20:12:57.624793 IP 69.164.201.172.80 > 71.56.137.10.57160: Flags [S.], seq 1330600505, ack 382527961, win 14600, options [mss 1460,nop,nop,sackOK,nop,wscale 6], length 0
2011-05-25 20:12:59.014477 IP 69.164.201.172.80 > 71.56.137.10.57160: Flags [S.], seq 1330600505, ack 382527961, win 14600, options [mss 1460,nop,nop,sackOK,nop,wscale 6], length 0
2011-05-25 20:13:03.618790 IP 71.56.137.10.57160 > 69.164.201.172.80: Flags [S], seq 382527960, win 8192, options [mss 1460,nop,nop,sackOK], length 0
2011-05-25 20:13:03.618866 IP 69.164.201.172.80 > 71.56.137.10.57160: Flags [S.], seq 1330600505, ack 382527961, win 14600, options [mss 1460,nop,nop,sackOK,nop,wscale 6], length 0
2011-05-25 20:13:05.014514 IP 69.164.201.172.80 > 71.56.137.10.57160: Flags [S.], seq 1330600505, ack 382527961, win 14600, options [mss 1460,nop,nop,sackOK,nop,wscale 6], length 0
2011-05-25 20:13:17.014504 IP 69.164.201.172.80 > 71.56.137.10.57160: Flags [S.], seq 1330600505, ack 382527961, win 14600, options [mss 1460,nop,nop,sackOK,nop,wscale 6], length 0
Run Code Online (Sandbox Code Playgroud)

功能服务器的 tcpdump

在查看我的功能服务器的 tcpdump 时,我确实看到了服务器和客户端之间的来回和第四次通信。

00:00:00.000000 IP 71.56.137.10.57260 > 72.14.189.46.80: Flags [S], seq 34114118s [mss 1460,nop,wscale 2,nop,nop,sackOK], length 0
00:00:00.000110 IP 72.14.189.46.80 > 71.56.137.10.57260: Flags [S.], seq 2454858 win 14600, options [mss 1460,nop,nop,sackOK,nop,wscale 5], length 0
00:00:00.061827 IP 71.56.137.10.57260 > 72.14.189.46.80: Flags [.], ack 1, win 100:00:00.004292 IP 71.56.137.10.57260 > 72.14.189.46.80: Flags [P.], seq 1:597, ngth 596
00:00:00.000074 IP 72.14.189.46.80 > 71.56.137.10.57260: Flags [.], ack 597, win00:00:00.493990 IP 72.14.189.46.80 > 71.56.137.10.57260: Flags [.], seq 1:2921, ngth 2920
00:00:00.000024 IP 72.14.189.46.80 > 71.56.137.10.57260: Flags [P.], seq 2921:30, length 98
00:00:00.065135 IP 71.56.137.10.57260 > 72.14.189.46.80: Flags [.], ack 3019, wi00:00:00.034766 IP 71.56.137.10.57260 > 72.14.189.46.80: Flags [P.], seq 597:12925, length 699
00:00:00.000035 IP 72.14.189.46.80 > 71.56.137.10.57260: Flags [.], ack 1296, wi00:00:00.000457 IP 72.14.189.46.80 > 71.56.137.10.57260: Flags [P.], seq 3019:328, length 211
00:00:00.019196 IP 71.56.137.10.57262 > 72.14.189.46.80: Flags [S], seq 10674886s [mss 1460,nop,wscale 2,nop,nop,sackOK], length 0
Run Code Online (Sandbox Code Playgroud)

任何建议、解释或评论将不胜感激,这样我就可以更多地了解 TCP,并希望下次我需要调试这样的问题时会更有用。

谢谢!

sys*_*138 7

在这只疲惫的眼睛看来,问题服务器附近似乎存在某种路由问题。数据包沿着一条路径进入,但似乎通过另一条路径离开,并且该路径上有一些有状态的东西并丢弃奇怪的“没有 SYN 的 ACK”数据包。

我曾经遇到过这种情况。最终的情况是服务器的网络掩码错误,因此当来自子网外的流量进入时,它会发出 ARP 请求以获取节点的 MAC 地址。对我来说不幸的是,路由器和我们的负载平衡器都启用了代理 ARP,并且负载平衡器在触发器上比路由器快一点。所以 SYN 数据包通过路由器进入,但试图通过负载平衡器离开子网。由于 LB 没有连接该 ACK 数据包,因此将其丢弃在地板上。

在您的情况下,一些明智的跟踪路由可能会说明网络路径问题。从受影响的服务器,尝试跟踪路由到导致问题的 IP,并从这些相同的 IP 执行相同的操作。如果你得到不同的路径,那可能就是它的位置。