通过日志分析防CC攻击和非法爬虫脚本,自动封禁非法IP,不影响SEO


编辑自动任务
crontab -e
检查进程
tail -f /var/log/cron
给予执行权限
chmod +x

Nginx日志设置(针对有CDN加速的主机)

nginx

http{


#网站做了CDN加速之后,需要改下Nginx的配置,才能记录到真实IP

map $http_x_forwarded_for  $clientRealIp {
        ""    $remote_addr;
        ~^(?P<firstAddr>[0-9\.]+),?.*$    $firstAddr;
}
log_format  cdn     '$clientRealIp - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer"  "$http_user_agent"';

#REMOTE_ADDR:节点IP
#HTTP_X_FORWARDED_FOR:网民电脑IP,代理IP1,代理IP2
#HTTP_X_REAL_FORWARDED_FOR:网民电脑IP
#HTTP_X_CONNECTING_IP:代理IP2

#防止CC

#注意如果采用UA方式识别,要选择非常少见的UA标识,否则会造成误杀。

#请求地址黑名单,default ""表示默认不分析
map $request_uri $r_agent {
        default "";
        ~*home.php\?mod=space&uid  $clientRealIp;  #Discuz的这个页面非常容易被爬虫扫描,用于撞库盗号
        ~*sec\.baidu\.com  $clientRealIp;  #以百度云观测为例,常常对网站发起短时间大量访问。
}
#UA黑名单和白名单,""表示白名单放行,不做分析,防止误杀。
map $http_user_agent $agent {
    default $r_agent;
    ~*X11 $clientRealIp;
    ~*Ubuntu $clientRealIp;
    ~*bingbot "";
    ~*yahoo "";
    ~*Googlebot "";
    ~*Baiduspider "";
    ~*Sogou "";
    ~*360Spider "";
}

#限制并发  名称设定为TotalConnLimitZone
limit_conn_zone $agent zone=TotalConnLimitZone:20m ;
limit_conn_log_level notice; 

#限制连接数  名称设定为ConnLimitZone
limit_req_zone $agent zone=ConnLimitZone:20m  rate=10r/s;
limit_req_log_level notice;

#IP黑名单
geo $clientRealIp $banip {
        default 0;
        include  blockip.conf;  #格式 xxx.xxx.xxx.xxx 1;
}


server
{
#记录CC拦截引起的503错误,方便后期检查,防止误杀。
location ~ /ErrorPages/503\.html$ 
    {
root /home/www/xxx/domain/xxx.com/web;
access_log /home/www/xxx/logs/err_503.log cdn; #access_log end  combined

    }

#识别IP黑名单,禁止访问
if ($banip = 1) {
          return 403;
    }

#以下可在伪静态里面设置
location ~ .*\.php$
    {
        limit_conn  TotalConnLimitZone  50;  #并发为 50 ,相当于最大开50个线程
        limit_req zone=ConnLimitZone burst=10 nodelay;   #最多 10 个排队, 由于每秒处理 20 个请求 + 10个排队,因此每秒最多刷新30次。

    }
#加入自己的静态目录,防止木马执行
location ~ /(attachment|upload|mov|center|static|zone|jkb|000|a\_img)/.*\.(php|php5|PHP|PHP5)?$ {
deny all;
}

}
}

日志生成后,进一步封禁非法IP

ban_ip.sh

#!/bin/bash
max=5                                                #我们设定的最大值,当访问量大于这个值得时候,封锁
confdir=/home/www/xxx/vhost/blockip.conf                #nginx封锁配置文件路径
logdir=/home/www/xxx/logs/err_503.log            #nginx访问日志文件路径
echo "">$confdir                                        #先把封锁配置文件中的内容清空
cat $logdir|awk '{print $1}'|sort|uniq -c|sort -n|while read line    #截取IP段
do
a=(`echo $line`)
if [ $a -ge $max ]                                        #比较每个访问IP是否大于设定的max值
then
 echo "${a[1]} 1;">>$confdir                            #把“deny IP;”语句写入封锁配置文件中
fi
done
amh lnmp vhost_reload lnmp2015

#iptables -I INPUT -p tcp --dport 80 -s ${a[1]} -j DROP         #把访问量大于设定值的IP加入的防火墙规则中,开CDN无效

day_log.sh

#!/bin/bash  
#设置日志文件存放目录  
LOG_HOME="/home/www/xxx/logs/"  
  
#备分文件名称  
LOG_PATH_BAK="$(date -d yesterday +%Y%m%d%H%M)".xxx.com-access.log 
  
#重命名日志文件  
mv ${LOG_HOME}/xxx.com-access.log ${LOG_HOME}/${LOG_PATH_BAK}.log
  
#向nginx主进程发信号重新打开日志   
if [ -f /usr/local/nginx-1.10/logs/nginx.pid ]; then
        kill -USR1 `cat /usr/local/nginx-1.10/logs/nginx.pid`
fi

/etc/logrotate.d/nginx 系统自带切割(推荐)

/home/www/xxx/logs/xxx.com-access.log {
daily
rotate 5
nocompress
sharedscripts
dateext
create
postrotate
    if [ -f /usr/local/nginx-1.10/logs/nginx.pid ]; then
        kill -USR1 `cat /usr/local/nginx-1.10/logs/nginx.pid`
    fi
endscript
}
00 04 * * *  /usr/sbin/logrotate -f /etc/logrotate.d/nginx