文章目录
1.什么是 SYN Flood 攻击?
SYN Flood 是互联网上最原始、最经典的 DDoS(Distributed Denial of Service)攻击之一。
SYN 报文指的是 TCP 协议中的 Synchronize 报文,是 TCP 三次握手过程中的首个报文。让我们先来了解一个正常的 TCP 三次握手过程。
TCP 建立连接需要三次握手,假设攻击者短时间伪造不同 IP 地址的 SYN 报文,服务端每接收到一个 SYN 报文,就进 SYN-RECV 状态。当服务端发送出去的 ACK + SYN 报文,无法得到未知 IP 主机的 ACK 应答,久而久之就会占满服务端的半连接队列,使得服务端不能为正常用户服务。
这就是 SYN Flood 攻击。
2.半连接与全连接队列
什么是 TCP 半连接和全连接队列?
TCP 三次握手时,Linux 内核会维护两个队列:
- 半连接队列,也称 SYN 队列。
- 全连接队列,也称 Accept 队列。
我们先来看下 Linux 内核的半连接队列与全连接队列是如何工作的?
- 当服务端接收到客户端的 SYN 报文时,会创建一个半连接对象,然后将其加入到内核的「 SYN 队列」。
- 紧接着服务端会发送 SYN + ACK 给客户端,等待客户端回应 ACK 报文。
- 服务端接收到 ACK 报文后,从「 SYN 队列」取出半连接对象,然后创建一个新的连接对象放入到「 Accept 队列」。
- 应用程序通过调用 socket 接口 accpet() 函数,从「 Accept 队列」取出连接对象。
不管是半连接队列还是全连接队列,都有最大长度限制,超过限制时,默认情况都会丢弃报文。
SYN Flood 攻击方式最直接的表现是会把 TCP 半连接队列打满,当 TCP 半连接队列满了,后续再收到 SYN 报文就会丢弃,导致客户端无法和服务端建立连接。
3.如何防范 SYN Flood 攻击?
SYN Flood 的目的是占满服务器的连接数,消耗服务器的系统资源。对于服务器自身来说,最直接的做法就是提高服务能力,比如组建集群,升级硬件。但是这种方式成本巨大,且对于海量的攻击报文来说,并没有太大作用,仅多撑几分钟甚至几秒而已。
防范 SYN Flood 攻击,可以有以下几种方法:
(1)增大半连接队列
增大 TCP 半连接队列,要同时增大下面这三个参数:
增大 /proc/sys/net/ipv4/tcp_max_syn_backlog
增大 listen() 函数中的 backlog
增大 /proc/sys/net/core/somaxconn
要想增大半连接队列,我们得知不能只单纯增大 tcp_max_syn_backlog 的值,还需一同增大 somaxconn 和 backlog,也就是增大全连接队列。否则,只单纯增大 tcp_max_syn_backlog 是无效的。
(2)开启 SYN Cookie
开启 SYN Cookie 可以在不使用半连接队列的情况下建立连接,相当于绕过半连接建立连接。
- 当「SYN 队列」满之后,后续服务端收到 SYN 包,不会丢弃,而是根据算法,计算出一个 Cookie 值。Cookie 包含了一些与连接相关的信息,如初始序列号等,但不会在服务器端保存连接状态。
- 服务端将 Cookie 值放到第二次握手报文的「序列号」里回给客户端。
- 服务端接收到客户端的 ACK 报文时,通过将 ACK 报文减去 1 获取 Cookie,然后根据 Cookie 判断报文的合法性并重建连接,然后将该连接对象放入「Accept 队列」。
- 最后应用程序通过调用 accpet() 函数,从「Accept 队列」取出连接。
可以看到,当开启了 SYN Cookie 了,即使受到 SYN Flood 攻击导致 SYN 队列满时,也能保证后续正常连接能够建立。
net.ipv4.tcp_syncookies 参数主要有以下三个值:
0 值,表示关闭
1 值,表示仅当 SYN 队列放不下时,再启用
2 值,表示无条件开启
那么在应对 SYN 攻击时,只需要设置为 1 即可。
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
(3)减少 SYN+ACK 报文重传次数
当服务端受到 SYN Flood 攻击时,会有大量处于 SYN-RECV 状态的 TCP 连接。处于这个状态的 TCP 会重传 SYN+ACK 报文,当重传次数达到上限后,就会断开连接。
那么针对 SYN Flood 攻击,我们可以减少 SYN+ACK 的重传次数,以加快处于 SYN-REVC 状态的 TCP 连接断开。
SYN+ACK 报文的最大重传次数由 tcp_synack_retries 内核参数决定(默认值是 5 次),比如减少到 2 次:
echo 2 > /proc/sys/net/ipv4/tcp_synack_retries
参考文献
SYN 洪水DDoS 攻击 - Cloudflare
什么是SYN Flood?如何防御SYN Flood? - 华为
4.1 TCP 三次握手与四次挥手面试题 - 小林coding
TCP 半连接队列和全连接队列满了会发生什么?又该如何应对?
SYN cookies - wikipedia
RFC 793 - Transmission Control Protocol (TCP)