shell脚本自动封禁和解IP

要求

1、每分钟检查一次日志/data/app/nginx/logs/access_json.log。格式如下

2、把一分钟内访问次数大于100的给封禁

3、封禁的日志记录到文件

4、每隔30分钟检查一次被封IP,将符合条件(访问次数小于5次)的解封

5、解封的IP也记录到文件

实现

封禁IP

查找出所有1分钟之前的日志

grep  `date  "+%FT%H:%M" -d "-1 min"` /data/app/nginx/logs/access_json.log

统计日志中每个hostIP出现的次数

awk -F'"' '{IPCOUNT[$12]++}END{for(i in IPCOUNT){print i,IPCOUNT[i]}}' /data/app/nginx/logs/access_json.log

将上边两条语句联合起来使用即得到想一分钟内IP的访问次数并保存至指定文件

grep  `date  "+%FT%H:%M" -d "-1 min"` /data/app/nginx/logs/access_json.log | awk -F'"' '{IPCOUNT[$12]++}END{for(i in IPCOUNT){print i,IPCOUNT[i]}}' >/tmp/ipcount.tmp

取出1分钟内访问次数大于50IP

abnormalIp=`awk '$2>50{printf $1}' /tmp/ipcount.tmp `

使用for循环添加iptables规则

for i in $abnormalip;do

echo   $abnormalip >>/tmp/iplimits.txt

iptables -A INPUT -p tcp  -s $abnormalip  --dport 80 -j REJECT

done

解IP 

由于iptables规则中第一个地段记录了对应规则所匹配的请求数量所以可以依据此作为解封IP的依据。

取出pkts小于5IP

iptables -vnL INPUT|sed '1d'|awk '$1<5{print $8}' >/tmp/ip_good.tmp

脚本如下

#!/bin/bash
#将1分钟之内时间赋值给变量t1
t1=`date  "+%FT%H:%M" -d "-1 min"`
blockip() {
#一分钟内IP的访问次数并保存至指定文件
grep  $t1  /data/app/nginx/logs/access_json.log | awk -F'"' '{IPCOUNT[$12]++}END{for(i in IPCOUNT){print i,IPCOUNT[i]}}' >/tmp/ipcount.tmp

#取出1分钟内访问次数大于50的IP
awk '$2>50{printf $1}' /tmp/ipcount.tmp >/tmp/ip_bad.tmp

#计算IP的数量
n=`wc -l /tmp/ip_bad.tmp |awk '{print $1}'`

#当n数值大于0是代表有访问次数频繁的可疑IP此时执行封禁IP
abnormalIp=`awk '{printf $1}' /tmp/ip_bad.tmp `
if [ $n -gt 0 ];then 
    for i in $abnormalip;do
        echo   $abnormalip >>/tmp/iplimits.txt
        iptables -A INPUT -p tcp  -s $abnormalip  --dport 80 -j REJECT
    done
fi
}

unblockip() {
#首先将ip请求次数小于5次的记录到一个白名单/tmp/ip_good.tmp文件中
iptables -vnL INPUT|sed '1d'|awk '$1<5{print $8}' >/tmp/ip_good.tmp
n=`wc -l /tmp/ip_good.tmp |awk '{print $1}'`

normalIp=`awk '{printf $1}' /tmp/ip_good.tmp `
if [ $n -gt 0 ];then
        for i in $normalip;do
                echo   $abnormalip >>/tmp/iplimits.txt
                iptables -D INPUT -p tcp  -s $normalip  --dport 80 -j REJECT
        done
fi

}
#取出当前时间的分钟数
t=`date +%M`
#当分钟数为00或者30的时候执行解封IP操作,其他时间(包括00和30)执行封禁IP操作
if [ $t == "00" ] || [ $t == "30" ]
then
    unblockip
    blockip
else
    blockip
fi
原文地址:https://www.cnblogs.com/wxxjianchi/p/13630999.html