三次握手大家都耳熟能详了:

  • 客户端发起握手信号SYN(synchronous),然后进入 SYN_SEND 状态,等待服务端响应
  • 服务端收到信号,返回SYN+ACK(Synchronization-Acknowledgement)信号,声明做好接收消息的准备,并要求客户端也要做好接收消息的准备,然后进入SYN_RCVD状态,也就是半开状态,服务端会持续等待客户端再次发起的确认信息,这个等待时间很长,能达到分钟级别。(注意:这里是攻击的核心点)
  • 客户端收到消息后,再次发送ACK(Acknowledgement)消息给服务端,声明做好了接收数据的准备
  • 连接成功

为什么三次?

三次是满足一个完整、妥善会话的最小逻辑单元,比如:

  • A:能不能借我500块钱?
  • B:可以,转账500。
  • A:好的,收到!

中间任何一步的失败都会造成会话的不完整,要么A不能确认B是否转账,要么B不能确认A是否收到汇款。

SYN Flood攻击

如上所述,B转账后会处于半开放状态,要持续等待两分钟,直到收到A的确认收到汇款消息为止。等待是焦急的,劳神的,是耗费脑细胞的。当成千上万的虚假客户端只发送握手信号SYN,收到服务端信号后,并不再次发起确认信号时,服务端则会占用大量的系统内存来维持等待这些半开放的连接,耗尽系统资源,导致正常的握手请求得不到响应,这就是SYN Flood攻击的原理。

对策

  • 缩短SYN Timeout时间
  • 提高半开状态数量
  • SYN cookie:

    服务端收到握手信号SYN,在返回SYN+ACK时对ACK进行加密,加密信息包含原地址、端口、目标地址,总之能标识是谁发来的信息,然后不进入半开放状态,直接释放所以状态,这样省去了维持等待所耗费的系统资源,当收到客户端字再次发起的ACK信号时,计算是否为上个SYN+ACK消息的返回,如果是则直接进入连接状态。

  • Firewalls and Proxies:

    用防火墙作为客户端和服务端的中间代理,客户端先与防火墙建立三次握手,只有在握手成功后,防火墙再与服务端建立握手,然后防火墙在中间代理数据传输。此时服务端收到的都是正常握手请求。

参考:https://www.wikiwand.com/en/SYN_flood#