写了个简单脚本依据连接数超过100,自动封ip的脚本。
因为最近这几天公司网站一直给人刷验证码,以及API接口。虽然可以使用iptables把它ip封了,但是那些人都是半夜来刷的,真可恶,同时有好几十个肉鸡过来刷,并且有时候有几个ip居然用iptables封不了,这几天疯狂了解相关的DDOS***原理信息,看能否找到有效的方法拦截。
[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
转载于:https://blog.51cto.com/hejianping/1774973