![服务器延迟回复 TCP SYN 数据包](https://linux22.com/image/119054/%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%BB%B6%E8%BF%9F%E5%9B%9E%E5%A4%8D%20TCP%20SYN%20%E6%95%B0%E6%8D%AE%E5%8C%85.png)
什么时候工作站连接到 HTTPS 服务器服务器,那么通常服务器发送 SYN+ACK 数据包,延迟约 60 秒。从服务器抓包可以看到如下:
10:15:21.310878 00:19:e2:9e:df:f0 > 00:11:25:8c:7a:1a, ethertype IPv4 (0x0800), length 74: 10.10.10.160.38256 > 10.10.10.16.443: S 3411497795:3411497795(0) win 29200 <mss 1460,sackOK,timestamp 2503046494 0,nop,wscale 7>
10:15:23.102826 00:19:e2:9e:df:f0 > 00:11:25:8c:7a:1a, ethertype IPv4 (0x0800), length 74: 10.10.10.160.38244 > 10.10.10.16.443: S 3008273869:3008273869(0) win 29200 <mss 1460,sackOK,timestamp 2503046942 0,nop,wscale 7>
10:15:23.326801 00:19:e2:9e:df:f0 > 00:11:25:8c:7a:1a, ethertype IPv4 (0x0800), length 74: 10.10.10.160.38256 > 10.10.10.16.443: S 3411497795:3411497795(0) win 29200 <mss 1460,sackOK,timestamp 2503046998 0,nop,wscale 7>
10:15:27.230802 00:19:e2:9e:df:f0 > 00:11:25:8c:7a:1a, ethertype IPv4 (0x0800), length 74: 10.10.10.160.38244 > 10.10.10.16.443: S 3008273869:3008273869(0) win 29200 <mss 1460,sackOK,timestamp 2503047974 0,nop,wscale 7>
10:15:27.486804 00:19:e2:9e:df:f0 > 00:11:25:8c:7a:1a, ethertype IPv4 (0x0800), length 74: 10.10.10.160.38256 > 10.10.10.16.443: S 3411497795:3411497795(0) win 29200 <mss 1460,sackOK,timestamp 2503048038 0,nop,wscale 7>
10:15:35.422853 00:19:e2:9e:df:f0 > 00:11:25:8c:7a:1a, ethertype IPv4 (0x0800), length 74: 10.10.10.160.38244 > 10.10.10.16.443: S 3008273869:3008273869(0) win 29200 <mss 1460,sackOK,timestamp 2503050022 0,nop,wscale 7>
10:15:35.678797 00:19:e2:9e:df:f0 > 00:11:25:8c:7a:1a, ethertype IPv4 (0x0800), length 74: 10.10.10.160.38256 > 10.10.10.16.443: S 3411497795:3411497795(0) win 29200 <mss 1460,sackOK,timestamp 2503050086 0,nop,wscale 7>
10:15:51.550815 00:19:e2:9e:df:f0 > 00:11:25:8c:7a:1a, ethertype IPv4 (0x0800), length 74: 10.10.10.160.38244 > 10.10.10.16.443: S 3008273869:3008273869(0) win 29200 <mss 1460,sackOK,timestamp 2503054054 0,nop,wscale 7>
10:15:51.806784 00:19:e2:9e:df:f0 > 00:11:25:8c:7a:1a, ethertype IPv4 (0x0800), length 74: 10.10.10.160.38256 > 10.10.10.16.443: S 3411497795:3411497795(0) win 29200 <mss 1460,sackOK,timestamp 2503054118 0,nop,wscale 7>
10:16:24.062769 00:19:e2:9e:df:f0 > 00:11:25:8c:7a:1a, ethertype IPv4 (0x0800), length 74: 10.10.10.160.38256 > 10.10.10.16.443: S 3411497795:3411497795(0) win 29200 <mss 1460,sackOK,timestamp 2503062182 0,nop,wscale 7>
10:16:24.062832 00:11:25:8c:7a:1a > 1c:87:2c:5a:43:e2, ethertype IPv4 (0x0800), length 74: 10.10.10.16.443 > 10.10.10.160.38256: S 561747608:561747608(0) ack 3411497796 win 5792 <mss 1460,sackOK,timestamp 3558683637 2503062182,nop,wscale 2>
10:16:24.062843 00:19:e2:9e:df:f0 > 00:11:25:8c:7a:1a, ethertype IPv4 (0x0800), length 74: 10.10.10.160.38244 > 10.10.10.16.443: S 3008273869:3008273869(0) win 29200 <mss 1460,sackOK,timestamp 2503062182 0,nop,wscale 7>
10:16:24.062860 00:11:25:8c:7a:1a > 1c:87:2c:5a:43:e2, ethertype IPv4 (0x0800), length 74: 10.10.10.16.443 > 10.10.10.160.38244: S 562554685:562554685(0) ack 3008273870 win 5792 <mss 1460,sackOK,timestamp 3558683637 2503062182,nop,wscale 2>
10:16:24.063075 00:19:e2:9e:df:f0 > 00:11:25:8c:7a:1a, ethertype IPv4 (0x0800), length 66: 10.10.10.160.38256 > 10.10.10.16.443: . ack 1 win 229 <nop,nop,timestamp 2503062182 3558683637>
10:16:24.063116 00:19:e2:9e:df:f0 > 00:11:25:8c:7a:1a, ethertype IPv4 (0x0800), length 66: 10.10.10.160.38244 > 10.10.10.16.443: . ack 1 win 229 <nop,nop,timestamp 2503062182 3558683637>
为了排除任何与 ARP 相关的问题,我安装了静态 ARP 条目工作站在服务器:
# ip neigh show 10.10.10.160
10.10.10.160 dev eth0 lladdr 1c:87:2c:5a:43:e2 PERMANENT
#
最后但并非最不重要的一点是,我始终能够从 10.10.10.16 ping 通 10.10.10.160。例如我while :; do ping -c 1 -I 10.10.10.16 10.10.10.160 &>/dev/null || date; sleep 2; done
跑过服务器一整天,没有一个 ping 失败。
最后,当我比较客户端发送的 TCP SYN 数据包时10:15:51.806784
(没有收到来自服务器)与10:16:24.062769
(从服务器)在 Wireshark 中,那么除了校验和之外,它们是相同的。
另外,服务器侧面防火墙的配置方式是第一条规则输入链是记录来自 10.10.10.160( iptables -I INPUT -s 10.10.10.160 -d 10.10.10.16 -p tcp --syn --dport 443 -j LOG
) 的 TCP SYN 数据包,第二条规则是接受来自 10.10.10.160 的所有流量。例如,以下行被记录到内核环形缓冲区:
IN=eth0 OUT= MAC=00:11:25:8c:7a:1a:00:19:e2:9e:df:f0:08:00 SRC=10.10.10.160 DST=10.10.10.16 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=65477 DF PROTO=TCP SPT=40066 DPT=443 WINDOW=29200 RES=0x00 SYN URGP=0
正如我已经说过的,它们在下一条规则中被接受。这应该排除任何tc
/netfilter
相关问题。
其他客户端(例如 10.10.10.170)工作正常。
什么会导致这种行为?
答案1
我在这里看到一个主要问题:来自服务器的回复与发送到它的数据包所经过的路径不同。
您的工作站使用路由器 10.10.10.190 通过其 10.10.10.16/32 地址(/32?您的绘图还显示 /28)来访问服务器,而不是使用与 WS 位于同一 LAN 网段的 10.10.10.148 地址。
但是,从服务器到 WS 的 TCP 数据包不使用路由器,因为服务器可以直接到达 WS。
为什么这有关系?
结果是您的路由器看不到来自服务器的回复,并且对连接状态有错误的认识(尽管服务器回复了 SYN+ACK,但从路由器的角度来看,连接状态仍处于初始 SYN)。
与当今大多数路由器一样,它可能会阻止从 WS 到服务器的任何后续 TCP 数据包,直到它看到来自服务器的 SYN+ACK(这种情况不会发生)。
因此,您的实际问题可能不是您的服务器在发送 SYN+ACK 之前等待 60 秒,而是您的路由器在初始 SYN 之后阻止了从 WS 到服务器的 TCP 流量。
那么为什么会出现流量转储呢?
如果我的理论是正确的,那么您在问题中发布的流量转储是具有欺骗性的,因为我们没有完整的转储:
- 服务器不会回复 SYN 请求,因为它已经回复了第一个请求,并且这些请求被视为重复
- 您在 10:16:24.062769 和 10:16:24.062860 看到的可能是服务器在一定延迟后再次发送 SYN+ACK 回复,而没有从 WS 接收到任何内容
如何解决这个问题?
您有多种选择:
- 通过 10.10.10.148 IP 地址直接到达服务器(实际上不是修复)
- 从服务器中删除 10.10.10.148 IP 地址(我猜这不是一个选项)
- 禁用路由器上的防火墙连接跟踪(我想这不是一个选项,而且无论如何也不理想)
- 将路由器的 MAC 地址 00:19:e2:9e:df:f0 放入服务器的 10.10.10.160 的 ARP 表中(恕我直言,这是一个丑陋的黑客行为,当直接通过其 10.10.10.148 IP 到达服务器时,您最终会遇到另一个类似的问题地址,因为 SYN 数据包不会使用路由器,但服务器的回复会使用)
- 使用基于源的路由(策略路由)告诉服务器,当传出数据包的源地址为 10.10.10.16 时,无论目标地址是什么,都使用路由器
当然,给出了实际上不是真实选项的选项,以便您可以实验和验证我的理论。基于源的路由是您应该做的。