HTTP 的 Slow Attack 有着悠久历史的 HTTP DOS 攻击方式,最早大约追溯到 5 年前,按理说早该修复了,但是 Apache 的默认配置中仍然没有添加相关配置,或者他们认为这是 feture 不是 bug,所以至今默认安装的 Apache 中还存在着 Slow Attack 的威胁。
Slow Attack 大致可分为以下几种:
Debian7 x86_64 & Apache 2.2.22
Debian8 x86_64 & Apache 2.4.10
(1) 在 Debian 中通过 apt 安装默认的 Apache
apt-get -y install apache2
(2) 在默认的 DocumentRoot 目录里面放一个测试文件,serverlist.txt
(3) 更换监听端口为 8889(程序 GG 们是不是有似曾相识的感觉)
(4) 用 slowhttptest 工具对 debian7 测试上面四种攻击方法,工具 wiki
结果如下:
slow header
slowhttptest -c 65500 -H -i 10 -r 200 -s 8192 -t SLOWHEADER -u http://debian7:8889
给 Apache 发送的请求如下(Header 少了一个换行,表示 Header 一直没发完):
Apache 中充斥着这样的连接,导致 DOS
slow read
slowhttptest -c 65500 -X -r 1000 -w 10 -y 20 -t SLOWREAD -n 5 -z 32 -u http://debian7:8889
给 Apache 发送的是合法的请求(但是窗口很小)
最终导致占满了连接,依然 DOS
slow post
slowhttptest -c 65500 -B -i 10 -r 200 -s 8192 -t SLOWBODY -u http://debian7:8889
给 Apache 发送的请求如下(以很慢的速度来发送 message body)
同样也导致 DOS
Apache Range Attack
已失效的攻击方法,可以看一下它给 Apache 发送的请求是什么样的
slowhttptest -c 65000 -R -u http://debian7:8889 -t HEAD -a 5 -b 300000 -r 500
要求服务器将文件分成很多很多的小段,用来消耗服务器资源,理论上 CPU 和 Memory 会增加
对于 Apache 可以做以下优化:
MaxRequestWorkers was called MaxClients before version 2.3.13. The old name is still supported.
可以使用 Apache 的模块来缓解 Http Slow Attack
mod_reqtimeout:默认已启用。设置 header 和 body 的发送时间及频率
<IfModule reqtimeout_module>
RequestReadTimeout header=20-40,minrate=500
RequestReadTimeout body=10,minrate=500
</IfModule>
mod_qos:开源模块,需额外安装。可设置多个参数来控制客户端的连接,如最大 IP 数、每个 IP 最大连接数等
<IfModule mod_qos.c>
# handle connections from up to 100000 different IPs
QS_ClientEntries 100000
# allow only 50 connections per IP
QS_SrvMaxConnPerIP 50
# limit maximum number of active TCP connections limited to 256
MaxClients 256
# disables keep-alive when 180 (70%) TCP connections are occupied
QS_SrvMaxConnClose 180
# minimum request/response speed (deny slow clients blocking the server, keeping connections open without requesting anything
QS_SrvMinDataRate 150 1200
</IfModule>
mod_security:开源模块,需额外安装。性能较好,可以为 Web 应用提供一个外部安全层来检测和抵御攻击
SecRule RESPONSE_STATUS "@streq 408" "phase:5,t:none,nolog,pass, setvar:ip.slow_dos_counter=+1, expirevar:ip.slow_dos_counter=60, id:'1234123456'"
SecRule IP:SLOW_DOS_COUNTER "@gt 5" "phase:1,t:none,log,drop, msg:'Client Connection Dropped due to high number of slow DoS alerts', id:'1234123457'"
根据上面的配置, mod_security 记录每个 IP 让 Apache 返回 408(request timeout) 的次数,当一分钟内超过 5 次时,那个 IP 的请求会在 5 分钟内全部被丢弃。 当然也可以根据实际情况配置其他的安全策略。
刚刚的使用场景仅仅是从 Apache 获取 serverlist,每个 IP 只需要一个短链接就可以满足需求,所以直接在 iptables 中限制每个 IP 的连接数可以解决以上绝大部分问题,除非攻击者拥有众多肉鸡,否则单 IP 的攻击将失去效果。
iptables -A INPUT -p tcp --syn --dport 8889 -m connlimit --connlimit-above 20 -j REJECT --reject-with tcp-reset
用 iptables 设置了每个 IP 的最大连接数后,测试结果显示 Attacker 只能建立 20 个连接,所有攻击方法失效。