现在使用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="XXX@XXX.com"
# 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
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。