三次握手前,服务端的状态从CLOSED
变为LISTEN
, 同时在内部创建了两个队列:半连接队列和全连接队列,即SYN队列和ACCEPT队列。
# 半连接队列
当客户端发送SYN
到服务端,服务端收到以后回复ACK
和SYN
,状态由LISTEN
变为SYN_RCVD
,此时这个连接就被推入了SYN队列,也就是半连接队列。
# 全连接队列
当客户端返回ACK
, 服务端接收后,三次握手完成。这个时候连接等待被具体的应用取走,在被取走之前,它会被推入另外一个 TCP 维护的队列,也就是全连接队列(Accept Queue)。
# SYN Flood 攻击原理
SYN Flood 属于典型的 DoS/DDoS 攻击。其攻击的原理很简单,就是用客户端在短时间内伪造大量不存在的 IP 地址,并向服务端疯狂发送SYN
。对于服务端而言,会产生两个危险的后果:
处理大量的
SYN
包并返回对应ACK
, 势必有大量连接处于SYN_RCVD
状态,从而占满整个半连接队列,无法处理正常的请求。由于是不存在的 IP,服务端长时间收不到客户端的
ACK
,会导致服务端不断重发数据,直到耗尽服务端的资源。
# 如何应对 SYN Flood 攻击?
- 增加 SYN 连接,也就是增加半连接队列的容量。
- 减少 SYN + ACK 重试次数,避免大量的超时重发。
- 利用 SYN Cookie 技术,在服务端接收到
SYN
后不立即分配连接资源,而是根据这个SYN
计算出一个Cookie,连同第二次握手回复给客户端,在客户端回复ACK
的时候带上这个Cookie
值,服务端验证 Cookie 合法之后才分配连接资源。