前两天在知乎上看到一篇文章: 面试官,不要再问我三次握手和四次挥手, 对于TCP的三次握手机制的细节做了细微的讲解, 其中说到了连接队列这个知识点, 是以前没有了解过的, 特此记录…

更新


[2019-10-28]

  • Initial Release

TCP 三次握手


由于连接队列概念的产生, 依赖于三次握手机制, 所以对于三次握手的知识, 还有有必要复习一下:

  1. Client发送SYN, seq = xServer, 进入SYN_SEND状态
  2. Server发送SYN, ACK, ack = x + 1, seq = yClient, 进入SYN_RCVD状态
  3. Client再次发送ACK, ack = y + 1Server, 双方进入ESTABLISHED状态

TCP 连接队列


TCP内部维护了两个连接队列:

  • 半连接队列
  • 全连接队列

在第一次进行握手的时候, 服务端会将收到的SYN连接请求统一加入到半连接队列, 服务端在第二次握手的时候, 向客户端发送SYN + ACK确认信息包, 如果服务端长时间没有接收到客户端的确认包, 会进行多次重传, 如果重传次数超过最大重传次数, 会将该连接从半连接队列中移除.

同样的, 当双方三次握手完成, 并且都进入ESTABLISHED状态, 此时服务端会将已经建立的连接统一放入全连接队列中

SYN 攻击


从上面的总结可以看到, 当半连接队列已满的时候, 会忽略其他的连接. 那么问题来了:

我是否可以利用这一点来对服务器进行攻击?

答案是肯定的. 恶意攻击者可以在短时间内伪造大量不存在的IP地址, 向目标服务器发起HTTP请求, 此时会发送大量的SYN包, 服务端接收到SYN, 会向这些无效客户端发送SYN + ACK包, 从而导致无限制的进行重传, 半连接队列也会因此而饱满, 导致正常的TCP连接无法建立, 这就是SYN 攻击