写了个简单脚本依据连接数超过100,自动封ip的脚本。

   因为最近这几天公司网站一直给人刷验证码,以及API接口。虽然可以使用iptables把它ip封了,但是那些人都是半夜来刷的,真可恶,同时有好几十个肉鸡过来刷,并且有时候有几个ip居然用iptables封不了,这几天疯狂了解相关的DDOS***原理信息,看能否找到有效的方法拦截。j_0010.gif


[root@docker scripts]# cat iptables_ip.sh 

#!/bin/sh

# Filename:    iptables_stop_ip.sh

# Author:      hejp

# Time:        2016-5-21

# Description: for stop cc ip

# Notes:       This script runs  every minute of every day 


#上限

num=100


iplist=`netstat -an |grep ^tcp.*:80|egrep -v "LISTEN|127.0.0.1"|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -rn -k1|awk '{if ($1>$num){print $2}}'`


for i in $iplist

    do

      iptables -t filter -I INPUT -p tcp -s  $i  --dport 80 -j DROP

done


  当然,这样其实很容易误封内网的ip,所以后面还需要弄2个列表,一个是实时的连接数超过100的列表,另一个是允许通行的内网ip列表,通过比对,分析差异,如果是内网ip,就不封,如果是外网的ip就封了。这个办法有点笨,不过先用着先,先把问题解决,后面再找更好办法来处理。


  补充一点,假如人家是用低于100线程访问网站的话,人家还是可以刷,上面那脚本就不起作用了,因为访问日志每天都做切割的,所以可以依据访问数来封ip,从访问日志access.log过滤,一天内同一个ip访问数达到10万(依据业务取上限),就把它封了。

#!/bin/sh

accesslist=`awk '{print $1}' /var/log/nginx/access.log|sort|uniq -c|sort -rn -k1|awk '{if ($1>100000){print $2}}'`


p=`iptables -L -n|awk '{print $4}'|egrep -v "source|ACCEPT|^$"|sort|uniq`


if [ $accesslist == $p ]

   then

   echo "this ip had in iptable_list !"

   exit 0;

fi



for k in $accesslist

    do

      iptables -t filter -I INPUT -p tcp -s  $k  --dport 80 -j DROP

done