面经上看到了半连接攻击的问题,跟自己想的差不多,这里简单总结一下。
半连接攻击
在正常情况下,客户端连接服务端需要通过三次握手,首先客户端构造一个SYN连接数据包发送至服务端,自身进入SYN_SEND状态,当服务端收到客户端的SYN包之后,为其分配内存核心内存,并将其放置在半连接队列中,服务端接收客户SYN包并会向客户端发送一个SYN包和ACK包,此刻服务端进入SYN_RECV态。客户端收到包之后,再次向服务端发送ACK确认包。至此连接建立完成,双方都进入ESTABLSHEDZ状态。半连接就是通过不断地构造客户端的SYN连接数据包发向服务端,等到服务端的半连接队列满的时候,后续的正常用户的连接请求将会被丢弃,从而无法连接到服务端。此为半连接攻击方式。
当然,发送请求的ip可能是不存在的,所以服务端会不停的超时重传,极其的消耗资源
半连接队列
当客户端发送SYN到服务端,服务端收到以后回复ACK和SYN,状态由LISTEN变为SYN_RCVD,此时这个连接就被推入了SYN队列,也就是半连接队列。
(全连接队列:连接完全建立之后,连接放到全连接队列中,等待应用来取)
如何解决?
- 扩大半连接队列的大小(一种思路,但不可取)
- 减少 SYN + ACK 重试次数,避免大量的超时重发
- 利用 SYN Cookie技术,在服务端接收到SYN后不立即分配连接资源,而是根据这个SYN计算出一个Cookie,连同第二次握手回复给客户端,在客户端回复ACK的时候带上这个Cookie值,服务端验证Cookie 合法之后才分配连接资源。
- syn cache:系统在收到一个SYN报文时,在一个专用HASH表中保存这种半连接信息,直到收到正确的回应ACK报文再分配TCB。这个开销远小于TCB的开销。当然还需要保存序列号。
全连接攻击
全连接攻击是通过消费服务端进程数和连接数,只连接而不进行发送数据的一种攻击方式。当客户端连接到服务端,仅仅只是连接,此时服务端会为每一个连接创建一个进程来处理客户端发送的数据。但是客户端只是连接而不发送数据,此时服务端会一直阻塞在recv或者read的状态,如此一来,多个连接,服务端的每个连接都是出于阻塞状态从而导致服务端的崩溃。
简而言之(占着茅房不那啥)
参考资料
tcp连接之半连接攻击和全连接攻击总结
半连接队列、全连接队列、SYN Flood 攻击、如何应对SYN Food攻击、半连接队列和 SYN Flood 攻击的关系