一、 攻击描述
年初开始,网站应用服务器网卡流量普遍蹿升到100M以上,其中几台服务器网卡流量更是达到了204Mbps。随之带来的就是访问速度逐渐变慢,网络带宽数次被用完。
二、 攻击分析
1、 既然是网卡流出100M以上,那么一定有不正常的请求地址过来,接着服务器才会响应并发送到客户端。由此判断是请求的地址有异常 IT网.cn,http://www.it.net.cn
应用服务器受到攻击时的网卡流量图 IT网.cn,http://www.it.net.cn
IT网.cn,http://www.it.net.cn
网站应用服务器受到攻击时的负载现象
IT网,http://www.it.net.cn
IT网.cn,http://www.it.net.cn
2、 分析web日志,可以发现很多IP同时在一秒钟对的多个地址发送GET请求,且返回的地址的流量在200k-300k之间。试想一下,返回一个php地址,怎么会有200多k的流量,那么就一定是恶意的请求。看下面url中的 232347,这个232347,就是返回给客户端的流量。 IT网.cn,http://www.it.net.cn
123.232.102.228 - - [07/Mar/2012:14:24:23 +0800] "GET /forum-116-20.html HTTP/1.0" "200" 232347 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)" "-"
123.232.102.228 - - [07/Mar/2012:14:24:23 +0800] "GET /forum-1402-1.html HTTP/1.0" "200" 253872 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)" "-"
123.232.102.228 - - [07/Mar/2012:14:24:23 +0800] "GET /forum-63-1.html HTTP/1.0" "200" 118163 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)" "-"
123.232.102.228 - - [07/Mar/2012:14:24:23 +0800] "GET /forum-1342-1.html HTTP/1.0" "200" 235327 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)" "-"
123.232.102.228 - - [07/Mar/2012:14:24:23 +0800] "GET /forum.php?mod=forumdisplay&fid=58 HTTP/1.0" "200" 283377 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)" "-"
3、攻击主要针对php应用,php并发跟nginx差了好几个数量级。这次攻击,平均每台php 每秒最高承受200个并发,绝大部分的针对列表页,直接对数据库造成影响。
四、解决方案
1、防火墙封IP(不推荐)
用封IP的方式来阻止攻击源IP,是一种方法,起初,我是采用了这种方法,但是这样封IP,还需要到日志中去搜索。比较繁琐,而且效果不明现。 IT网.com,http://www.it.net.cn
2、Nginx被动防御(推荐)
还记得日志中的相同的user-agent的没有,nginx这次利用了user-agent来防御攻击。
在的nginx的配置文档的上面加入了
if ( $http_user_agent ~* "Mozilla/4.0\ \(compatible;\ MSIE\ 6.0;\ Windows\ NT\ 5.0\;\ .NET\ CLR\ 1.1.4322\)" )
{
return 444;
}
重启nginx后,nginx 在日志中检测到该类user-agent时,就会返回444 http 状态码,既请求失败。这样设置后,各应用服务器负载恢复到正常,网卡流量正常。
218.5.73.245 - - [07/Mar/2012:10:53:12 +0800] "GET /forum-222-1.html HTTP/1.0" 444 0 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)"
218.5.73.245 - - [07/Mar/2012:10:53:12 +0800] "GET /forum-222-1.html HTTP/1.0" 444 0 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)"
218.5.73.245 - - [07/Mar/2012:10:53:12 +0800] "GET /forum-222-1.html HTTP/1.0" 444 0 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)"
Nginx 处理攻击ip的结果
五、总结
1、本次nginx 在防小型ddos或者cc有自己的特色:处理请求高效,消耗资源极低。 IT网.cn,http://www.it.net.cn
缺点:需要分析日志,找到规律,比如:user-agent等等。
2、疑问?
Q:有些同学要问了,这样屏蔽该类user-agent,造成误杀率有多大?
A:cc攻击者攻击时,都会有自己特殊的user-agent,屏蔽该类user-agent,不会造成额外的误杀。这是通过观察屏蔽日志的得出来的结论,服务器用上该类策略后,从来木有一个网友因为这事找过。
Q:如果cc攻击软件伪装成正常的user-agent,这样的造成误杀多大? IT网.cn,http://www.it.net.cn
A:1):并不是所有的攻击者都具备修改user-agent的,相当部分的攻击者用的都是购买的攻击软件,如果要修改,则要付出金钱的代价。这不是攻击者想要的结果。2):就算是伪装成了正常的user-agent,也会有自己的特点,可以从其共有特征来分析,比如来源地址是否相同等等,这里就可以作为共同点来设置策略。在做策略时应注意观察nginx屏蔽日志中,是否其他的正常的请求也被屏蔽了?
124.133.235.202 - - [08/Mar/2012:10:33:37 +0800] "GET / HTTP/1.1" 302 163 "/zhuanti/nzpp/zonghegr.jsp?group=2" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)" -
124.133.235.202 - - [08/Mar/2012:10:33:37 +0800] "GET / HTTP/1.1" 302 163 "/zhuanti/nzpp/zonghegr.jsp?group=2" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)" -
124.133.235.202 - - [08/Mar/2012:10:33:37 +0800] "GET / HTTP/1.1" 302 163 "/zhuanti/nzpp/zonghegr.jsp?group=2" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)" -
124.133.235.202 - - [08/Mar/2012:10:33:37 +0800] "GET / HTTP/1.1" 302 163 "/zhuanti/nzpp/zonghegr.jsp?group=2" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)" -
124.133.235.202 - - [08/Mar/2012:10:33:37 +0800] "GET / HTTP/1.1" 302 163 "/zhuanti/nzpp/zonghegr.jsp?group=2" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)" -
124.133.235.202 - - [08/Mar/2012:10:33:37 +0800] "GET / HTTP/1.1" 302 163 "/zhuanti/nzpp/zonghegr.jsp?group=2" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)" -
124.133.235.202 - - [08/Mar/2012:10:33:37 +0800] "GET / HTTP/1.1" 302 163 "/zhuanti/nzpp/zonghegr.jsp?group=2" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)" -
124.133.235.202 - - [08/Mar/2012:10:33:37 +0800] "GET / HTTP/1.1" 302 163 "/zhuanti/nzpp/zonghegr.jsp?group=2" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)" -
例如上面的日志,这次攻击者将user-agent伪装成正常的,再用user-agent做关键字,就会有部分误杀了。所以针对此类攻击,可以以来源地址作为关键字,nginx防护策略可以这么做, IT网.cn,http://www.it.net.cn
if ($http__referer ~ * "/zhuanti/nzpp/zonghegr.jsp?group=2")
{
return 444;
} IT网,http://www.it.net.cn
这样就不会有误杀了
3、经验教训 IT网,http://www.it.net.cn
教训:去年的一次CC攻击,跟这次攻击有异曲同工之处,都是打的是php;那时我们在启用了黑洞防护墙后效果并不明显。
经验:当天晚上,我仔细分析了web日志,发现其user-agent,都是相同的,例如windows 5.0,跟正常的windows NT 5.0有本质区别,那可不可以在这上面做文章呢。带着这个问题,在网上搜索了nginx 防cc方面的资料,果然发现网上的高手的想法跟我的相同,都从其相同点user-agent入手,用nginx 来匹配该类user-agent,然后返回503 http状态码,当然这里我做了修改,返回了444状态码。所以,在吸取了上次的教训后,在今年网站遭受攻击时,我果断采用该条策略,结果证明效果很明显。虽然cc攻击一直在持续,但是网站访问依然流畅。
公司网站直接不能访问了,立即登录服务器,直接top看到情况如下:
发现负载都达到了800了,机器眼看就要爆了,首先先停了mysql,发现负载有点下降,联系了开发同事一同查看,因为今天新上线了一些代码,可能是新上代码的问题,随后看到负载依然没降,然后将php和nginx都重启了,虽然短暂的降了一些,过一会立马负载又起来了,这时看了下nginx日志,看是不是用户访问导致的问题,结果一看就发现问题了,如下:
30分钟发了你60w+的请求。
发现这个ip不停的发请求,很明显,是被攻击了,临时将这个ip在nginx中deny掉,直接返回给它503,配置如下:在server中加入
负载也慢慢降下来了,服务也正常了,当时太晚了,洗洗就睡了,结果第二天早上一来又发现网站打不开了,直接看nginx日志,攻击者换了一个ip,跟昨晚的现象一样,这次直接在源头把他干掉了,就是添加iptables,如下:
将攻击的ip全部写入iptables里面,然后联系机房看能不能做策略协助解决这种CC攻击,最后机房那边也将这些ip给封了,但是攻击者在换ip怎么办?不可能他换一个我加一条把,看来只能发大招了,写了个iptables脚本,如下:
统计tcp连接,同一ip超过500次tcp连接的肯定就是攻击者的ip了,正常用户也不可能一下去开500个窗口去访问我的网站吧,然后将这个ip直接在iptables上面干掉,现在好了,问题解决了,这种CC攻击有一个特点就是用的源ip基本都是固定的,DDOS有些可能是用不同原ip进行攻击,那么这种防御就显得有些吃力了。那遇到不同源ip攻击怎么防御呢?
首先要联系机房,一般机房都有监控和防御设备,让机房帮忙解决一些问题可能更有效,不能在iptable上面去防御,就只能通过nginx去防御了,让nginx去识别哪些是攻击者,哪些是真正的用户?其实nginx有2个模块:ngx_http_limit_conn_module和ngx_http_limit_req_module
可以参考官方文档:
http://nginx.org/cn/docs/http/ngx_http_limit_req_module.html
http://nginx.org/cn/docs/http/ngx_http_limit_conn_module.html
首先在http中定义,如下:
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
然后到你需要限制的目录下面,server段中,一般就是php请求,如下:
location ~* ^/(.*)\.php?$ {
limit_conn addr 3;
limit_req zone=one burst=2 nodelay;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $host_path/$fastcgi_script_name;
include fastcgi_params;
}
应用这2条规则后,只要需要执行php脚本的这些页面同一个IP只许建立3个连接,并且每秒只能有1个请求(突发请求可以达到2个)。
虽然这样的规则一般来说对正常的用户不会产生影响(极少有人在1秒内打开3个页面),但是为了防止影响那些手快的用户访问,可以在nginx中自定义503页面,503页面对用户进行提示,然后自动刷新,这个参数可以根据自己的情况进行更改,这样不管攻击者是多个ip还是单个ip攻击都可以防御到,
如果在nginx日志中能找到攻击者特有的代码,这样就更容易防御,
比如User-agent。下面的是某一次CC攻击时的User-agent
Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0; MyIE 3.01)Cache-Control: no-store, must-revalidate
几乎没有正常的浏览器会在User-agent中带上“must-revalidate”这样的关键字。所以我们可以以这个为特征进行过滤,将User-agent中带有“must-revalidate”的请求全部拒绝访问:
if ($http_user_agent ~ must-revalidate) {
return 403;
}
来源:oschina
链接:https://my.oschina.net/u/1433107/blog/409966