admin管理员组

文章数量:1559076

问题背景

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

客户端 --- 防火墙(nat/pat) --- 互联网 --- 防火墙 --- 负载均衡 --- web 服务器

案例取自 wireshark 官方问答论坛


问题分析

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

正常的流

比较简短的交互过程,没有任何异常。

问题流

确实 ,充斥了 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 。

但在随后帧 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/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/s/blog_3fde82520101fmxw.html



感谢阅读,更多技术文章可关注个人公众号:echo reply ,谢谢。

本文标签: 服务器