防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' ];then
ip_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/bash
i=1
while :
do
status=`awk -v i=$i -F ' ' 'NR==i{print $9}' /var/log/nginx/503/errortest.log`
if [ "$status" = '503' ];then
ip_503=`awk -v i=$i -F ' ' 'NR==i{print $1}' /var/log/nginx/503/errortest.log`
echo $ip_503
sed -i "6 i-A INPUT -s $ip_503/32 -j DROP" /etc/sysconfig/iptables
echo "" > /var/log/nginx/503/errortest.log
service iptables restart
nginx -s reload
break
elif [ `cat /var/log/nginx/503/errortest.log|awk -F ' ' 'NR==i{print $9}' /var/log/nginx/503/errortest.log`="" ];then
break
else
i=$[i+1]
fi
done

之后使用crontab每分钟运行一遍或者更短时间运行这个脚本就可以了。

发布了84 篇原创文章 · 获赞 46 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/gufenchen/article/details/101034941