怎么使用nginx防cc攻击配置御CC攻击

更多公众号:heiyeluren-techLAMP相关的互联网技术的交流咨询分享最新文章相关推荐搜狗:感谢您阅读[]说说服务器被攻击,怎么定位,怎么解决,怎么防御?,本文可能来自网络,如果侵犯了您的相关权益,请联系管理员。QQ:1234567891011
http {&&&&limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s; //触发条件,所有访问ip 限制每秒10个请求&&&&...&&&&server {&&&&&&&&...&&&&&&&&location&&~ \.php$ {&&&&&&&&&&&&limit_req zone=one burst=5 nodelay;&& //执行的动作,通过zone名字对应&&&&&&&&&&&&&& }&&&&&&&&&& }&&&& }&
参数说明:
$binary_remote_addr&&二进制远程地址zone=one:10m&&&&定义zone名字叫one,并为这个zone分配10M内存,用来存储会话(二进制远程地址),1m内存可以保存16000会话rate=10r/s;&&&& 限制频率为每秒10个请求burst=5&&&&&&&& 允许超过频率限制的请求数不多于5个,假设1、2、3、4秒请求为每秒9个,那么第5秒内请求15个是允许的,反之,如果第一秒内请求15个,会将5个请求放到第二秒,第二秒内超过10的请求直接503,类似多秒内平均速率限制。nodelay&&&&&&&& 超过的请求不被延迟处理,设置后15个请求在1秒内处理。&
二.限制IP连接数
ngx_http_limit_conn_module的配置方法和参数与http_limit_req模块很像,参数少,要简单很多
<div class="crayon-num" data-line="crayon-585b8c<div class="crayon-num crayon-striped-num" data-line="crayon-585b8c<div class="crayon-num" data-line="crayon-585b8c<div class="crayon-num crayon-striped-num" data-line="crayon-585b8c<div class="crayon-num" data-line="crayon-585b8c<div class="crayon-num crayon-striped-num" data-line="crayon-585b8c<div class="crayon-num" data-line="crayon-585b8c<div class="crayon-num crayon-striped-num" data-line="crayon-585b8c<div class="crayon-num" data-line="crayon-585b8c<div class="crayon-num crayon-striped-num" data-line="crayon-585b8c<div class="crayon-num" data-line="crayon-585b8c
http {&&&&limit_conn_zone $binary_remote_addr zone=addr:10m; //触发条件&&&&...&&&&server {&&&&&&&&...&&&&&&&&location /download/ {&&&&&&&&&&&&limit_conn addr 1;&&&&// 限制同一时间内1个连接,超出的连接返回503&&&&&&&&&&&&&&&&}&&&&&&&&&& }&&&& }&
三.白名单设置
http_limit_conn和http_limit_req模块限制了单ip单位时间内的并发和请求数,但是如果Nginx前面有lvs或者 haproxy之类的负载均衡或者反向代理,nginx获取的都是来自负载均衡的连接或请求,这时不应该限制负载均衡的连接和请求,就需要geo和map 模块设置白名单:
<div class="crayon-num" data-line="crayon-585b8c<div class="crayon-num crayon-striped-num" data-line="crayon-585b8c<div class="crayon-num" data-line="crayon-585b8c<div class="crayon-num crayon-striped-num" data-line="crayon-585b8c<div class="crayon-num" data-line="crayon-585b8c<div class="crayon-num crayon-striped-num" data-line="crayon-585b8c<div class="crayon-num" data-line="crayon-585b8c<div class="crayon-num crayon-striped-num" data-line="crayon-585b8c<div class="crayon-num" data-line="crayon-585b8c<div class="crayon-num crayon-striped-num" data-line="crayon-585b8c<div class="crayon-num" data-line="crayon-585b8c
geo $whiteiplist&&{&&&&&&&&default 1;&&&&&&&&10.11.15.161 0;&&&&}map $whiteiplist&&$limit {&&&&&&&&1 $binary_remote_addr;&&&&&&&&0 "";&&&&}limit_req_zone $limit zone=one:10m rate=10r/s;limit_conn_zone $limit zone=addr:10m;&
geo模块定义了一个默认值是1的变量whiteiplist,当在ip在白名单中,变量whiteiplist的值为0,反之为1
如果在白名单中--& whiteiplist=0 --& $limit="" --& 不会存储到10m的会话状态(one或者addr)中 --& 不受限制
反之,不在白名单中 --& whiteiplist=1 --& $limit=二进制远程地址 --&存储进10m的会话状态中 --& 受到限制
使用ab命令来模拟CC攻击,http_limit_conn和http_limit_req模块要分开测试,同时注意 http_limit_conn模块只统计正在被处理的请求(这些请求的头信息已被完全读入)所在的连接。如果请求已经处理完,连接没有被关闭时,是不会 被统计的。这时用netstat看到连接数可以超过限定的数量,不会被阻止。
ab -n 请求数 -c 并发 http://10.11.15.174/i.php&
如果被阻止前台会返回503,同时在nginx的error_log中会看到如下错误日志:
被限制连接数:
<div class="crayon-num" data-line="crayon-585b8c<div class="crayon-num crayon-striped-num" data-line="crayon-585b8c
2015/01/28 14:20:26 [error] 4107#0: *65525 limiting connections by zone "addr", client: 10.11.15.161, server: , request: "GET /i.php?=PHPE8-11d2-A769-00AA001ACF42 HTTP/1.1", host: "10.11.15.174", referrer: "http://10.11.15.174/i.php"&
被限制请求数:
<div class="crayon-num" data-line="crayon-585b8c<div class="crayon-num crayon-striped-num" data-line="crayon-585b8c
2015/01/28 14:18:59 [error] 4095#0: *65240 limiting requests, excess: 5.772 by zone "one", client: 10.11.15.161, server: , request: "GET /i.php?=PHPE8-11d2-A769-00AA001ACF42 HTTP/1.1", host: "10.11.15.174", referrer: "http://10.11.15.174/i.php"&
五.其它一些防CC的方法
1.Nginx模块 ModSecurity、http_guard、ngx_lua_waf
ModSecurity 应用层WAF,功能强大,能防御的攻击多,配置复杂
ngx_lua_waf 基于ngx_lua的web应用防火墙,使用简单,高性能和轻量级
http_guard 基于openresty
2.软件+Iptables
fail2ban 通过分析日志来判断是否使用iptables拦截
DDoS Deflate 通过netstat判断ip连接数,并使用iptables屏蔽
开头说过抗DDOS是一个系统工程,通过优化系统和软件配置,只能防御小规模的CC攻击,对于大规模攻击、四层流量攻击、混合攻击来说,基本上系统和应用软件没挂,带宽就打满了。下面是我在工作中使用过的防御DDOS的方式:
高防服务器和带流量清洗的ISP 通常是美韩的服务器,部分ISP骨干供应商有流量清洗服务,例如香港的PCCW。通常可以防御10G左右的小型攻击
流量清洗服务 例如:akamai(prolexic),nexusguard 我们最大受到过80G流量的攻击,成功被清洗,但是费用非常贵
CDN 例如:蓝讯 网宿 cloudflare 等,CDN针对DDOS的分布式特点,将流量引流分散,同时对网站又有加速作用,效果好,成本相对低。
总结一下:发动攻击易,防御难。七层好防,四层难防;小型能防,大型烧钱
参考文章:
本文来自:,永久链接:
2,676 views比特客户端
您的位置:
详解大数据
详解大数据
详解大数据
详解大数据
使用Nginx防御 CC攻击叙述
关键字:CC攻击 nginx 安全管理
  本文主要介绍了有关使用Nginx防御CC攻击的一些配置。CC攻击针对的是上面的内存和CPU资源,因此通常会找到一些比较高消耗的接口,例如search.php之类的需要大量sql查询的接口。因此,明白了这一点,我们就很好防御了,主要是针对单个ip地址的连接数和请求php文件的密度来控制的。
  我们主要用到的是Nginx中提供的两个limit:
  ngx_http_limit_conn_module ngx_http_limit_req_module
  一、白名单
  首先这两个模块是支持白名单的,就是可能有某些IP地址,我们是不需要进行限制的,比如可能会是啦什么的或者自己的IP,因此需要设置一个白名单,不需要的可跳过本步。具体方法:
  在HTTP段中插入如下格式内容,声明白名单IP
  http{ ....... geo $limited{ default 1; #公司 119.123.5.0/24 0; } ......... }
  geo指令定义了一个白名单$limited变量,默认值为1,如果客户端IP在上面的范围内,$limited的值为0。
  然后紧跟在上面内容后使用map指令映射搜索引擎客户端的ip为空串,如果不是白名单IP就显示本身真实的IP,这样搜索引擎iIP就不能存到limit模块的内存中,所以不会限制白名单的IP访问。
  map $limited $limit { 1 $binary_remote_ 0 ""; }
  二、访问频率限制
  访问频率限制使用到的是ngx_http_limit_req_module,需要在两个地方配置,首先在HTTP段中,声明好这个模块一些参数,如果有设置白名单,设置如下
  http{ ... limit_req_zone $limit zone=one:10m rate=20r/m; ##平均20r/m 每分钟20个请求 ... }
  如果没有配置白名单,所有来访IP都会限制,配置如下
  http{ ... limit_req_zone $binary_remote_addr zone=one:10m rate=20r/m; ##平均20r/m 每分钟20个请求 ... }
  解释一下上面的参数,第一个代表的是需要限制的ip群,这个很好理解,第二个zone=one表示这个limit_zone的名字叫做one,后面的使用中可以用这个one来进行指代,后面的15m,代表为这个zone分配10m的内存,1m可以保存16000的$binary_remote_addr。最后一个是频率,如果要按秒来算可以设置20r/s这样。
  最后是配置到Nginx的php的解析段
  location ~ \.php$ { ... limit_req zone=one burst=5 ... }
  指定了使用名字为one的zone,然后缓冲队列为5,无延迟,如果不设置无延迟,访问会卡住。
  三、访问连接限制
  访问连接限制使用到的是ngx_http_limit_conn_module,也是需要在两个地方配置,首先在HTTP段中,声明好这个模块一些参数,如果有设置白名单,设置如下
  http{ ... limit_conn_zone $limit zone=addr:10m; ... }
  如果没有配置白名单,所有来访IP都会限制,配置如下
  view sourceprint?http{ ... limit_conn_zone $binary_remote_addr zone=addr:10m; ... }
  参数的意思跟上面的差不多也就不多解释了。
  后面的就是在server段中进行设置了,可以具体到某个目录什么的了
  server { location /download/ { limit_conn addr 5; }
  大功告成,打完收工,记得要nginx -s reload一下哦~
[ 责任编辑:小石潭记 ]
去年,手机江湖里的竞争格局还是…
甲骨文的云战略已经完成第一阶段…
软件信息化周刊
比特软件信息化周刊提供以数据库、操作系统和管理软件为重点的全面软件信息化产业热点、应用方案推荐、实用技巧分享等。以最新的软件资讯,最新的软件技巧,最新的软件与服务业内动态来为IT用户找到软捷径。
商务办公周刊
比特商务周刊是一个及行业资讯、深度分析、企业导购等为一体的综合性周刊。其中,与中国计量科学研究院合力打造的比特实验室可以为商业用户提供最权威的采购指南。是企业用户不可缺少的智选周刊!
比特网络周刊向企业网管员以及网络技术和产品使用者提供关于网络产业动态、技术热点、组网、建网、网络管理、网络运维等最新技术和实用技巧,帮助网管答疑解惑,成为网管好帮手。
服务器周刊
比特服务器周刊作为比特网的重点频道之一,主要关注x86服务器,RISC架构服务器以及高性能计算机行业的产品及发展动态。通过最独到的编辑观点和业界动态分析,让您第一时间了解服务器行业的趋势。
比特存储周刊长期以来,为读者提供企业存储领域高质量的原创内容,及时、全面的资讯、技术、方案以及案例文章,力求成为业界领先的存储媒体。比特存储周刊始终致力于用户的企业信息化建设、存储业务、数据保护与容灾构建以及数据管理部署等方面服务。
比特安全周刊通过专业的信息安全内容建设,为企业级用户打造最具商业价值的信息沟通平台,并为安全厂商提供多层面、多维度的媒体宣传手段。与其他同类网站信息安全内容相比,比特安全周刊运作模式更加独立,对信息安全界的动态新闻更新更快。
新闻中心热点推荐
新闻中心以独特视角精选一周内最具影响力的行业重大事件或圈内精彩故事,为企业级用户打造重点突出,可读性强,商业价值高的信息共享平台;同时为互联网、IT业界及通信厂商提供一条精准快捷,渗透力强,覆盖面广的媒体传播途径。
云计算周刊
比特云计算周刊关注云计算产业热点技术应用与趋势发展,全方位报道云计算领域最新动态。为用户与企业架设起沟通交流平台。包括IaaS、PaaS、SaaS各种不同的服务类型以及相关的安全与管理内容介绍。
CIO俱乐部周刊
比特CIO俱乐部周刊以大量高端CIO沙龙或专题研讨会以及对明星CIO的深入采访为依托,汇聚中国500强CIO的集体智慧。旨为中国杰出的CIO提供一个良好的互融互通 、促进交流的平台,并持续提供丰富的资讯和服务,探讨信息化建设,推动中国信息化发展引领CIO未来职业发展。
IT专家新闻邮件长期以来,以定向、分众、整合的商业模式,为企业IT专业人士以及IT系统采购决策者提供高质量的原创内容,包括IT新闻、评论、专家答疑、技巧和白皮书。此外,IT专家网还为读者提供包括咨询、社区、论坛、线下会议、读者沙龙等多种服务。
X周刊是一份IT人的技术娱乐周刊,给用户实时传递I最新T资讯、IT段子、技术技巧、畅销书籍,同时用户还能参与我们推荐的互动游戏,给广大的IT技术人士忙碌工作之余带来轻松休闲一刻。
微信扫一扫
关注Chinabyte当前位置:&>&&>&
Nginx服务器如何防止cc攻击
时间: 09:36:01 &#160;&#160; 来源:服务器之家 &#160;&#160; 投稿:root
Nginx是一款轻量级的Web服务器,由俄罗斯的程序设计师Igor
Sysoev所开发,最初供俄国大型的入口网站及搜寻引Rambler使用。
其特点是占有内存少,并发能力强,事实上Nginx的并发能力确实在同类型的网站服务器中表现较好。
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)。
1.&&&&&&& 主动抑制
为了让Nginx支持更多的并发连接数,根据实际情况对工作线程数和每个工作线程支持的最大连接数进行调整。例如设置“worker_processes
10”和“worker_connections 1024”,那这台服务器支持的最大连接数就是10×。
worker_processes 10;
worker_connections 10240;
0.7开始提供了2个限制用户连接的模块:NginxHttpLimitZoneModule和NginxHttpLimitReqModule。
NginxHttpLimitZoneModule可以根据条件进行并发连接数控制。
例如可以定义以下代码:
limit_zone&& my_zone& $binary_remote_addr&
location /somedir/ {
limit_conn&& my_zone& 1;
其中“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地址在指定的目录中只能建立一个连接。
NginxHttpLimitReqModule可以根据条件进行请求频率的控制。
例如可以定义以下代码:
limit_req_zone& $binary_remote_addr&
zone=my_req_zone:10m&& rate=1r/s;
location /somedir/ {
limit_req_zone&& zone= my_req_zone& burst=2;
其中“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个每秒的突发请求速率。
当有连接触发上诉规则时,Nginx会报“503 Service Temporarily
Unavailable”的错误,停止用户请求。返回一个503,对服务器来说影响不大,只占用一个nginx的线程而已,相对来说还是很划算的。
为了测试效果,我将以上代码放入Nginx的配置文件,并编写了一个php文件显示phpinfo;另外还写了一个html文件,其中嵌入了多个iframe调用php文件。当我打开这个html文件了,可以看到只有一个iframe中的php文件正常显示了,其他的iframe都显示503错误。
应用举例(Discuz!)
Discuz!是使用比较多的一个php论坛程序。以Discuz!7.0为例,程序目录下有比较多的可以直接访问的php文件,但其中最容易受到攻击的一般有index.php(首页)、forumdisplay.php(板块显示)、viewthread.php(帖子显示)。攻击者一般会对这些页面发起大量的请求,导致HTTP服务器连接数耗尽、mysql数据库停止响应,最终导致服务器崩溃。
为了防止上述页面被攻击,我们可以设定以下的规则进行防御:
limit_zone&& myzone_bbs& $binary_remote_addr&
limit_req_zone $binary_remote_addr zone=bbs:10m rate=1r/s;
location ~ ^/bbs/(index|forumdisplay|viewthread).php$ {
limit_conn&& myzone_bbs& 3;
limit_req zone=bbs burst=2
root&&&&&&&&&&
fastcgi_pass&& unix:/dev/shm/php-cgi.
fastcgi_index& index.
fastcgi_param& SCRIPT_FILENAME&
/usr/share/nginx/html$fastcgi_script_
include&&&&&&&
应用这条规则后,bbs目录下的index.php、forumdisplay.php和viewthread.php这些页面同一个IP只许建立3个连接,并且每秒只能有1个请求(突发请求可以达到2个)。
虽然这样的规则一般来说对正常的用户不会产生影响(极少有人在1秒内打开3个页面),但是为了防止影响那些手快的用户访问,可以在nginx中自定义503页面,503页面对用户进行提示,然后自动刷新。
在Nginx中自定义503页面:
error_page&& 503&& /errpage/503.
503页面的源代码:
& title&页面即将载入....&/title&
& meta http-equiv=content-type c&
& META NAME="ROBOTS" C&
& body bgcolor="#FFFFFF"&
& table align="center" height="85%"&
&tr align="center" valign="middle"&
&table width="80%" align="center" style="font-family:
Verdana, T color: #666666; font-size: 11px"&
&td valign="middle" align="center" bgcolor="#EBEBEB"&
&br /&&b style="font-size: 16px"&页面即将载入&/b&
&br /&&br /&你刷新页面的速度过快。请少安毋躁,页面即将载入...
&br /&&br /&[&a
href="/Article/201109/javascript:window.location.reload();"&&font
color=#666666&立即重新载入&/font&&/a&]
&br /&&br /&
& SCRIPT language=javascript&
function update()
window.location.reload();
setTimeout("update()",2000);
& /script&
2.&&&&&&& 被动防御
虽然主动防御已经抵挡了大多数HTTP GET
FLOOD攻击,但是道高一尺魔高一丈,攻击者会总会找到你薄弱的环节进行攻击。所以我们在这里也要介绍一下被动防御的一些方法。
1)&&&&&&& 封IP地址
访问者通过浏览器正常访问网站,与服务器建立的连接一般不会超过20个,我们可以通过脚本禁止连接数过大的IP访问。
以下脚本通过netstat命令列举所有连接,将连接数最高的一个IP如果连接数超过150,则通过 iptables阻止访问:
status=`netstat -na|awk '$5 ~ /[0-9]+:[0-9]+/ {print $5}' |awk -F
":" -- '{print $1}' |sort -n|uniq -c |sort -n|tail -n 1`
NUM=`echo $status|awk '{print $1}'`
IP=`echo $status|awk '{print $2}'`
result=`echo "$NUM & 150" | bc`
if [ $result = 1 ]
echo IP:$IP is over $NUM, BAN IT!
/sbin/iptables -I INPUT -s $IP -j DROP
运行crontab -e,将上述脚本添加到crontab每分钟自动运行:
* * * * * /root/xxxx.sh
通过apache自带的ab工具进行服务器压力测试:
ab -n 1000 -c 100 /bbs/index.php
测试完成后,我们就可以看到系统中有IP被封的提示:
[ ~]#tail /var/spool/mail/root
Content-Type: text/ charset=ANSI_X3.4-1968
Auto-Submitted: auto-generated
X-Cron-Env: &SHELL=/bin/sh&
X-Cron-Env: &HOME=/root&
X-Cron-Env: &;PATH=/usr/bin:/bin&
X-Cron-Env: &LOGNAME=root&
X-Cron-Env: &USER=root&
IP:58.246.xx.xx is over 1047, BAN IT!
至此,又一次HTTP GET FLOOD防御成功。
根据特征码屏蔽请求(对CC攻击效果较好)
一般同一种CC攻击工具发起的攻击请求包总是相同的,而且和正常请求有所差异。
当服务器遭遇CC攻击时,我们可以快速查看日志,分析其请求的特征,比如User-agent。下面的是某一次CC攻击时的User-agent
Mozilla/4.0 ( 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;
本文主要介绍了nginx下的HTTP GET
FLOOD防御,如果有不对的地方,希望大家可以向我提出。同时,也希望大家能够举一反三,把这种思路应用到apache、lighttpd等常见的web服务器中。
转载请注明原文地址:通过nginx配置文件抵御攻击,防御CC攻击的经典思路 - 推酷
通过nginx配置文件抵御攻击,防御CC攻击的经典思路
大家好,我们是OpenCDN团队的Twwy。这次我们来讲讲如何通过简单的配置文件来实现nginx防御攻击的效果。
其实很多时候,各种防攻击的思路我们都明白,比如限制IP啊,过滤攻击字符串啊,识别攻击指纹啦。可是要如何去实现它呢?用守护脚本吗?用PHP在外面包
一层过滤?还是直接加防火墙吗?这些都是防御手段。不过本文将要介绍的是直接通过nginx的普通模块和配置文件的组合来达到一定的防御效果。
验证浏览器行为
我们先来做个比喻。
社区在搞福利,在广场上给大家派发红包。而坏人派了一批人形的机器人(没有语言模块)来冒领红包,聪明工作人员需要想出办法来防止红包被冒领。
于是工作人员在发红包之前,会给领取者一张纸,上面写着“红包拿来”,如果那人能念出纸上的字,那么就是人,给红包,如果你不能念出来,那么请自觉。于是机器人便被识破,灰溜溜地回来了。
是的,在这个比喻中,人就是浏览器,机器人就是攻击器,我们可以通过鉴别cookie功能(念纸上的字)的方式来鉴别他们。下面就是nginx的配置文件写法。
if ($cookie_say != &hbnl&){ add_header Set-Cookie &say=hbnl&; rewrite .* &$scheme://$host$uri& redirect; }
让我们看下这几行的意思,当cookie中say为空时,给一个设置cookie
say为hbnl的302重定向包,如果访问者能够在第二个包中携带上cookie值,那么就能正常访问网站了,如果不能的话,那他永远活在了302中。
你也可以测试一下,用CC攻击器或者webbench或者直接curl发包做测试,他们都活在了302世界中。
当然,这么简单就能防住了?当然没有那么简单。
仔细的你一定会发现配置文件这样写还是有缺陷。如果攻击者设置cookie为say=hbnl(CC攻击器上就可以这么设置),那么这个防御就形同虚设了。我们继续拿刚刚那个比喻来说明问题。
坏人发现这个规律后,给每个机器人安上了扬声器,一直重复着“红包拿来,红包拿来”,浩浩荡荡地又来领红包了。
这时,工作人员的对策是这样做的,要求领取者出示有自己名字的户口本,并且念出自己的名字,“我是xxx,红包拿来”。于是一群只会嗡嗡叫着“红包拿来”的机器人又被撵回去了。
当然,为了配合说明问题,每个机器人是有户口本的,被赶回去的原因是不会念自己的名字,虽然这个有点荒诞,唉。
然后,我们来看下这种方式的配置文件写法
if ($cookie_say != &hbnl$remote_addr&){ add_header Set-Cookie &say=hbnl$remote_addr&; rewrite .* &$scheme://$host$uri& redirect; }
这样的写法和前面的区别是,不同IP的请求cookie值是不一样的,比如IP是1.2.3.4,那么需要设置的cookie是
say=hbnl1.2.3.4。于是攻击者便无法通过设置一样的cookie(比如CC攻击器)来绕过这种限制。你可以继续用CC攻击器来测试下,你会
发现CC攻击器打出的流量已经全部进入302世界中。
不过大家也能感觉到,这似乎也不是一个万全之计,因为攻击者如果研究了网站的机制之后,总有办法测出并预先伪造cookie值的设置方法。因为我们做差异
化的数据源正是他们本身的一些信息(IP、user agent等)。攻击者花点时间也是可以做出专门针对网站的攻击脚本的。
那么要如何根据他们自身的信息得出他们又得出他们算不出的数值?
我想,聪明的你一定已经猜到了,用salt加散列。比如md5(“opencdn$remote_addr”),虽然攻击者知道可以自己IP,但是他无法
得知如何用他的IP来计算出这个散列,因为他是逆不出这个散列的。当然,如果你不放心的话,怕万一能查出来的话,可以加一些特殊字符,然
后多散几次。
很可惜,nginx默认是无法进行字符串散列的,于是我们借助nginx_lua模块来进行实现。
rewrite_by_lua '
local say = ngx.md5(&opencdn& .. ngx.var.remote_addr)
if (ngx.var.cookie_say ~= say) then
ngx.header[&Set-Cookie&] = &say=& .. say
return ngx.redirect(ngx.var.scheme .. &://& .. ngx.var.host .. ngx.var.uri)
通过这样的配置,攻击者便无法事先计算这个cookie中的say值,于是攻击流量(代理型CC和低级发包型CC)便在302地狱无法自拔了。
大家可以看到,除了借用了md5这个函数外,其他的逻辑和上面的写法是一模一样的。因此如果可以的话,你完全可以安装一个nginx的计算散列的第三方模块来完成,可能效率会更高一些。
这段配置是可以被放在任意的location里面,如果你的网站有对外提供API功能的话,建议API一定不能加入这段,因为API的调用也是没有浏览器行为的,会被当做攻击流量处理。并且,有些弱一点爬虫也会陷在302之中,这个需要注意。
同时,如果你觉得set-cookie这个动作似乎攻击者也有可能通过解析字符串模拟出来的话,你可以把上述的通过header来设置cookie的操作,变成通过高端大气的js完成,发回一个含有doument.cookie=…的文本即可。
那么,攻击是不是完全被挡住了呢?只能说那些低级的攻击已经被挡住而来,如果攻击者必须花很大代价给每个攻击器加上webkit模块来解析js和执行
set-cookie才行,那么他也是可以逃脱302地狱的,在nginx看来,确实攻击流量和普通浏览流量是一样的。那么如何防御呢?下节会告诉你答
&请求频率限制
不得不说,很多防CC的措施是直接在请求频率上做限制来实现的,但是,很多都存在着一定的问题。
那么是哪些问题呢?
首先,如果通过IP来限制请求频率,容易导致一些误杀,比如我一个地方出口IP就那么几个,而访问者一多的话,请求频率很容易到上限,那么那个地方的用户就都访问不了你的网站了。
于是你会说,我用SESSION来限制就有这个问题了。嗯,你的SESSION为攻击者敞开了一道大门。为什么呢?看了上文的你可能已经大致知道了,因为
就像那个“红包拿来”的扬声器一样,很多语言或者框架中的SESSION是能够伪造的。以PHP为例,你可以在浏览器中的cookie看到
PHPSESSIONID,这个ID不同的话,session也就不同了,然后如果你杜撰一个PHPSESSIONID过去的话,你会发现,服务器也认可
了这个ID,为这个ID初始化了一个会话。那么,攻击者只需要每次发完包就构造一个新的SESSIONID就可以很轻松地躲过这种在session上的请
求次数限制。
那么我们要如何来做这个请求频率的限制呢?
首先,我们先要一个攻击者无法杜撰的sessionID,一种方式是用个池子记录下每次给出的ID,然后在请求来的时候进行查询,如果没有的话,就拒绝请
求。这种方式我们不推荐,首先一个网站已经有了session池,这样再做个无疑有些浪费,而且还需要进行池中的遍历比较查询,太消耗性能。我们希望的是
一种可以无状态性的sessionID,可以吗?可以的。
rewrite_by_lua '
local random = ngx.var.cookie_random
if(random == nil) then
random = math.random(999999)
local token = ngx.md5(&opencdn& .. ngx.var.remote_addr .. random)
if (ngx.var.cookie_token ~= token) then
ngx.header[&Set-Cookie&] = {&token=& .. token, &random=& .. random}
return ngx.redirect(ngx.var.scheme .. &://& .. ngx.var.host .. ngx.var.uri)
大家是不是觉得好像有些眼熟?是的,这个就是上节的完美版的配置再加个随机数,为的是让同一个IP的用户也能有不同的token。同样的,只要有nginx的第三方模块提供散列和随机数功能,这个配置也可以不用lua直接用纯配置文件完成。
有了这个token之后,相当于每个访客有一个无法伪造的并且独一无二的token,这种情况下,进行请求限制才有意义。
由于有了token做铺垫,我们可以不做什么白名单、黑名单,直接通过limit模块来完成。
http{ ... limit_req_zone $cookie_token zone=session_limit:3m rate=1r/s; }
然后我们只需要在上面的token配置后面中加入
limit_req zone=session_limit burst=5;
于是,又是两行配置便让nginx在session层解决了请求频率的限制。不过似乎还是有缺陷,因为攻击者可以通过一直获取token来突破请求频率限制,如果能限制一个IP获取token的频率就更完美了。可以做到吗?可以。
http{ ... limit_req_zone $cookie_token zone=session_limit:3m rate=1r/s; limit_req_zone $binary_remote_addr $uri zone=auth_limit:3m rate=1r/m; }
location /{ limit_req zone=session_limit burst=5; rewrite_by_lua '
local random = ngx.var.cookie_random
if (random == nil) then
return ngx.redirect(&/auth?url=& .. ngx.var.request_uri)
local token = ngx.md5(&opencdn& .. ngx.var.remote_addr .. random)
if (ngx.var.cookie_token ~= token) then
return ngx.redirect(&/auth?url=&.. ngx.var.request_uri)
'; } location /auth { limit_req zone=auth_limit burst=1; if ($arg_url = &&) { return 403; } access_by_lua '
local random = math.random(9999)
local token = ngx.md5(&opencdn& .. ngx.var.remote_addr .. random)
if (ngx.var.cookie_token ~= token) then
ngx.header[&Set-Cookie&] = {&token=& .. token, &random=& .. random}
return ngx.redirect(ngx.var.arg_url)
我想大家也应该已经猜到,这段配置文件的原理就是:把本来的发token的功能分离到一个auth页面,然后用limit对这个auth页面进行频率限制即可。这边的频率是1个IP每分钟授权1个token。当然,这个数量可以根据业务需要进行调整。
需要注意的是,这个auth部分我lua采用的是access_by_lua,原因在于limit模块是在rewrite阶段后执行的,如果在
rewrite阶段302的话,limit将会失效。因此,这段lua配置我不能保证可以用原生的配置文件实现,因为不知道如何用配置文件在
rewrite阶段后进行302跳转,也求大牛能够指点一下啊。
当然,你如果还不满足于这种限制的话,想要做到某个IP如果一天到达上限超过几次之后就直接封IP的话,也是可以的,你可以用类似的思路再做个错误页面,
然后到达上限之后不返回503而是跳转到那个错误页面,然后错误页面也做个请求次数限制,比如每天只能访问100次,那么当超过报错超过100次(请求错
误页面100次)之后,那天这个IP就不能再访问这个网站了。
于是,通过这些配置我们便实现了一个网站访问频率限制。不过,这样的配置也不是说可以完全防止了攻击,只能说让攻击者的成本变高,让网站的扛攻击能力变
强,当然,前提是nginx能够扛得住这些流量,然后带宽不被堵死。如果你家门被堵了,你还想开门营业,那真心没有办法了。
然后,做完流量上的防护,让我们来看看对于扫描器之类的攻击的防御。
这个是一个不错的waf模块,这块我们也就不再重复造轮子了。可以直接用这个模块来做防护,当然也完全可以再配合limit模块,用上文的思路来做到一个封IP或者封session的效果。
本文旨在达到抛砖引玉的作用,我们并不希望你直接单纯的复制我们的这些例子中的配置,而是希望根据你的自身业务需要,写出适合自身站点的配置文件。另外这样做,会对爬虫不友好,需要特别处理!
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致

我要回帖

更多关于 cc攻击怎么防御 的文章

 

随机推荐