需求: 根据web服务器上的访问日志,把一些请求量非常高的ip给拒绝掉! 分析: 我们要做的,不仅是要找到哪些ip请求量不合法,并且还要每隔一段时间把之前封掉的ip(若不再继续请求了)给解封。 所以该脚本的关键点在于定一个合适的时间段和阀值。 比如, 我们可以每一分钟去查看一下日志,把上一分钟的日志给过滤出来分析,并且只要请求的ip数量超过50次那么就直接封掉。 而解封的时间又规定为每半小时分析一次,把几乎没有请求量的ip给解封!参考日志文件:
我写的线上跑的脚本如下:
#! /bin/bashlogfile=/home/logs/client/access.logd1=`date -d "-1 minute" +%H:%M`
d2=`date +%M`
ipt=/sbin/iptables
ips=/tmp/ips.txt
block(){
grep "$d1:" $logfile|awk '{print $1}' |sort -n |uniq -c |sort -n >$ips
for ip in `awk '$1>50 {print $2}' $ips`; do
$ipt -I INPUT -p tcp --dport 80 -s $ip -j REJECT
echo "`date +%F-%T` $ip" >> /tmp/badip.txt
done
}
unblock(){
for i in `$ipt -nvL --line-numbers |grep '0.0.0.0/0'|awk '$2<15 {print $1}'|sort -nr`; do
$ipt -D INPUT $i
done
$ipt -Z
}
if [ $d2 == "00" ] || [ $d2 == "30" ]; then
unblock
block
else
block
fi
0
假如web服务器为apache服务。
#!/bin/bash
## This script is for judging if ip forbidden or permitted to access the website.
## Writed by Louis on 2014/08/31 15:00
file=/usr/local/apache2/logs/access_log
conf=/usr/local/apache2/conf/httpd.conf
touch /usr/local/apache2/conf/ips
ips=/usr/local/apache2/conf/ips
while :; do
awk '{print $1}' $file|grep '^[0-9]'|sort|uniq -c|sort -nr|awk '$1>50 {print $2}' > $ips
sleep 60
done
while :; do
minip=`awk '{print $1}' $file|grep '^[0-9]'|sort|uniq -c|sort -nr|awk '$1<2 {print $2}'`
for j in $minip; do
if grep -oq $j $ips; then
sed -i "/$minip/d" $ips
fi
done
sleep 1800
done
if ! grep -q '/usr/local/apache2/conf/ips' $conf;then
sed -i '161 a\ Deny from /usr/local/apache2/conf/ips' $conf|sed -i 's/"//g' $conf
fi
思路:给apache服务配置文件添加Deny from /usr/local/apache2/conf/ips,其中文件/usr/local/apache2/conf/ips为高请求的IP,只需要按照要求定时更新该IP列表即可。
#!/bin/bash
## This script is for judging if ip forbidden or permitted to access the website.
## Writed by Louis on 2014/08/31 15:00
file=/usr/local/apache2/logs/access_log
conf=/usr/local/apache2/conf/httpd.conf
touch /usr/local/apache2/conf/ips
ips=/usr/local/apache2/conf/ips
while :; do
awk '{print $1}' $file|grep '^[0-9]'|sort|uniq -c|sort -nr|awk '$1>50 {print $2}' > $ips
sleep 60
done
while :; do
minip=`awk '{print $1}' $file|grep '^[0-9]'|sort|uniq -c|sort -nr|awk '$1<2 {print $2}'`
for j in $minip; do
if grep -oq $j $ips; then
sed -i "/$minip/d" $ips
fi
done
sleep 1800
done
if ! grep -q '/usr/local/apache2/conf/ips' $conf;then
sed -i '161 a\ Deny from /usr/local/apache2/conf/ips' $conf|sed -i 's/"//g' $conf
fi
思路:给apache服务配置文件添加Deny from /usr/local/apache2/conf/ips,其中文件/usr/local/apache2/conf/ips为高请求的IP,只需要按照要求定时更新该IP列表即可。
0
本帖最后由 loveyouhyf 于 2016-1-6 21:56 编辑
参考阿铭老师脚本并稍做修改如下:主要是改取得防火墙规则号的方法,改用badip.txt的ip与防火墙规则中ip匹配的方式,来进行删除防火墙规则动作,以达到解锁的目的
#!/bin/bash
logfile=/usr/local/apache/logs/access_log
badip=/tmp/badip.txt
ipt=/sbin/iptables
##for ((i=30;i>=1;i--));do
##d=`date -R -d "-$i min"|awk '{print $2"/"$3"/"$4":"$5}'|awk -F ':' '{print $1":"$2":"$3":"}'`
d=`date -d "-1 minute" +%d/%b/%Y:%H:%M:`
d2=`date +%M`
> $badip
block(){
for ip in `grep $d $logfile|awk '{print $1}'|sort -n|uniq -c|sort -n|awk '$1>1 {print $2}'`;do
$ipt -I INPUT -p tcp --dport 80 -s $ip -j REJECT
echo "`date +%F-%T -d "-$i minute"` $ip" >>$badip
done
}
unblock(){
for num in `awk '{print $2}' $badip` ;do
n=`$ipt -nvL --line-numbers|grep '0.0.0.0/0'|awk '$9=="'"$num"'" {print $1}'`
$ipt -D INPUT $n
$ipt -Z
done
}
while :;do
if [ $d2 == "00" ] || [ $d2 == "30" ]; then
unblock
block
else
block
fi
sleep 60
done
参考阿铭老师脚本并稍做修改如下:主要是改取得防火墙规则号的方法,改用badip.txt的ip与防火墙规则中ip匹配的方式,来进行删除防火墙规则动作,以达到解锁的目的
#!/bin/bash
logfile=/usr/local/apache/logs/access_log
badip=/tmp/badip.txt
ipt=/sbin/iptables
##for ((i=30;i>=1;i--));do
##d=`date -R -d "-$i min"|awk '{print $2"/"$3"/"$4":"$5}'|awk -F ':' '{print $1":"$2":"$3":"}'`
d=`date -d "-1 minute" +%d/%b/%Y:%H:%M:`
d2=`date +%M`
> $badip
block(){
for ip in `grep $d $logfile|awk '{print $1}'|sort -n|uniq -c|sort -n|awk '$1>1 {print $2}'`;do
$ipt -I INPUT -p tcp --dport 80 -s $ip -j REJECT
echo "`date +%F-%T -d "-$i minute"` $ip" >>$badip
done
}
unblock(){
for num in `awk '{print $2}' $badip` ;do
n=`$ipt -nvL --line-numbers|grep '0.0.0.0/0'|awk '$9=="'"$num"'" {print $1}'`
$ipt -D INPUT $n
$ipt -Z
done
}
while :;do
if [ $d2 == "00" ] || [ $d2 == "30" ]; then
unblock
block
else
block
fi
sleep 60
done
0
if ! grep -q '/usr/local/apache2/conf/ips' $conf;then
sed -i '161 a\ Deny from /usr/local/apache2/conf/ips' $conf|sed -i 's/"//g' $conf
fi
你这个方法可行,可是最后这一个我不理解,能解释一下吗?
Louis 发表于 2014-8-31 15:40
假如web服务器为apache服务。
#!/bin/bash
## This script is for judging if ip forbidden or permitted ...
if ! grep -q '/usr/local/apache2/conf/ips' $conf;then
sed -i '161 a\ Deny from /usr/local/apache2/conf/ips' $conf|sed -i 's/"//g' $conf
fi
你这个方法可行,可是最后这一个我不理解,能解释一下吗?
编辑回复