阿里云
阿里云多端小程序中小企业获客首选
发表主题 回复主题
  • 15102阅读
  • 1回复

Nginx简单防御CC攻击

级别: 荣誉会员
发帖
182
云币
249
4/ _jrZO  
Nginx是一款轻量级的Web服务器,由俄罗斯的程序设计师Igor Sysoev所开发,最初供俄国大型的入口网站及搜寻引Rambler使用。 其特点是占有内存少,并发能力强,事实上Nginx的并发能力确实在同类型的网站服务器中表现较好。 )U %`7(bN  
Nginx虽然可以比Apache处理更大的连接数,但是HTTP GET FLOOD针对的不仅仅是WEB服务器,还有数据库服务器。大量HTTP请求产生了大量的数据库查询,可以在几秒之内使数据库停止响应,系统负载升高,最终导致服务器当机。 ?'> .>  
本文主要介绍Centos+Nginx下如何快速有效得防御CC攻击。至于如何安装Nginx就不详细介绍了,有兴趣的读者可以在Nginx官方网站(http://www.nginx.org/)下载源代码进行编译。如果你使用的是Centos5,也可以使用rpm包进行安装(http://centos.alt.ru/repository/centos/5/i386/nginx-stable-0.7.65-1.el5.i386.rpm)。 & kC  
1.主动抑制 \zBi-GI7  
为了让Nginx支持更多的并发连接数,根据实际情况对工作线程数和每个工作线程支持的最大连接数进行调整。例如设置“worker_processes 10”和“worker_connections 1024”,那这台服务器支持的最大连接数就是10×1024=10240。 QX=TuyO  
worker_processes 10; v"k ? e  
events { :^)?AO#J  
use epoll; ^~~Rto)Y  
worker_connections 10240; iB)\* )  
} 1-y8Hy_a2  
Nginx 0.7开始提供了2个限制用户连接的模块:NginxHttpLimitZoneModule和NginxHttpLimitReqModule。 T!c|O3m  
NginxHttpLimitZoneModule可以根据条件进行并发连接数控制。 wn[)/*(,$(  
例如可以定义以下代码: Y_%:%J  
http { (<Cq_K w  
limit_zone   my_zone  $binary_remote_addr  10m; Q!l(2nva  
server { _.s ,gX  
location /somedir/ { H$I~Vz[\yb  
limit_conn   my_zone  1; :s *  
} Ey=2 zo^F  
} P]Fb0X  
} |4@cX<d.  
其中“limit_zone my_zone $binary_remote_addr 10m”的意思是定义一个名称为my_zone的存储区域、my_zone中的内容为远程IP地址、my_zone的大小为10M;“location /somedir/”的意思是针对somedir目录应用规则;“limit_conn my_zone 1”的意思是针对上面定义的my_zone记录区记录的IP地址在指定的目录中只能建立一个连接。 fI`Ez!w0  
NginxHttpLimitReqModule可以根据条件进行请求频率的控制。 Yi Zk|K_  
例如可以定义以下代码: OJe!K:  
http { Ow;thNN  
limit_req_zone  $binary_remote_addr  zone=my_req_zone:10m   rate=1r/s; W8& )UtWQ  
... 9k6s  
server { m,HE4`g  
... s{^B98d+W  
location /somedir/ { (.#nl}fA  
limit_req_zone   zone= my_req_zone  burst=2; ?'k_K:_  
} [<XYU,{R  
其中“limit_req_zone $binary_remote_addr zone=my_req_zone:10m rate=1r/s”的意思是定义一个名称为my_req_zone的存储区域,my_req_zone内容为远程IP地址,my_req_zone大小为10M,my_req_zone中的平均请求速率只能为1个每秒;“location /somedir/”的意思是针对somedir目录应用规则;“limit_req_zone zone= my_req_zone burst=2”的意思是针对上面定义的my_req_zone记录区记录的IP地址在请求指定的目录中的内容时最高2个每秒的突发请求速率。 chICc</l&  
当有连接触发上诉规则时,Nginx会报“503 Service Temporarily Unavailable”的错误,停止用户请求。返回一个503,对服务器来说影响不大,只占用一个nginx的线程而已,相对来说还是很划算的。 F6U#EvL  
为了测试效果,我将以上代码放入Nginx的配置文件,并编写了一个php文件显示phpinfo;另外还写了一个html文件,其中嵌入了多个iframe调用php文件。当我打开这个html文件了,可以看到只有一个iframe中的php文件正常显示了,其他的iframe都显示503错误。 # xO PF9  
zmhc\M ?z  
应用举例(Discuz!) ZUI6VM  
Discuz!是使用比较多的一个php论坛程序。以Discuz!7.0为例,程序目录下有比较多的可以直接访问的php文件,但其中最容易受到攻击的一般有index.php(首页)、forumdisplay.php(板块显示)、viewthread.php(帖子显示)。攻击者一般会对这些页面发起大量的请求,导致HTTP服务器连接数耗尽、mysql数据库停止响应,最终导致服务器崩溃。 V?EX`2S  
为了防止上述页面被攻击,我们可以设定以下的规则进行防御: e|k]te  
http { V*n$$-5 1-  
limit_zone   myzone_bbs  $binary_remote_addr  10m; O:0{vu9AQ  
limit_req_zone $binary_remote_addr zone=bbs:10m rate=1r/s; qm=U<'b^  
... i:YX_+n  
server { a_Xwi:e<  
... xKu#O H  
location ~ ^/bbs/(index|forumdisplay|viewthread).php$ { d[6 'w ?  
limit_conn   myzone_bbs  3; :)lS9<Y}  
limit_req zone=bbs burst=2 nodelay; D&FDPaJM  
root           html; LuySa2 ,  
fastcgi_pass   unix:/dev/shm/php-cgi.sock; =][ )|n  
fastcgi_index  index.php; v? ."`,e  
fastcgi_param  SCRIPT_FILENAME  /usr/share/nginx/html$fastcgi_script_name; LzL)qdL  
include        fastcgi_params; O[d#-0s  
} Cf(WO-F^  
} AFi_P\X  
} (xG%H:6,  
应用这条规则后,bbs目录下的index.php、forumdisplay.php和viewthread.php这些页面同一个IP只许建立3个连接,并且每秒只能有1个请求(突发请求可以达到2个)。 %np(z&@wi  
虽然这样的规则一般来说对正常的用户不会产生影响(极少有人在1秒内打开3个页面),但是为了防止影响那些手快的用户访问,可以在nginx中自定义503页面,503页面对用户进行提示,然后自动刷新。 fnq 3ic"V  
在Nginx中自定义503页面: +6uf6&.@~  
error_page   503   /errpage/503.html; @aQ:3/  
503页面的源代码: S TWH2_`  
<html> VzXVy)d  
< head> c!E{fSP  
< title>页面即将载入....</title> tU?BR<q  
< meta http-equiv=content-type c> j4;^5 Dy^  
< META NAME="ROBOTS" C> C<_\{de|9  
< /head> %%K3J<5  
< body bgcolor="#FFFFFF"> (9`dLw5  
< table cellpadding="0" cellspacing="0" border="0" width="700" align="center" height="85%"> ;j9%D`u<  
<tr align="center" valign="middle"> [2,D]e  
<td>  D_dv8  
<table cellpadding="10" cellspacing="0" border="0" width="80%" align="center" style="font-family: Z7bJ<TpZ  
Verdana, Tahoma; color: #666666; font-size: 11px"> <( OHX3~  
<tr> -F?97&G$  
<td valign="middle" align="center" bgcolor="#EBEBEB"> =Xvm#/  
<br /><b style="font-size: 16px">页面即将载入</b> * sldv  
<br /><br />你刷新页面的速度过快。请少安毋躁,页面即将载入... Lk|`\I T  
<br /><br />[<a href="javascript:window.location.reload();"><font color=#666666>立即重新载入</font></a>] q;#AlquY@  
<br /><br /> se.HA  
</td> i!%WEHPe  
</tr> 6hj[/O)E  
</table> 5Xr})%L  
</td> j1`<+YT<#  
</tr> dDA8IW![S  
< /table> u D(C jHM>  
< /body> pfZ[YC-  
< /html> S(CkA\[rz  
kBqgz| jE%  
< SCRIPT language=javascript> >TglX t+  
function update() 1qR$ Yr\  
{ {X<g93  
window.location.reload(); qv(3qY  
} 8o+:|V~X  
setTimeout("update()",2000); +F q_w  
< /script> iDcTO}  
2.被动防御 JkN*hm?  
虽然主动防御已经抵挡了大多数HTTP GET FLOOD攻击,但是道高一尺魔高一丈,攻击者会总会找到你薄弱的环节进行攻击。所以我们在这里也要介绍一下被动防御的一些方法。 L~f~XgQ  
1)封IP地址 LpY{<:y  
访问者通过浏览器正常访问网站,与服务器建立的连接一般不会超过20个,我们可以通过脚本禁止连接数过大的IP访问。 8x- 19#  
以下脚本通过netstat命令列举所有连接,将连接数最高的一个IP如果连接数超过150,则通过 iptables阻止访问: 3\4e{3$  
#!/bin/sh Iu P~Vt{m  
status=`netstat -na|awk '$5 ~ /[0-9]+:[0-9]+/ {print $5}' |awk -F ":" -- '{print $1}' |sort -n|uniq -c |sort -n|tail -n 1` -HGRrWS  
NUM=`echo $status|awk '{print $1}'` !U:&8Le  
IP=`echo $status|awk '{print $2}'` E} ]=<8V  
result=`echo "$NUM > 150" | bc` V'#R1x"3  
if [ $result = 1 ] U]}FA2  
then V|@bITJ?7  
echo IP:$IP is over $NUM, BAN IT! sN8pwRjb  
/sbin/iptables -I INPUT -s $IP -j DROP @]IRB1X  
fi Odwf7>  
运行crontab -e,将上述脚本添加到crontab每分钟自动运行: Uhr2"Nuuy  
* * * * * /root/xxxx.sh ,+ IFV  
通过apache自带的ab工具进行服务器压力测试: ML'y`S  
ab -n 1000 -c 100 http://www.xxx.com/bbs/index.php T16gq-h'  
测试完成后,我们就可以看到系统中有IP被封的提示: pTGGJ,  
[root@xxxxxx ~]#tail /var/spool/mail/root V-7l+C5  
Content-Type: text/plain; charset=ANSI_X3.4-1968 N@tKgx  
Auto-Submitted: auto-generated V*PL_|Q5  
X-Cron-Env: <SHELL=/bin/sh> l'q%bi=f  
X-Cron-Env: <HOME=/root> 5- GS@fY  
X-Cron-Env: <;PATH=/usr/bin:/bin> P<Bx1H-z-  
X-Cron-Env: <LOGNAME=root> qJT/4 8lf_  
X-Cron-Env: <USER=root> bwhH2^ !  
n_; s2,2r  
IP:58.246.xx.xx is over 1047, BAN IT! deaB_cjdI  
至此,又一次HTTP GET FLOOD防御成功。 ;PC!  
2)根据特征码屏蔽请求(对CC攻击效果较好) izcaWt3 a  
一般同一种CC攻击工具发起的攻击请求包总是相同的,而且和正常请求有所差异。 .B<Bqr@?8  
当服务器遭遇CC攻击时,我们可以快速查看日志,分析其请求的特征,比如User-agent。下面的是某一次CC攻击时的User-agent iii|;v ]+  
Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0; MyIE 3.01)Cache-Control: no-store, must-revalidate MhCU; !  
几乎没有正常的浏览器会在User-agent中带上“must-revalidate”这样的关键字。所以我们可以以这个为特征进行过滤,将User-agent中带有“must-revalidate”的请求全部拒绝访问: o$</At  
if ($http_user_agent ~ must-revalidate) { ;$&\ :-6A#  
return 403; v]{UH {6  
} YhV<.2^k  
本文主要介绍了nginx下的HTTP GET FLOOD防御,如果有不对的地方,希望大家可以向我提出。同时,也希望大家能够举一反三,把这种思路应用到apache、lighttpd等常见的web服务器中。
本帖最近评分记录: 1 条评分 云币 +5
kideny 云币 +5 此贴已经加入 http://bbs.aliyun.com/read/135619.html? 2014-07-21
级别: 科学怪人
发帖
9985
云币
21878

只看该作者 沙发  发表于: 2014-07-21
此贴已经加入 http://bbs.aliyun.com/read/135619.html?
发表主题 回复主题
« 返回列表上一主题下一主题

限100 字节
批量上传需要先选择文件,再选择上传
 
验证问题: 67 - 31 = ?
上一个 下一个
      ×
      全新阿里云开发者社区, 去探索开发者的新世界吧!
      一站式的体验,更多的精彩!
      通过下面领域大门,一起探索新的技术世界吧~ (点击图标进入)