平时我们的小网站会时不时遭受到爆发式的access日志增长,经过我们查看,很多时候都是同一个ip在搞怪,或许ddos,或许cc,或许扫服务器,或许爬虫,大量的请求会占用我们的服务器资源,于是我就写个脚本每一分钟盯着,帮我们时刻去封禁可疑ip。
当然我们可以使用nginx的http_limit_conn和http_limit_req模块来防御,本篇章以shell脚本为主要点。
ps:本人小白,刚刚学习到这些,试着写了一下,若思路复杂,技术错误,大佬勿喷,作为学生必定虚心请教,恳请大佬赐教。
一.首先我们要明确,脚本监测的是nginx的access日志文件,并且筛选出可疑ip写入conf文件
#!/usr/bin/env bash
#Decsription:access日志监测脚本
#Author: shuangyueban
#Created Time: 2022/04/22
set -e
#脚本语句返回非零,立即停止退出,避免一错再错,酿成大错。
read -p "请输入需要监测access文件的绝对路径: " Path_one
if [ ! -f $Path_one ];then
echo "文件不存在"
exit 1
fi
#输入我们监测的access文件的绝对路径,并且监测文件是否存在
read -p "请输入deny-conf文件的绝对路径: " Path_two
if [ ! -f $Path_two ]
then
echo "文件不存在"
exit 1
fi
for (( ; ; ))
do
#写个无限循环,全天候监测
if [ -s $Path_one ];then
cat $Path_one > middle.log
cat /dev/null > $Path_one
#把日志写出到middle.log中间件,删除原文件内容。
#middle将拿去做判断,到时保留有用信息会写入到新的以日期命名的access日志。
cat middle.log | awk ' {print $1} ' |sort|uniq -c | awk '{{ print $2 "=" $1 }}' > ip.txt
#通过筛选排序计数,结果会记录到ip.txt文件中,其表现为举例“192.168.1.1=30”
#uniq -c 会统计重复ip并且显示次数,我这里以等号连接
cat ip.txt | while read badip
do
IP=$( echo $badip | awk -F= '{ print $1 }')
NUM=$( echo $badip | awk -F= '{ print $2 }')
if [ $NUM -gt 100 ] ;then
if [ $(cat -n $Path_two | grep "${IP}" | wc -l ) -eq 0 ];then
#先判断是否已经记录过,如果记录过则不再重复。
echo "deny ${IP};" >> $Path_two
#此处重新加载nginx,(请填写)。
fi
cat middle.log | grep "${IP}" | tail -n 3 >>`date "+%Y_%m_%d"`_access.log
#爆发式信息挑几条写入最后日志即可。
sed -i "/${IP}/d" middle.log
#删除爆发式没用信息。
fi
done
cat middle.log >>`date "+%Y_%m_%d"`_access.log
#middle文件操作完毕,剩余写入以日期为名的最终access文件
fi
sleep 1m
#休眠一波,这种脚本基本不会占服务器资源。
done
二.需要注意的几点:
1.必须要有access.log文件和关于deny的conf文件
2.脚本会在当前目录下自动生成ip.txt和middle.log文件,不用理会,做个中间件而已
3.脚本会自动生成一个以日期命名的最终access.log文件,即使到了第二天,也是会自动生成新的。
4.代码第45行需要填写
5.关于deny的conf文件记得包含一下
ps:本人小白,刚刚学习到这些,试着写了一下,若思路复杂,技术错误,大佬勿喷,作为学生必定虚心请教,恳请大佬赐教。