三次握手中的第二次丢包后会发生什么?

概述

如果你在客户端发现一些莫名其妙的 504 响应码,却不知道为什么,那么本文对你可能有帮助。

如果你查看 Nginx 日志发现有时出现 lua tcp socket connect timed out,却不知道为什么,那么本文对你可能有帮助。

如果你发现你的机器向别的机器发送 RST 包,却不知道为什么,那么本文对你可能有帮助。


前段时间在排查一个传输层的问题,通过抓包发现我们的机器(此处可以认为为客户端)向服务端发出了 RST 包。我们的机器为什么会莫名其妙 reset 别人的连接呢?通过进一步排查,发现根本原因在三次握手的第二次丢包了!


这个问题需要同时在客户端与服务端抓包才能发现。如果不方便在双方向抓包,只能抓到单方向包的朋友,可以参考此文中单方向的包,与你的包进行比对,看是否也属于第三次握手中的第二次包丢失的情况。

报文解析

在最后的附录,附上了笔者当时排查用到的双方向报文,按需自行查阅。
如果你是为了调查 RST 问题,下方的原因解析可以先跳过,先看现象对比中的客户端与服务端部分,如果与你的抓包结果相匹配,则可以继续阅读此文。如果不匹配,那说明你遇到问题很可能不是这个,这篇文章可能帮不到你。
如果你是为了增加一些奇怪的知识,请按顺序继续向下阅读。

原因解析

在这里插入图片描述


上图是 TCP 三次握手中的第二次(SYN+ACK)报文丢失进而引发 RST 的完整过程,下面我用文字叙述一遍:

首先,正常的三次握手流程应该是:

  1. 客户端发出 SYN【SYN=1, Seq=x】
  2. 服务端返回 SYN+ACK 【SYN=1, ACK=1, Seq=y, Ack=x+1】
  3. 客户端返回 ACK【ACK=1, Seq=x+1, Ack=y+1】

而第二次握手报文丢失情况的过程是:

  1. 客户端向服务端发出握手报文,请求建立 TCP 连接,即第一次握手【SYN=1, ACK=0, Seq=x】
  2. 服务端向客户端回复 SYN+ACK 包,但是这个包在网络中丢失了
  3. 客户端等啊等,一直等不到服务端的 SYN+ACK,以为自己的 SYN 丢了,触发超时重传机制,向服务端又发了一个【SYN=1, ACK=0, Seq=z】
  4. 服务端也知道自己的 SYN+ACK 丢了,于是又重传了若干次 SYN+ACK。这时服务端突然收到了客户端重传的【SYN=1, ACK=0, Seq=z】。根据 RFC5691 指出:为了减轻通过 SYN 标志位进行的 RST 攻击(Blind Reset Attack Using the SYN Bit)的影响,服务端此时应立即发送一个【ACK=1, Seq=y, Ack=x+1】给客户端,用以重置连接。
  5. 客户端在接收到 【ACK=1, Seq=y, Ack=x+1】后,立即回复【RST=1, Seq=x+1】。此处的 Seq=x+1 表明:这个 RST 是前面那个 ACK:【ACK=1, Seq=y, Ack=x+1】引起的。然后,双方断开连接。


至此,服务端第二次握手的 SYN+ACK 包丢失,最终导致了客户端“莫名其妙”地发出 RST 包。


PS:KleeNet 论文中指出服务端回复 ACK 给客户端是因为服务端忽略了重传报文的 SYN 标志位,并认为这是一个 BUG。而实际上,这并不是一个 BUG,而是 TCP 为了减轻通过 SYN 标志位进行的 RST 攻击(Blind Reset Attack Using the SYN Bit)的影响 ,有意为之的。


PS:我们事后排查,是因为客户端与服务端之间存在防火墙,防火墙的硬件模块故障导致某些 TCP 包被防火墙丢弃,进而引发丢包,进而引发了 TCP 建连失败,进而引发了 Nginx 的 504 问题

现象对比

客户端

如果你是客户端,你发现你的抓包结果有如下几个特征,那么极有可能就是本文所述的情况:

  1. 最开始向服务端发送了一个【SYN=1, Seq=x】
  2. 从来没收到过 SYN+ACK 报文
  3. 存在 SYN 报文的超时重传(TCP Retransmission)
  4. 在发出 RST 报文前突然收到一个 ACK 报文,且 Ack=x+1

服务端

如果你是服务端,你发现你的抓包结果有如下几个特征,那么极有可能就是本文所述的情况:

  1. 最开始收到了客户端发来的【SYN=1, Seq=x】
  2. 存在很多 SYN+ACK 的重传报文(TCP Retransmission)
  3. 在若干个 SYN+ACK 的重传报文之后突然又收到了客户端的 SYN
  4. 在收到了客户端 SYN 后,给客户端返了一个 ACK,且 Ack=x+1

附录

客户端报文

在这里插入图片描述


服务端报文

在这里插入图片描述


参考文献

KleeNet: Discovering insidious interaction bugs in wireless sensor networks
before deployment

RFC5961

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值