当前位置: 代码网 > 服务器>服务器>Linux > Nginx日志的自动封异常ip和解封脚本方式

Nginx日志的自动封异常ip和解封脚本方式

2025年06月17日 Linux 我要评论
nginx日志的自动封异常ip和解封脚本设计思路1.每五分钟统计一次日志异常ip2.被封的异常ip一小时后自动解封3.尽量减少对nginx的重启,完成全部判断后再去考虑是否重启nginx进程4.黑名单

nginx日志的自动封异常ip和解封脚本

设计思路

1.每五分钟统计一次日志异常ip

2.被封的异常ip一小时后自动解封

3.尽量减少对nginx的重启,完成全部判断后再去考虑是否重启nginx进程

4.黑名单ip采用非iptable,使用将deny+ip语句加入blockip.conf中(后期解封比较好处理),并且在上述语句块中nginx.conf中include此文件(blockip.conf可以根据需要放入http 语句块、server 语句块、location 语句块)

5.blockip.conf设计为deny + ip + ;号 + #号 + 时间戳(五个可以分割的值)

程序流程图

程序有两个脚本组成

1.python写的blockip.conf中的ip根据时间戳去解封(简称sub),返回一个是够要重启的信号给shell

2.shell写的根据最近五分钟访问超过100次(生产环境建议改成500-1000)的ip,加入到blockip.conf,根据是否有新ip加入和sub返回值判断nginx是否需要重启

 

脚本

1.nginx_black.sh

#/bin/bash

#/usr/local/python3.9/bin/python3   /root/ai2/sub_oldip.py
reload1=$(/usr/local/python3.9/bin/python3   /root/ai2/sub_oldip.py)   ##调用python脚本,是否返回重启
reload2=nores               ##默认值不重启
#echo "$reload1"
sleep 1s
my_log=/root/ai2/log.txt
#logfile=/root                     
logfile=/usr/local/tengine/logs   ##nginx日志


confdir=/usr/local/tengine/conf/blockip.conf     ##nginx的blockip.conf目录
time_sjc=$(date -d  now +%s)                     ##获取时间戳
my_log_date=`date +"%y-%m-%d %h:%m:%s"`               ##日志记录时间
start_time=`date -d "-5min" +"%h:%m:%s"`         ##start_time-stop_time的值为nginx统计日志的时间为5分钟
#echo "$start_time"
stop_time=`date +"%h:%m:%s"`
#echo "$stop_time"

#过滤出单位之间内的日志并统计最高ip数,请替换为你的日志路径
tac $logfile/host.access.log | awk -v st="$start_time" -v et="$stop_time" ' {t=substr($4,rstart+14,21);if(t>=st && t<=et) {print $0}}' |awk '{print $1}' |grep -i -v -e "google|yahoo|baidu|msnbot|feedsky|sogou" |sort | uniq -c | sort -nr |head -20> $logfile/log_ip_top20

ip=`cat $logfile/log_ip_top20 | awk '{if($1>50)print $2}'`    ##统计排名前10的ip访问次数,100次以上加入黑名单
ip_tmp=`cat $logfile/log_ip_top20 | awk '{if($1>50)print $2}' |head -1`    ##用于if判断去首行,多行会报错
##echo "$ip"

if [ "$ip_tmp" = "" ];then    ##如果ip_tmp为空,打印没有黑名单ip
     echo "$my_log_date no black ip " >> $my_log
else
#      for line in $ip                        ##按行读取黑名单ip,按格式加入到blockip.conf和日志
#         do
#         echo "deny $line ; # $time_sjc" >> $confdir
#         echo "$my_log_date deny $line " >> $my_log
#         done
#      #/usr/local/tengine/sbin/nginx -s reload
#      reload2=res                             ##赋值reload2 需要重启

      for line in $ip                        ##按行读取黑名单ip,按格式加入到blockip.conf和日志
         do
           if [ `grep -c "$line" $confdir` -eq '0' ];then
             echo "deny $line ; # $time_sjc" >> $confdir
             echo "$my_log_date deny $line " >> $my_log
             reload2=res
           else
             #line_uptime="deny $line ; # $time_sjc"
             #sed -e "s/.*'$line'.*$/$line_uptime/g" $confdir
             sed  -i /"$line"/d "$confdir"
             echo "deny $line ; # $time_sjc" >> $confdir
             echo "$my_log_date $line is in conf" >> $my_log
           fi
         done

fi
#echo  "$reload1"
#echo  "$reload2"

##如果reload1或者reload2都为res则重启,否则不重启;
if [ "$reload1" = "res" ] || [ "$reload2" = "res"  ];then
  /usr/local/tengine/sbin/nginx -s reload          ##替换自己的nginx环境变量
  echo "$my_log_date nginx  reload"  >> $my_log
else
  echo "$my_log_date nginx no reload"  >> $my_log
fi

2.sub_oldip.py

#!/usr/bin/python3
# chenzhenhua
import string,time,os
time_now = int(time.time())
log_time = time.strftime("%y-%m-%d %h:%m:%s", time.localtime())
dir = "/usr/local/tengine/conf/blockip.conf"                       ##修改自己的blockip.conf地址
f_log = open("/root/ai2/log.txt","a")                ##本程序日志

with open(dir,"r",encoding="utf-8") as f:     ##读取blockip.conf
    lines = f.readlines()
    #print(lines)
with open(dir,"w",encoding="utf-8") as f2:    ##把日期小于3600的ip重新写入回blockip.conf
    for line in lines:
        if line == '' or line == '\n':
            continue
        else:
            old_time = int(line.strip().split()[4])    ##取第五个值,然后和现在时间挫进行对比
            time_sjc = time_now -old_time
            ipadd = line.split()[1]
            if time_sjc > 3600:              ###根据要求调整秒数,秒数大于次值不再重新写入blockip.conf
                line_log = line.strip().split()[1]
                f_log.write("%s sub %s \n"%(log_time,line_log )  )
                continue
            else:
                f2.write(line)

f2.close()
with open(dir,"r",encoding="utf-8") as f3:
    lines2 = f3.readlines()
f3.close()
#time.sleep(0.5)
if lines2 == lines:                                      ###对比新、老blockip.conf是否一致
    f_log.write("%s py over retrun nores \n" % (log_time))
 #   time.sleep(0.5)
    print('nores')                                       ##返回shell不要求重启
else:
    f_log.write("%s py over retrun res \n" % (log_time))
 #   time.sleep(0.5)
    print('res')                                         ##返回shell不要求重启
f_log.close()

测试

加入每五分钟执行一次

[root@zabbix ~]# crontab -e
*/5 * * * * /root/ai2/nginx_black.sh

其他服务器进行ab测试,没有的百度安装

 ab -c 10 -n 100 http://172.16.3.89/test2/

再回到本机进行查看,发现已经加入黑名单中

[root@zabbix logs]# tail -f /root/ai2/log.txt 
2021-08-14 18:15:02 nginx no reload
2021-08-14 18:20:01 py over retrun nores 
2021-08-14 18:20:02 no black ip 
2021-08-14 18:20:02 nginx no reload
2021-08-14 18:25:01 py over retrun nores 
2021-08-14 18:25:02 no black ip 
2021-08-14 18:25:02 nginx no reload
2021-08-14 18:30:01 py over retrun nores 
2021-08-14 18:30:02 deny 192.168.200.244 
2021-08-14 18:30:02 nginx  reload
[root@zabbix logs]# cat /usr/local/tengine/conf/blockip.conf 
deny 192.168.200.244 ; # 1628937002

我们再去刚才ab测试服务器进行curl查看,已经返回403

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com