利用Nignx巧妙解决我所遇到的DDOS攻击
自家的APP上线已经有一段时间了,突然有一天发现线上产品居然不能发送验证码。
登录第三方短信验证码服务后台,发现问题很严重。
3 | youbiquan | 15797 | 2015-12-25 |
4 | youbiquan | 57 | 2015-12-23 |
5 | youbiquan | 49 | 2015-12-22 |
6 | youbiquan | 54 | 2015-12-21 |
7 | youbiquan | 64 | 2015-12-20 |
发现几天前,短信服务居然发出去15000多条短信出去,直接把服务费刷光了。
要找原因就只能找 Nignx 的日志了。
日志中,发现大量的对短信接口的访问,并且在我查看时候,日志依然在疯狂的追加,是典型的ddos攻击了。当然最核心的内容还是对短信接口的疯狂访问量
221.178.182.21 - - [05/Jan/2016:16:19:25 +0800] "POST /myinterface?showType=smsAuthcode HTTP/1.1" 200 161 "-" "Dalvik/1.6.0 (Linux; U; Android 4.4.3; XM50h Build/19.1.1.C.1.2)" "-" 171.82.225.66 - - [05/Jan/2016:16:19:32 +0800] "POST /myinterface?showType=smsAuthcode HTTP/1.1" 200 161 "-" "Dalvik/1.6.0 (Linux; U; Android 4.4.4; 2014812 MIUI/V6.6.3.0.KHJCNCF)" "-" 171.82.225.66 - - [05/Jan/2016:16:19:32 +0800] "POST /myinterface?showType=smsAuthcode HTTP/1.1" 200 161 "-" "Dalvik/1.6.0 (Linux; U; Android 4.4.4; 2014812 MIUI/V6.6.3.0.KHJCNCF)" "-" 110.89.16.13 - - [05/Jan/2016:16:19:49 +0800] "POST /myinterface?showType=smsAuthcode HTTP/1.1" 200 161 "-" "Dalvik/1.6.0 (Linux; U; Android 4.2.2; R827T Build/JDQ39)" "-" 110.89.16.13 - - [05/Jan/2016:16:19:49 +0800] "POST /myinterface?showType=smsAuthcode HTTP/1.1" 200 161 "-" "Dalvik/1.6.0 (Linux; U; Android 4.2.2; R827T Build/JDQ39)" "-" 118.114.160.200 - - [05/Jan/2016:16:21:26 +0800] "POST /myinterface?showType=smsAuthcode HTTP/1.1" 200 161 "-" "Mozilla/5.0" "-" 118.114.160.200 - - [05/Jan/2016:16:21:39 +0800] "POST /myinterface?showType=smsAuthcode HTTP/1.1" 200 161 "-" "Mozilla/5.0" "-" 119.122.0.136 - - [05/Jan/2016:16:21:41 +0800] "POST /myinterface?showType=smsAuthcode HTTP/1.1" 200 161 "-" "Mozilla/5.0" "-" 118.114.160.200 - - [05/Jan/2016:16:21:51 +0800] "POST /myinterface?showType=smsAuthcode HTTP/1.1" 200 161 "-" "Mozilla/5.0" "-"甚至在很多访问量过大时候,都会觉得服务器不能正常提供服务,处于崩溃的边缘。
2. 临时方案
在搞清楚问题之前,首先想到的是,先把短信服务停掉,让攻击者不能访问服务,但是又不能将服务器关掉,毕竟线上用户还在使用。
所以先用nginx把这个接口rewrite了。
if ( $request_uri ~* "showType=smsAuthcode" ) { rewrite ^/ http://www.baidu.com/; }
当然配置方法可能有好多,这里只是提供一个解决问题的思路,具体配置还可以参考更专业的nginx配置的资料。
首先给百度抱歉,把攻击请求转发给百度了。其实随便return一个值就好了,例如200.
3. 基于log分析的方案
当然问题这样,并不能算解决,线上用户也不能注册新用户了。
我首先想到的方案还是对IP访问限制,分析了一下log,有的ip攻击次数到达几千次,当然也有的ip只有几次访问。对于访问几次的ip,其实没有办法确定是真用户还是攻击机器的IP。 在网上找了一个可以让某个接口,在一定时间内,限制ip访问次数的方案。
iptables -A INPUT -p tcp --dport 80 -d xx.xx.xx.xx -m string --string "/myinterface?showType=smsAuthcode" --algo kmp -m recent --name httpuser --set iptables -A INPUT -m recent --update --name httpuser --seconds 86400 --hitcount 4 -j LOG --log-level 5 --log-prefix 'HTTP attack: ' iptables -A INPUT -m string --string "/myinterface?showType=smsAuthcode" --algo kmp -m recent --update --name httpuser --seconds 86400 --hitcount 10 -j REJECT
基本的含义,就是对访问的请求进行字符串匹配,如果发现有对短信接口的访问,就使用recent模块记录下来访问,如果在一天中访问超过4次,就不让再访问短信接口。
其实也是有一定效果的方案
序号 | 账号 | 数量(条) | 日期 |
---|---|---|---|
2 | youbiquan | 540 | 2016-01-08 |
3 | youbiquan | 2857 | 2016-01-04 |
4 | youbiquan | 388 | 2016-01-05 |
5 | youbiquan | 2469 | 2016-01-06 |
虽然采用基于ip地址的防范,有点效果,但是依然没有根本防住的,我们平时一天也就发50条左右,IP防火墙设置后,依然每天有几千条。分析后发现,这个攻击使用的IP地址是在太多了,所以感觉用IP地址防根本没有希望。
某一天,一筹莫展的时候,我又打开nginx访问日志,突然发现攻击的行为的 user-agent都好短,和其他访问的user-agent有明显差别。
似乎攻击者的user-agen都是“Mozila/5.0“,然后就没有了,而其他的访问,会有更多信息,包括系统版本,浏览器等。
按照这样的猜想,我去用程序分析user-agent,果然只有访问短信接口的UA中存在很短的 “Mozila/5.0“, 其他访问不存在这个UA,但是还有一些不短的UA
Dalvik/1.6.0 (Linux; U; Android 4.2.2; R827T Build/JDQ39)" "-"于是就搜了一下,发现Dalvik是一个Android虚拟机,瞬间觉得明朗了,感觉完全可以基于UA防范,把Mozila/5.0和虚拟机全拦截住,问题不就解决了么。
于是在nginx的配置里,加了下面几段代码
if ($http_user_agent = "Mozilla/5.0") { return 503; } if ($http_user_agent ~* "Dalvik/1.6.0") { return 503; }
第一段就是严格匹配 Mozila/5.0 第二段的意思以 Dalvik开头的UA,就是虚拟机的UA。
果然在采用这个方式防范以后,瞬间有了明显效果。
2 | youbiquan | 57 | 2016-01-09 |
按照新方法,从新防范后,短信发送的条数,直接回到之前的正常水平,自己用了几个手机测试了一下,也是OK的。
不过也不能高兴的太早,似乎攻击者也很容易伪造UA,想要完全解决DDOS,还要更多学习科学文化知识才行~
以上就介绍了利用Nignx巧妙解决我所遇到的DDOS攻击,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。