#利用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计算流量脚本:

#!/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优化后的脚本:

#!/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的脚本:

#!/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