宝塔Nginx+Cloudflare+Shell实现识别CC攻击IP 并记录拉黑功能
现在使用NGINX的人越来越多,而且配合CLOUDFLARE来使用防御功能的人也越来越多。目前经常有人说正被CC攻击困扰。
CC攻击的请求就是制造大量访问请求让你服务器处理不过来,从而无法对外服务。
既然知道原理,那么我们来针对性的,把日志中的攻击IP识别出来,并提交给防火墙去拉黑处理
这里我们最好别用自己服务器的防火墙去处理这些拉黑IP的操作,因为这样一来服务器虽然把这些IP拉黑,但是实际攻击者还是到了你门外,只是被挡在外面而已,在砸门的过程,还是需要消耗你服务器资源。
因此我们这里配合业界鼎鼎大名的CLOUDFLARE,CF使用ANYCASE网络,天生无惧DDOS,剩下的CC,因为CF有个IP防火墙功能,因此可以通过批量提交IP数据给CF从而让CF的防火墙将这部分访问你服务器的恶意攻击IP屏蔽。
1、首先配置网站使用CLOUDFLARE
这个就不累述,可以直接官网注册使用,使用DNS接入,也可以使用我们的https://cdn.bnxb.com提供的CNAME接入方式
2、配置宝塔的NGINX识别真实访客IP
这里我们使用宝塔,因为这个配置比较简单,其实其他NGINX原理是一样的。
为什么需要识别真实访客IP,因为加上CF的CDN后,访客的访问是这样的过程:访客-》CDN->你的服务器 这样在你服务器看来跟他产生握手连接的都是CDN的IP
幸好CF免费提供一个HEADER标头,会将访客->CDN 这一步的访客IP记录下来,并传递到你的服务器,这个标头是HTTP_CF_CONNECTING_IP
之前我们在https://www.bnxb.com/php/27592.html
这里介绍过,过程有部分一样
NGINX配置获取CloudFlare 下的访客真实IP并记录到日志
需要修改NGINX的配置文件,宝塔的nginx配置文件存放位置与一般nginx不一样,宝塔存放nginx配置文件位置:/www/server/nginx/conf/nginx.conf;一般nginx的配置文件位置:/usr/local/nginx/conf/nginx.conf。
在
http { }
部分增加
log_format main '$HTTP_CF_CONNECTING_IP [$fmt_localtime] "$request" ' '$status $body_bytes_sent "$http_referer" ' '$http_user_agent $request_time'; map $host $fmt_localtime { default ''; } log_by_lua_block { ngx.var.fmt_localtime = ngx.localtime(); }
主要是为了方便时间的格式阅读,这里把Nginx默认的日志显示的时间格式也给改了。
然后在网站记录的日志定义使用main这个日志格式,比如:
access_log /www/wwwlogs/www.bnxb.com.log main;
可以参考https://www.bnxb.com/nginx/27513.html
3、配置SHELL脚本来执行读取攻击IP信息,并记录入某个TXT文件
#/bin/bash #日志文件 logfile=/www/wwwlogs/ last_minutes=1 #开始时间1分钟之前(这里可以修改,如果要几分钟之内攻击次数多少次,这里可以自定义) start_time= date +"%Y-%m-%d %H:%M:%S" -d '-1 minutes' echo $start_time #结束时间现在 stop_time=`date +"%Y-%m-%d %H:%M:%S"` echo $stop_time cur_date="`date +%Y-%m-%d`" echo $cur_date #过滤出单位之间内的日志并统计最高ip数 tac $logfile/bnxb.com.log | awk -v st="$start_time" -v et="$stop_time" '{t=substr($2,RSTART+14,21);if(t>=st && t<=et) {print $0}}' | awk '{print $1}' | sort | uniq -c | sort -nr > $logfile/log_ip_top10 ip_top=`cat $logfile/log_ip_top10 | head -1 | awk '{print $1}'` ip=`cat $logfile/log_ip_top10 | awk '{if($1>60)print $2}'` # 单位时间[1分钟]内单ip访问次数超过60次的ip记录入black.log for line in $ip do echo $line >> $logfile/black.txt echo $line # 这里还可以执行CF的API来提交数据到CF防火墙 done
这样就获得了一份black.txt文件,这个文件一行一个IP,可以直接通过我们的cdn.bnxb.com的批量导入防火墙记录功能,将这个记录中的IP全部屏蔽访问
或者你也可以让服务器通过CLOUDFLARE的API将这些攻击IP封杀
代码修改完如下:
#/bin/bash # CF邮箱CFEMAIL="[email protected]" # Cloudflare API key,通过官方获取 CFAPIKEY="xxxxxxxxxxxxxxxx" # zoneid 每个域名都有一个独立的ID zoneid="xxxxxxxxxxxxxxxxxxxx" #日志文件 logfile=/www/wwwlogs/ last_minutes=1 #开始时间1分钟之前(这里可以修改,如果要几分钟之内攻击次数多少次,这里可以自定义) start_time= date +"%Y-%m-%d %H:%M:%S" -d '-1 minutes' echo $start_time #结束时间现在 stop_time=`date +"%Y-%m-%d %H:%M:%S"` echo $stop_time cur_date="`date +%Y-%m-%d`" echo $cur_date #过滤出单位之间内的日志并统计最高ip数 tac $logfile/bnxb.com.log | awk -v st="$start_time" -v et="$stop_time" '{t=substr($2,RSTART+14,21);if(t>=st && t<=et) {print $0}}' | awk '{print $1}' | sort | uniq -c | sort -nr > $logfile/log_ip_top10 ip_top=`cat $logfile/log_ip_top10 | head -1 | awk '{print $1}'` ip=`cat $logfile/log_ip_top10 | awk '{if($1>60)print $2}'` # 单位时间[1分钟]内单ip访问次数超过60次的ip记录入black.log for line in $ip do echo $line >> $logfile/black.txt echo $line curl -s -X POST "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules" -H "X-Auth-Email: $cfemail" -H "X-Auth-Key: $cfapikey" -H "Content-Type: application/json" --data '{"mode":"block","configuration":{"target":"ip","value":"'$line'"},"notes":"CC attatck"}' done
注意,我这里已经改成使用CF的全局防火墙,也就是提交的IP封锁,将对账户下全部域名都有效。
如果只想对本域名有效,就将
https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules
改成
https://api.cloudflare.com/client/v4/zones/$zoneid/firewall/access_rules/rules
- 最新评论