2014-01-22 shell脚本练习

回复 收藏

需求: 根据web服务器上的访问日志,把一些请求量非常高的ip给拒绝掉! 分析: 我们要做的,不仅是要找到哪些ip请求量不合法,并且还要每隔一段时间把之前封掉的ip(若不再继续请求了)给解封。 所以该脚本的关键点在于定一个合适的时间段和阀值。 比如, 我们可以每一分钟去查看一下日志,把上一分钟的日志给过滤出来分析,并且只要请求的ip数量超过50次那么就直接封掉。 而解封的时间又规定为每半小时分析一次,把几乎没有请求量的ip给解封!参考日志文件:

我写的线上跑的脚本如下:

#! /bin/bashlogfile=/home/logs/client/access.log
d1=`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

2014-01-22 12:26 举报
已邀请:
0

忆水寒冰

赞同来自:

qq
0

good

赞同来自:

看看
0

hkj8808

赞同来自:

学习一下  这个真的不会
0

Agatha-cn

赞同来自:

xuexi
0

路过

赞同来自:

是啊
0

ocean

赞同来自:

xuexi
0

轩鹏

赞同来自:

1
0

黑色的梦

赞同来自:

{:4_91:}
0

齐天大圣

赞同来自:

dd
0

tulip

赞同来自:

kk
0

zyfeifie

赞同来自:

kankan
0

So Long

赞同来自:

不会
0

鸵鸟

赞同来自:

xx
0

Louis

赞同来自:

假如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列表即可。
0

木字当头

赞同来自:

study
0

wyatt88

赞同来自:

这个学习下哈
0

huifeidexiaxia

赞同来自:

学习
0

chenzudao1234

赞同来自:

kankan
0

So Long

赞同来自:

学习下
0

Louis_Lee

赞同来自:

lxg
0

jade

赞同来自:

看看,学习对比中
0

xuyl

赞同来自:

学习,学习。。。。。。。
0

yaabb163

赞同来自:

ddddddddd
0

cmzsteven

赞同来自:

{:4_91:}
0

zhangw

赞同来自:

1
0

dantes

赞同来自:

111111
0

hangtiangazi

赞同来自:

看看。。。
0

Wagskun

赞同来自:

xue
0

来点情绪

赞同来自:

看看,学习一下!
0

北辰星

赞同来自:

练习
0

qin521ne

赞同来自:

学习
0

307141950

赞同来自:

kankan

0

渐行渐远

赞同来自:

额,都在看
0

Shawn

赞同来自:

.
0

ifconfig2

赞同来自:

看看
0

yanggang

赞同来自:

{:4_91:}
0

ldp840611

赞同来自:

看看
0

Rohero

赞同来自:

学习
0

石头

赞同来自:

{:4_91:}
0

weifeng1463

赞同来自:

ok
0

Landon

赞同来自:

asd
0

loveyouhyf

赞同来自:

本帖最后由 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
0

hlymlv

赞同来自:

看看
0

xteplinux

赞同来自:

{:4_91:}
0

balich

赞同来自:

学习
0

licengceng

赞同来自:

学习
0

老咸菜

赞同来自:

1
0

lin19890913

赞同来自:

看看
0

落涧飞鹰

赞同来自:

看看
0

bbcw

赞同来自:

看看答案,自己的思路办法太复杂了
0

jinm

赞同来自:

学习
0

LPing

赞同来自:

学习
0

sy0258

赞同来自:

学习
0

乐橙306

赞同来自:

1
0

不怕不怕

赞同来自:

参考
0

gxp2008

赞同来自:

看看,就是没想明白,怎么把要封的ip,接入到iptables上
我的思路是,过滤出来 以403所在的行 第二段 ip,过滤干净
然后将这些ip排序,计数,符合就封掉。每半小时解封一次
0

奇怪的蔬菜

赞同来自:

参考一下
0

指日可待

赞同来自:

学习一下
0

小猫咪

赞同来自:

{:5_121:}
0

youlianqing

赞同来自:

学习
0

liang

赞同来自:

学习学习, DenyHosts这个软件好像就是这样的功能,
0

漠林sky

赞同来自:

看一下
0

wangzai

赞同来自:

学习
0

xzzlamp

赞同来自:

11
0

郭贞

赞同来自:

{:4_91:}
0

xufanyunwei

赞同来自:

学习
0

timfeng3535

赞同来自:

dfasdfasdf
0

branttsai

赞同来自:

不会,学习学习,谢谢。
0

duyanbin

赞同来自:

学习一下
0

googleqicq

赞同来自:

{:4_92:}
0

Toornix

赞同来自:

看下答案
0

jonnylin

赞同来自:

学习
0

小毅

赞同来自:

这个好难
0

hsm

赞同来自:

学习
0

kevinjin

赞同来自:

看答案
0

kevinjin

赞同来自:

把封掉和解封的2个动作分成2个函数来写,最后再按照每半个小时的表示方法调用两个模块,不同时间点做不同的操作,我觉得很有借鉴意义
0

Bullet_Point

赞同来自:

1
0

malong

赞同来自:

kankan
0

小杰

赞同来自:

{:4_91:}
0

hhao

赞同来自:

1
0

xigua

赞同来自:

学习一下
0

liqian

赞同来自:

学习中。。。
0

15812926028

赞同来自:

666
0

riverxyz

赞同来自:

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
你这个方法可行,可是最后这一个我不理解,能解释一下吗?
0

linuxcp

赞同来自:

{:4_91:}
0

chenlei82486708

赞同来自:

学习
0

dongteng

赞同来自:

学习
0

J_C

赞同来自:

看看
0

zhangyanlong

赞同来自:

111

0

13600827194

赞同来自:

看看

0

有人喜欢蓝

赞同来自:

学习一下思路

0

kw是id

赞同来自:

学习一下思路

0

qwlp19910807

赞同来自:

学习一下

0

nmzhaoliming

赞同来自:

学习

0

Ject1992he - linux学习

赞同来自:

学习

0

Ject1992he - linux学习

赞同来自:

QQ截图20161229113931.png括起的脚本是不是有错呢?

0

loujb

赞同来自:

看看

0

sun330

赞同来自:

学习

0

dongdongchen

赞同来自:

可以看看

0

大雁

赞同来自:

不理解,先看铭哥写的

回复帖子,请先登录注册

退出全屏模式 全屏模式 回复
评分
可选评分理由: