項目上線之后绍妨,經(jīng)常會被一些爬蟲盯上,這些IP產(chǎn)生大量高頻請求怔球,導(dǎo)致帶寬流量異常,對服務(wù)器造成負(fù)荷浮还。針對這種問題可以采用iptables+ipset進(jìn)行封禁處理竟坛。
為什么不單獨用iptables?
因為iptables創(chuàng)建大量規(guī)則的時候性能會嚴(yán)重下降,性能指數(shù)是O(n)担汤。而ipset是一個ip集合涎跨,一條iptables規(guī)則鏈接一個ipset,性能指數(shù)是O(1)崭歧,ip集合存儲在帶索引的數(shù)據(jù)結(jié)構(gòu)中,這種結(jié)構(gòu)即使集合比較大也可以進(jìn)行高效的查找隅很。此外,ipset支持動態(tài)修改率碾,即使ipset的iptables規(guī)則已經(jīng)啟動叔营,新加入到ipset中的IP也能生效。
centos/redhat安裝ipset
yum install ipset -y
創(chuàng)建一個ipset
ipset create xxx hash:net (也可以是hash:ip 所宰,這指的是單個ip,xxx是ipset名稱)
ipset最大存儲數(shù)量默認(rèn)為65536個元素绒尊,使用maxelem指定數(shù)量
示例:
#集合名字:blacklist,timeout 3600 表示封禁3600s歧匈,timeout為0表示永久垒酬;
ipset create blacklist hash:ip timeout 3600
#指定最大存儲數(shù)量
ipset create blacklist hash:ip maxelem 1000000
#添加一個黑名單IP
ipset add blacklist 192.168.10.1
#刪除一個黑名單IP
ipset del blacklist 192.168.10.1
#刪除一個ipset
ipset destroy blacklist
創(chuàng)建一條iptables規(guī)則用來過濾黑名單IP
#添加一條 iptables規(guī)則,鏈接ipset件炉,開啟封禁80勘究,443策略
iptables -A INPUT -p tcp -m set --match-set blacklist src -m multiport --dports 443,80 -j DROP
#也可以封禁所有端口
iptables -I INPUT -p tcp -m set --match-set blacklist src -m multiport -j DROP
基于自定義訪問頻率閾值或者請求敏感關(guān)鍵字來創(chuàng)建自動篩選惡意IP的腳本/data/iptables_ipset_deny.sh
FILES:nginx的access.log文件
sensitive: 敏感關(guān)鍵字
threshold: 一分鐘內(nèi)請求頻率閾值
#!/bin/bash
FILES="/data/nginx/logs/access.log"
sensitive="sensitive_word"
threshold=1000
ip_file="/tmp/ip_file"
sensitive_file="/tmp/sensitive_file"
DATE=`date -d '1 minutes ago' +%Y:%H:%M`
grep ${DATE} ${FILES} | awk '{print $1}' | sort | uniq -c | sort -n | tail -n 1 > ${ip_file}
grep ${DATE} ${FILES} | grep -i ${sensitive} | awk '{print $1}' | sort -n | uniq > ${sensitive_file}
ip_file_number=`awk '{print $1}' ${ip_file}`
ip_file_ip=`awk '{print $2}' ${ip_file}`
if [[ $ip_file_number -gt $threshold ]];then
ipset add blacklist ${ip_file_ip} timeout 3600
fi
if [ -s ${sensitive_file} ];then
for sensitive_ip in `cat ${sensitive_file}`
do
ipset add blacklist ${sensitive_ip}
done
fi
---------------------
使用crontab啟動腳本
echo "* * * * * bash /data/iptables_ipset_deny.sh" >> /etc/crontab