TCP 半连接队列和全连接队列满了,怎么破?( 五 )


7、如果 SYN 半连接队列已满,只能丢弃连接吗?并不是这样,开启 syncookies 功能就可以在不使用 SYN 半连接队列的情况下成功建立连接,在前面我们源码分析也可以看到这点,当开启了 syncookies 功能就不会丢弃连接 。
syncookies 是这么做的:服务器根据当前状态计算出一个值,放在己方发出的 SYN+ACK 报文中发出,当客户端返回 ACK 报文时,取出该值验证,如果合法,就认为连接建立成功,如下图所示 。

TCP 半连接队列和全连接队列满了,怎么破?

文章插图
开启 syncookies 功能
syncookies 参数主要有以下三个值:
  • 0 值,表示关闭该功能;
  • 1 值,表示仅当 SYN 半连接队列放不下时,再启用它;
  • 2 值,表示无条件开启功能;
那么在应对 SYN 攻击时,只需要设置为 1 即可:
TCP 半连接队列和全连接队列满了,怎么破?

文章插图
8、如何防御 SYN 攻击?
这里给出几种防御 SYN 攻击的方法:
  • 增大半连接队列;
  • 开启 tcp_syncookies 功能;
  • 减少 SYN+ACK 重传次数 。
(1)方式一:增大半连接队列在前面源码和实验中,得知要想增大半连接队列,我们得知不能只单纯增大 tcp_max_syn_backlog 的值,还需一同增大 somaxconn 和 backlog,也就是增大全连接队列 。否则,只单纯增大 tcp_max_syn_backlog 是无效的 。
增大 tcp_max_syn_backlog 和 somaxconn 的方法是修改 Linux 内核参数:
TCP 半连接队列和全连接队列满了,怎么破?

文章插图
增大 backlog 的方式,每个 Web 服务都不同,比如 Nginx 增大 backlog 的方法如下:
TCP 半连接队列和全连接队列满了,怎么破?

文章插图
最后,改变了如上这些参数后,要重启 Nginx 服务,因为半连接队列和全连接队列都是在 listen 初始化的 。
(2)方式二:开启 tcp_syncookies 功能
开启 tcp_syncookies 功能的方式也很简单,修改 Linux 内核参数:
(3)方式三:减少 SYN+ACK 重传次数
当服务端受到 SYN 攻击时,就会有大量处于 SYN_REVC 状态的 TCP 连接,处于这个状态的 TCP 会重传 SYN+ACK ,当重传超过次数达到上限后,就会断开连接 。
那么针对 SYN 攻击的场景,我们可以减少 SYN+ACK 的重传次数,以加快处于 SYN_REVC 状态的 TCP 连接断开 。
TCP 半连接队列和全连接队列满了,怎么破?

文章插图
参考:
[1] 系统性能调优必知必会.陶辉.极客时间.
[2] https://blog.cloudflare.com/syn-packet-handling-in-the-wild

【TCP 半连接队列和全连接队列满了,怎么破?】


推荐阅读