事情是这样发生的,由于商业竞争热烈,不免有些公司会涌现恶意竞争的征象,实在CC攻击算是最大略履行的一种DDoS种别攻击吧,在之前我所在的公司就遭受了一波商业竞争者发起的CC攻击。详细细节就不多说了,这种事情实在见怪不怪,来分享一下我的办理方案。
实在会有很多人说,像WAF什么的设备都可以有效抵挡住CC攻击,包括开源WAF也具备这个功能,有必要自己去写一个脚本来防护吗?
我的想法实在很大略,对付不知道怎么搭建开源WAF,或者资金投入并不大的公司而言,能有一个大略防御办理方案,这是我写这篇文章想实现的一个意义,也算是对这个职位的一些回馈吧,当然实在写防御脚本基本是每一位安全职员都会而且很闇练的一个技能,在这里我就先抛砖引玉,分享一下关于防CC脚本的设计思路。

首先要给读者遍及一下什么是CC攻击?
CC(ChallengeCoHapsar,寻衅黑洞)攻击是DDoS攻击的一种类型,利用代理做事器向受害做事器发送大量貌似合法的要求。CC根据其工具命名,攻击者利用代理机制,利用浩瀚广泛可用的免费代理做事器发动DDoS攻击。许多免费代理做事器支持匿名模式,这使追踪变得非常困难。
CC攻击的事理是什么?
CC攻击的事理便是攻击者掌握某些主机一直地发大量数据包给对方做事器造成做事器资源耗尽,一贯到宕机崩溃。CC紧张是用来攻击页面的,每个人都有这样的体验:当一个网页访问的人数特殊多的时候,打开网页就慢了,CC便是仿照多个用户(多少线程便是多少用户)一直地进行访问那些须要大量数据操作(便是须要大量CPU韶光)的页面,造成做事器资源的摧残浪费蹂躏,CPU永劫光处于100%,永久都有处理不完的连接直至就网络拥塞,正常的访问被中止。
CC攻击的特色是什么?
1. 业务流量激增
2. 访问日志持续大量增长
3. 大量相同来源IP访问同一域名
基于以上先容,我们来思考一下如何限定CC攻击。
首先不管是开源的WAF还是商业的WAF,CC攻击的防御大多都是阻断,而非扔进黑洞,这两者有什么差异呢?阻断大体是返回403相应码,使得本应正常返回的包返回403页,举个例子相称于本该当返回1M大小的包返回1K,这样做能很大程度的减轻网络压力以及做事器处理压力,能够减轻CC攻击所带来的影响。
我们是存在WAF的,但是为什么有WAF的防CC攻击,还要自行开拓防CC脚本,在这里有一个问题须要思考的是,如果做事器在云端,网络走的是云真个按量计费办法,就算你一直的返回403,一样司帐费,对付一个攻击者而言,只要你存在丢失他就已经成功了,纵然这个丢失对你来说微不足道,但是CC的本钱并不高乃至可以说是没有本钱,比耐心的话可能末了你付出的会更多。
抱着这个心态我研究了一下怎么能直接让他的CC打不进来。
首先来看一下整体的一个思路:
攻击者发起CC攻击,由于域名在云环境,以是会走云计费通道进入到代理做事器,通过代理做事器转发到运用做事器,由运用做事器返回相应要求内容给代理做事器,代理做事器通过计费通道给出相应。
那么按照这个流程,综合考虑我们的目的,就须要在代理做事器上动手让非正常的要求无法通过,如下:
如此出口计费CC攻击要求不会返回给攻击者,也就不会扣除流量用度。
那么怎么判断要求是否为CC?
首先Nginx有本身的功能参数可以做到防CC,上面已经阐述过CC攻击的特色,根据特色我们可以利用下面这个参数
limit_req_zone $binary_remote_addr zone=one:10m rate=300r/s;limit_req zone=one burst=30;
意思是同一IP每秒要求限定为300次,持续30秒的要求将被阻断返回503
返回503和403有什么差异呢?单从这一点出发是没有任何差异的,以是须要用到下面这个模块来帮助我们连续开拓。
Nginx有很多强大的模块,下面为大家先容一个模块,记得编译安装时加载~
ngx_log_if模块,详细信息见https://github.com/cfsego/ngx_log_if
这个模块的功能是筛选日志,用到这个模块的逻辑在于将503日志中的源IP筛选出来,加到防火墙中阻断。
逻辑中涉及的问题是为何每分钟只加入第一条503日志对应的IP,而非做出判断后一起加入防火墙阻断,实在这点是考虑到并发量大判断逻辑会加严惩事器负载的问题,以是还是一条一条加吧,当然这里也可以优化一下。
首先定义的这天记格式,我们按照nginx默认的日志格式来,如果这里有不理解的朋友们可以搜一下nginx日志默认格式。
access_log /var/log/nginx/503/errortest.log;
接下来用到的是awk筛选出日志中的ip,这里如果有不理解awk的朋友可以参考https://www.cnblogs.com/xudong-bupt/p/3721210.html。
status=`awk -v i=$i -F ' ' 'NR==i{print $9}' /var/log/nginx/503/errortest.log`
做出判断
if [ \"大众$status\"大众 = '503' ];thenip_503=`awk -v i=$i -F ' ' 'NR==i{print $1}' /var/log/nginx/503/errortest.log`
添加进防火墙
sed -i \公众6 i-A INPUT -s $ip_503/32 -j DROP\"大众 /etc/sysconfig/iptables
整体考虑到503日志为空以及非503状态的IP记录,做出以下脚本
#!/bin/bashi=1while :dostatus=`awk -v i=$i -F ' ' 'NR==i{print $9}' /var/log/nginx/503/errortest.log`if [ \"大众$status\"大众 = '503' ];thenip_503=`awk -v i=$i -F ' ' 'NR==i{print $1}' /var/log/nginx/503/errortest.log`echo $ip_503sed -i \"大众6 i-A INPUT -s $ip_503/32 -j DROP\"大众 /etc/sysconfig/iptablesecho \"大众\公众 > /var/log/nginx/503/errortest.logservice iptables restartnginx -s reloadbreakelif [ `cat /var/log/nginx/503/errortest.log|awk -F ' ' 'NR==i{print $9}' /var/log/nginx/503/errortest.log`=\"大众\"大众 ];thenbreakelsei=$[i+1]fidone
之后利用crontab每分钟运行一遍或者更短韶光运行这个脚本就可以了。