1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#利用iptables  limit模块限速
#
#!/bin/bash
#SPEED=`/bin/bash  /etc/zabbix/script/flow.sh |cut -d '.' -f1`
SPEED=` /bin/bash   /root/flow .sh | cut  -d  '.'  -f1`
[ -z $SPEED ]&& SPEED=1
EXIST=`iptables -n - v  -L | grep  CC-FLOW| wc  -l`
if  [ $SPEED -gt 1250 ];
then
IP=` netstat  -antup| grep  ESTABLISHED| awk  '{print $5}'  | grep   -o   "\([0-9]\{1,3\}\.\)\{1,3\}[0-9]\{1,3\}" | sort   -rn | uniq  -c| awk  '{print $2}' `     #awk截取客户端字段、sort 和uniq是防止ip重复
if  [ $EXIST - eq  0 ]; then
iptables -N CC-FLOW    #创建自定义链CC-FLOW
iptables -A OUTPUT -j CC-FLOW     #把OUTPUT规则引到CC-FLOW
fi 
for   i   in  $IP
do
x=`iptables  -n - v  -L | grep   $i| wc  -l`
if  [ $x - ne  0 ]; then 
continue
fi
iptables -A CC-FLOW -d $i  -m limit --limit 150 /s  -j ACCEPT   #限制$i下载输入为每秒150个包,一个包一般是1540字节左右,所以速度大概在200kbyte
iptables -A CC-FLOW -d $i  -j DROP     #超过的drop
done
else
if  [ $EXIST - ne  0 ] && [ $SPEED -lt 500 ];  then 
iptables -F CC-FLOW            #清空cc-flow的规则
iptables -D OUTPUT -j CC-FLOW      #清空cc-flow与output的链接,否则删除不了链接
iptables -X CC-FLOW         #删除cc-flow链
fi
fi




flow.sh计算流量脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
old_inbw=` cat  /proc/net/dev  grep  eth0 |  awk  -F '[: ]+'  '{print $3}' `
old_outbw=` cat  /proc/net/dev  grep  eth0 |  awk  -F '[: ]+'  '{print $11}' `
       sleep  5
         new_inbw=` cat  /proc/net/dev  grep  eth0 |  awk  -F '[: ]+'  '{print $3}' `
         new_outbw=` cat  /proc/net/dev  grep  eth0 |  awk  -F '[: ]+'  '{print $11}' `
         inbw=$[ $new_inbw - $old_inbw ]
         outbw=$[ $new_outbw - $old_outbw ]
         # echo "eth0: IN:$inbw bytes  OUT:$outbw bytes"
         IN=` echo  "scale=2;$inbw/5/1024"  | bc  | awk  '{printf "%.2f\n", $0}' `
         OUT=` echo  "scale=2;$outbw/5/1024"  | bc  | awk  '{printf "%.2f\n", $0}' `
         echo  "$IN+$OUT"  | bc
         old_inbw=${new_inbw}
         old_outbw=${new_outbw}
         var0=$[$var0 + 1]

=============================================================

利用ipset 和ss优化后的脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/bin/bash
export  PATH= /usr/local/sbin : /usr/local/bin : /sbin : /bin : /usr/sbin : /usr/bin : /root/bin
IPSET=limitip
IPSET1=dropip
SPEED=` /bin/bash   /etc/zabbix/script/flow .sh | cut  -d  '.'  -f1`
[ -z $SPEED ]&& SPEED=1
EXIST=`iptables -n - v  -L | grep  $IPSET| wc  -l`
EXIST1=`iptables -n - v  -L | grep  $IPSET1| wc  -l`
if  [ $SPEED -gt 1250 ];
then
IPDROP=`ss -n| grep  ":80 " | awk  '{print $5}'  | grep  - v  "*" | grep  - v  ":80$" | grep  - v  '127.0.0' | grep   -o   "\([0-9]\{1,3\}\.\)\{1,3\}[0-9]\{1,3\}" | sort   -rn | uniq  -c| awk  '{if ($1>80) print $2}' | sed  's/\.[0-9]*$/\.0\/24/g' | sort   -rn | uniq  -c| awk  '{print $2}' | egrep  - v  -f  /home/tongbu/conf/nodeip .txt`
IPLIMIT=`ss -n| grep  ":80 " | awk  '{print $5}'  | grep  - v  "*" | grep  - v  ":80$" | grep  - v  '127.0.0' | grep   -o   "\([0-9]\{1,3\}\.\)\{1,3\}[0-9]\{1,3\}" | sort   -rn | uniq  -c| awk  '{if ($1<81) print $2}' | sed  's/\.[0-9]*$/\.0\/24/g' | sort   -rn | uniq  -c| awk  '{print $2}' | egrep  - v  -f  /home/tongbu/conf/nodeip .txt`
if  [ `ipset list | grep  "Name" | grep  "\<$IPSET\>" | wc  -l` - eq  0 ]; then
ipset create $IPSET  hash :net maxelem 10000
fi
if  [ `ipset list | grep  "Name" | grep  "\<$IPSET1\>" | wc  -l` - eq  0 ]; then
ipset create $IPSET1  hash :net maxelem 10000
fi
if  [ $EXIST - eq  0 ]; then
iptables -I INPUT -m  set  --match- set  $IPSET src -j DROP
iptables -I INPUT -m  set  --match- set  $IPSET src -m limit --limit 200 /s  -j ACCEPT
iptables -I OUTPUT -m  set  --match- set  $IPSET dst -j DROP
iptables -I OUTPUT -m  set  --match- set  $IPSET dst -m limit --limit 200 /s  -j ACCEPT
iptables -I INPUT -m  set  --match- set  $IPSET1 src -j DROP
fi 
for   i   in  $IPLIMIT
do
x=`ipset list | grep   $i| wc  -l`
if  [ $x - ne  0 ]; then 
continue
fi
ipset add $IPSET $i
done
        for   i   in  $IPDROP
         do
                 x=`ipset list | grep   $i| wc  -l`
                 if  [ $x - ne  0 ]; then
                         continue
                 fi
                 ipset add $IPSET1 $i
         done
else
if  [ $EXIST - ne  0 ] && [ $SPEED -lt 500 ]|| [ $EXIST1 - ne  0 ] ;  then 
NUMIN1=`  /etc/init .d /iptables  status| sed  -n  '/INPUT/,/OUTPUT/p' | grep  $IPSET | awk  '{print $1}' | head  -1`
                                 iptables -D INPUT $NUMIN1
NUMOUT1=`  /etc/init .d /iptables  status| sed  -n  '/OUTPUT/,$p' | grep  $IPSET | awk  '{print $1}' | head  -1`
iptables -D OUTPUT $NUMOUT1
                 NUMIN2=`  /etc/init .d /iptables  status| sed  -n  '/INPUT/,/OUTPUT/p' | grep  $IPSET | awk  '{print $1}' | head  -1`
                                 iptables -D INPUT $NUMIN2
                 NUMOUT2=`  /etc/init .d /iptables  status| sed  -n  '/OUTPUT/,$p' | grep  $IPSET | awk  '{print $1}' | head  -1`
                                 iptables -D OUTPUT $NUMOUT2
NUMIN3=`  /etc/init .d /iptables  status| sed  -n  '/INPUT/,/OUTPUT/p' | grep  $IPSET1 | awk  '{print $1}' | head  -1`
  iptables -D INPUT $NUMIN3
ipset destroy $IPSET
ipset destroy $IPSET1
fi
fi

改用tc限速和只限制发包大的ip的脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#!/bin/bash
export  PATH= /usr/local/sbin : /usr/local/bin : /sbin : /bin : /usr/sbin : /usr/bin : /root/bin
IPSET=limitip
IPSET1=dropip
SPEED=` /bin/bash   /etc/zabbix/script/flow .sh | cut  -d  '.'  -f1`
DEV=` grep  'NIC='   /etc/zabbix/script/flow .sh | cut  -d  '='  -f2`
IP=` grep  'IP='  /etc/log .sh | cut  -d  '='  -f2`
[ -z $SPEED ]&& SPEED=  1
EXIST=`iptables -n - v  -L -t mangle| grep  $IPSET| wc  -l`
EXIST1=`iptables -n - v  -L | grep  $IPSET1| wc  -l`
if  [ $SPEED -gt 1250 ];
then
IPDROP=`ss -n| grep  ":80 " | awk  '{print $5}'  | grep  - v  "*" | grep  - v  ":80$" | grep  - v  '127.0.0' | grep   -o   "\([0-9]\{1,3\}\.\)\{1,3\}[0-9]\{1,3\}" | sort   -rn | uniq  -c| awk  '{if ($1>80) print $2}' | egrep  - v  -f  /home/tongbu/conf/nodeip .txt`
IPLIMIT=`ss -tn| awk  'NR>1{if ($3 > 4000) print $5}' | cut  -d: -f1| sort  -rn| uniq  -c| awk  '{print $2}' | egrep  - v  -f  /home/tongbu/conf/nodeip .txt`
     if  [ `ipset list | grep  "Name" | grep  "\<$IPSET\>" | wc  -l` - eq  0 ]; then
         ipset create $IPSET  hash :net maxelem 1000000
     fi
     if  [ `ipset list | grep  "Name" | grep  "\<$IPSET1\>" | wc  -l` - eq  0 ]; then
         ipset create $IPSET1  hash :net maxelem 1000000
     fi
     if  [ $EXIST - eq  0 ]; then
         flow_max=`mysql  -h 218.32.211.9 -ucomlesu -pcqhd@b -e  "use comlesu; select flow_max from lc_node where ip='$IP'" | tail  -1`
         tc qdisc del dev $DEV root &> /dev/null
         tc qdisc add dev $DEV root handle 1: htb default 2
         tc class add dev $DEV parent 1: classid 1:1 htb rate $[$flow_max*1]kbps ceil $[$flow_max*1]kbps
         tc class add dev $DEV parent 1: classid 1:2 htb rate $[$flow_max*9]kbps ceil $[$flow_max*9]kbps
         tc qdisc add dev $DEV parent 1:1 handle 11 sfq perturb 10
         tc qdisc add dev $DEV parent 1:2 handle 12 sfq perturb 10
         tc filter add dev $DEV parent 1: protocol  ip prio 8 handle 111 fw classid 1:1
         iptables  -t  mangle -A POSTROUTING -m  set  --match- set   $IPSET dst -j MARK -- set -mark 111
         iptables -I INPUT -m  set  --match- set  $IPSET1 src -j DROP
     fi 
     for   i   in  $IPLIMIT
     do
         x=`ipset list | grep   $i| wc  -l`
         if  [ $x - ne  0 ]; then 
             continue
         fi
         ipset add $IPSET $i
     done
             for   i   in  $IPDROP
         do
                 x=`ipset list | grep   $i| wc  -l`
                 if  [ $x - ne  0 ]; then
                         continue
                 fi
                 ipset add $IPSET1 $i
         done
else
     if  [ $EXIST - ne  0 ] && [ $SPEED -lt 650 ]|| [ $EXIST1 - ne  0 ] ;  then 
         NUM1=`iptables -n - v  -L --line-number | grep  $IPSET1 | awk  '{print $1}' `
         iptables -D INPUT $NUM1
         NUM=`iptables -t mangle -n - v  -L --line-number | grep  $IPSET | awk  '{print $1}' `
         iptables  -t  mangle -D POSTROUTING  $NUM
         tc qdisc del dev $DEV root  &> /dev/null
         ipset destroy $IPSET
         ipset destroy $IPSET1
     fi
fi






















本文转自biao007h51CTO博客,原文链接:http://blog.51cto.com/linzb/1766218 ,如需转载请自行联系原作者