参考:https://blog.51cto.com/tsoagta/1710421

我们公司网站爬虫爬取频次太高,查阅资料后简单写了一个定时获取ip,然后封禁ip 的脚本。

主要思路是:读取nginx的access.log 可以获取ip访问信息,将访问超过多少次的ip存入到blockip.conf,由nginx.conf引用blockip.conf达到封ip目的。

1、liunx 执行命令,可查看ip访问信息

awk '{print $1}' /usr/local/nginx/logs/access.log |sort |uniq -c|sort -n

执行结果看图,图上可以看出ip的访问情况

nginx定时封ip防爬虫

2、基本的nginx操作配置不写了,查下nginx相关资料了解下

这里贴下定时启动的脚本代码,其中blockip.conf,tempip,blocktemp需要自己创建空文件,并放入你的nginx目录下,我的目录是

/usr/local/nginx/conf 

blockip.conf需要在nginx.conf中引用。引用方法:include blockip.conf

nginx定时封ip防爬虫

-----------------------------------脚本开始------------------------------------------------------

#!/bin/bash
max=7500                                                       #ip访问超过15000次封禁
confdir=/usr/local/nginx/conf/blockip.conf        #存放封锁ip的文件
logdir=/usr/local/nginx/logs/access.log            #nginx日志文件
tempip=/usr/local/nginx/conf/tempip                #存放nginx日志中访问超1万5的ip的临时文件,有重复值
blocktemp=/usr/local/nginx/conf/blocktemp     #备份blockip.conf的临时文件
echo "---开始清空blocktemp和tempip文件---"
>$blocktemp 
>$tempip 
echo "---开始备份blockip.conf并读取nginx日志ip文件---"
cat $confdir >>$blocktemp                     #开始备份
cat $logdir | awk '{print $1}' |sort |uniq -c|sort -n |while read line  #读取nginx日志文件的ip信息
do #循环开始
 a=(`echo $line`)
 if [ $a -ge $max ]                                    #if判断 a大于max时执行echo
 then 
  echo "deny ${a[1]};">>$tempip              #将nginx日志文件的ip写入到temp中
 fi 
done #循环结束
cat $blocktemp >>$tempip                      #将blocktemp内容读入到tempip
>$confdir                                                 #清空封锁ip的文件
cat $tempip | sort|uniq>>$confdir            #过滤重复ip,取独立ip放入blockip.conf
echo "---符合封禁的ip存入封禁文件 ---" 
echo "---开始判断重启nginx---" 
notice=0                                                   #通知重启0通知, 1不通知
reload=0                                                  #是否重启0不重启,1重启
while read conflog                                   #开始判断有新的超过次数的ip,是否通知nginx重启
do 
 echo '---读取最新ip:conflog='${conflog}      
 while read line                                       #读取blocktempip,和tempip比对,有新ip则通知重启
 do 
   echo '---已封禁ip:line='${line}
   if [ "$conflog" = "$line" ]                      #判断ip相等 
   then 
     notice=1
     echo '---ip已存在notice='${notice}'----' 
   else
     v=0 #随便写了一行,防止无内容报错 
     echo '---ip不相同---'
   fi 
 done < ${blocktemp} 
 if [ "$notice" -eq 0 ]                                 #notice=0通知nginx重启,否则notice置为0继续循环
 then 
   reload=1
   echo '---通知nginx重启notice='{$notice}'---'
 else
   notice=0 
   echo '---不通知nginx重启---'
 fi 
done <${tempip}                              #循环结束
if [ "$reload" -eq 1 ]                          #reload=1重启nginx
then 
 echo '---正在重启nginx,reload='${reload}'---' 
 /usr/local/nginx/sbin/nginx -s reload
 echo '---nginx重启完毕---'
else
 v=0 #随便写了一行,防止无内容报错 
 echo '---不重启reload='${reload}'---' 
fi                                                      #脚本结束
-----------------------------------------------------结束---------------------------------

3、如果要定时解封ip参考文章最上面的那个链接

查看定时器,定时器定时启动脚本文件,封ip

crontab -l   

*/30 * * * * /usr/local/nginx/conf/blockip.sh  # 每半小时定时启动,判断nginx访问次数超过7500的ip,封禁ip

编辑定时器

crontab -e

可自行设置定时启动时间

4、注意事项:代码粘贴后,保存为blockip.sh文件放入nginx目录/usr/local/nginx/conf/下。

chmod +x blockip.sh 赋予文件root权限

./blockip.sh  手动执行脚本文件

如果执行报错

syntax error: unexpected end of file

在window环境下编写的,然后传到linux服务器上的,doc下的文本内容格式和unix下的格式有所不同,比如dos文件传输到unix系统时,会在每行的结尾多一个^M结束符。

参考解决方式:https://blog.csdn.net/u013948858/article/details/79637851

其他解决方式:自己在liunx上用vi命令手打,哈哈

其他错误,类似下面这样的,一般是代码有问题。

syntax error near unexpected token `fi'

代码要规范,例如 if  [ $a = $b ]    [ ] 括号前后应都有空格等

变量赋值,例如notice=0 等号两边不可以留空格

参考:https://www.cnblogs.com/yangyanfei/p/6386831.html

网上关于脚本命令的资料很多,这里简单解释下。

blockip.sh 的源代码放一份上来,亲测可用。不能跑起来的看下我上面说的几个注意事项。

5、该代码不用频繁启动nginx,只有新的访问次数超过规定值的ip才会重启nginx,如果一直是那几个已经被存入blockip.conf的ip

则不会重新启动nginx
6、附图blockip.conf、tempip、blocktemp的内容示例。nginx定时封ip防爬虫

7、 blockip.sh文件下载

后面添加百度网盘链接

相关文章: