如何应对大量的syn
对于如何应对 syn-flood。随便查查大家都会告诉你,调大 tcp_max_syn_backlog 这个参数、开启tcp_syncookies即可。当我们这么操作之后确实会发现可以挡住了比较大的syn flood。
那我就要给你泼泼冷水了,仅调解这个参数并不一定能解决你的问题。
# 半连接队列长度net.ipv4.tcp_max_syn_backlog=128# 是否打开tcp syncookiesnet.ipv4.tcp_syncookies=1
实验
搭建如下测试环境
Linux xxxxx 4.18.0-147.8.1.el8_1.x86_64 #1 SMP Thu Apr 9 13:49:54 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
发起syn flood之前,nginx接口测试如下。
最开始我们把 nginx 的 backlog 调小一点,仅设置为16.
tcp_max_syn_backlog=256net.ipv4.tcp_syncookies=0
nginx conf
http { server { listen 28090 backlog=16; # backlog 全连接队列长度 location = /cent { echo "ok"; } }}
查看服务端syn_rec状态的个数,发现并没有达到 256 这个限制。而是稳定在 backlog 16 这个数字上。这个与我们的预期的 256 这个数值对不上。问题出在哪里了呢?
nginx 的服务已经非常慢了。用了1分多才返回了结果。
我们调整系统参数,打开syncookies。看一下有没有什么帮助。
net.ipv4.tcp_syncookies=1
nginx的返回速度已经由 1分多钟降低到1秒多了。而syn_rec 并没有改变。
修改 nginx conf
http { server { listen 28090 backlog=1024; # backlog 全连接队列长度 location = /cent { echo "ok"; } }}
发现 syn_rec 上升到接近 1024了。
nginx 接口的响应时间也降低了一个数量级。
目标机器上的CPU都处在内核态。说明都在处理TCP/IP内核协议栈上的工作。入网卡数据量 15819.7KB/29998.3pack ≈ 0.052KB 刚好等于一个TCP + IP包头的大小。
总结
经过上面的实验
tcp_max_syn_backlog 并不能完全生效
backlog 有明显的效果
tcp_syncookies 也有较好的效果
这个似乎跟网上说的不太一样,问题到底出在哪里了?这tcp_max_syn_backlog 这个参数也是有效果的,只不过内核经过升级之后半连接队列长度也要参考backlog而设定。具体可参考 https://lxr.missinglinkelectronics.com/linux/net/core/ 这里有内核网络相关的代码
本文限于篇幅就不做深入探讨。如果读者喜欢可以与我私下交流。
syn flood 就真的可以由上面几个参数化解么?非也。Dos、DDos攻击向来是各个网站难以解决的难题。我也就这一些经验给出一些解决方案。
使用防火墙,拦截或限制热门IP.(对于DDos无效)
开启 tcpcookies.(流量低时有效,但是也容易造成 tcp ack 攻击,造成目标机器的拒绝服务)
购买专业的流量清洗服务。IDC供应商、云服务商、CDN厂商、企业安全公司均提供类似服务。(可解决大流量问题)
以上这些方案都是治标不治本的方法,DDos 应该是每个网站都应该时刻防范的一种攻击。