寫了個簡單腳本依據連接數超過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