Wireshark TS | 服务器在三次握手后发送RST ?

问题背景

用户提到在大多数时候,服务器响应就像标题所描述的那样出现断连问题,简化的拓扑如下,

客户端 --- 防火墙(NAT/PAT) --- 互联网 --- 防火墙 --- 负载均衡 --- Web 服务器

案例取自 Wireshark 官方问答论坛


问题分析

来自于某一台 Web 服务器上的数据抓包文件,可能的问题会是什么呢?

正常的流
RST-01
比较简短的交互过程,没有任何异常。

问题流
RST-02
确实 ,充斥了 Bad TCP 和 TCP RST 的着色,而且有一些很特殊的问题,简析如下:

  1. 服务器 SYN/ACK 重传

从流中的前 3 个包(帧 70-72)上来看,其实 TCP 三次握手已经完成了,但是服务器仍然在 1.3s 后重传了 SYN/ACK,很奇怪的重传。因为如果像该用户所说,数据包是在服务器上所抓取的话,那么在明显收到客户端第三个 ACK 的情况下,服务器是否仍然认为三次握手没有完成,所以才进一步进行 SYN/ACK 重传。

基于此现象,按以前的经验,个人认为可能需要在服务器上进一步检查此连接具体的状态,是否 ESTABLISHED 等等,但论坛上的专家提到了一个可能引起此现象的问题 TCP_DEFER_ACCEPT

❤️ 感谢专家解锁数据包新世界 ,在此数据包文件的现象中确实匹配这种情况。

TCP_DEFER_ACCEPT (since Linux 2.4)
Allow a listener to be awakened only when data arrives on the socket. Takes an integer value (seconds), this can bound the maximum number of attempts TCP will make to complete the connection. This option should not be used in code intended to be portable.

如果在 Linux 服务器上开启了此选项,服务器会在接收到最后一个 ACK 之后,并不会进入 ESTABLISHED 状态,而是会忽略掉此 ACK ,保持 SYN_RECV 状态不变,然后接下来等待客户端发送数据。而如果客户端数据没有快速跟随时,由于服务器还处于 SYN_RECV 状态,因此就会在超时后进行 SYN/ACK 重传。

正常时的交互,客户端在约 82ms 时发送了 GET 请求,而发生问题时,客户端在约 1.5s 左右才发起 GET 请求,也是造成上述重传的原因。对于客户端的行为也需要同时在负载均衡前后抓包对比分析才能判断,此处缺失。

  1. 服务器 RST

服务器在收到客户端 GET 请求后,直接 RST 了连接。此处需要检查 TCP 中的 Seq Num、Ack Num 等,关闭 TCP 选项 Relative sequence numbers 后,观察到客户端发送的帧 74 ACK 编号 2106390967 明显与帧 72 或 73 所要求的 2962498563 不一样,且远在 ISN 之外。服务器因此丢弃这个数据包,并发送帧75 RST 。
RST-03
但在随后帧 76 至最后,客户端也有比较奇怪的行为,在收到 RST 之后仍然发送 ACK,这能解释的也可能是 RST 的 Seq Num 不在有效范围内,因此忽略。

在最后客户端 GET 请求不断重传无响应后,发送 FIN/ACK 关闭连接。


问题总结

此案例的现象比较奇怪,在缺少足够数据包支撑的情况下,譬如客户端上、负载均衡前后、防火墙前后等,无法得出导致该问题的最终原因。

PS:仅个人猜测,排除服务器 TCP_DEFER_ACCEPT 带来的现象外,有可能是负载均衡的问题,转换错乱了 ACK Num 。


参考

Why is server (CentOS 6) sending RST after TCP three-way handshake?
https://osqa-ask.wireshark.org/questions/57187/why-is-server-centos-6-sending-rst-after-tcp-three-way-handshake/

linux下tcp选项TCP_DEFER_ACCEPT详解
http://www.pagefault.info/2011/08/28/linux-tcp-option-tcpdeferaccept-detailed.html

TCP_DEFER_ACCEPT的行为和不同的实现方式
http://blog.sina.com.cn/s/blog_3fde82520101fmxw.html



感谢阅读,更多技术文章可关注个人公众号:Echo Reply ,谢谢。
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Wireshark是一款强大的网络协议分析工具,它可以让你深入地查看和解析网络数据包,包括TCP三次握手的过程。在Wireshark中,你可以按照以下步骤来观察TCP三次握手的详细信息: 1. **启动Wireshark**:首先,确保Wireshark已经安装并在运行。通常可以在任务栏或桌面找到它的图标。 2. **设置捕获过滤器**:在Wireshark的顶部菜单栏,选择"过滤器"(Filter),输入`tcp.flags.syn==1 && tcp.flags.ack==0`,这将只显示 SYN 包(第一次握手)和未确认的 SYN-ACK 包(第二次握手)。 3. **开始抓包**:点击开始捕获按钮(通常是黄色的三角形图标),或者使用快捷键F5,Wireshark将开始监听网络并显示数据包。 4. **查找三次握手**:在捕获的包列表中,观察那些发送者地址和接收者地址都不同,且标志(Flags)栏中包含 SYN 和 SYN/ACK 的包。第一次握手是发送方(SYN)给接收方,第二次是接收方回应(SYN/ACK),第三次是发送方确认(ACK)。 5. **查看详细信息**:双击任何一个数据包,你会进入详细的TCP会话视图,这里可以看到源IP、目的IP、源端口、目的端口以及TCP头部的各个字段,如Sequence Number、Acknowledgment Number等,这些都可以帮助你理解三次握手的每个阶段。 6. **时间线和交互模式**:Wireshark的时间线功能可以帮你同步查看数据包的时间关系,这对于理解三次握手的顺序至关重要。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值