参考: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的访问情况
2、基本的nginx操作配置不写了,查下nginx相关资料了解下
这里贴下定时启动的脚本代码,其中blockip.conf,tempip,blocktemp需要自己创建空文件,并放入你的nginx目录下,我的目录是
/usr/local/nginx/conf
blockip.conf需要在nginx.conf中引用。引用方法:include blockip.conf
-----------------------------------脚本开始------------------------------------------------------
#!/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的内容示例。
7、 blockip.sh文件下载
后面添加百度网盘链接