Linux伺服器自動封鎖訪問異常的IP指令碼(一)
問題:
最近發現很多大並發爬我們網站部分介面的爬蟲,導致經常性頻寬異常和服務異常,為了暫時性偷懶,寫指令碼自動封鎖這些IP。
思路和方法:
經過日誌排查,發現這些爬蟲IP不多,但是並發很大,基本在10-20並發之間,正常的單IP請求幾乎很少有10並發以上的,所以處理的思路就是
使用iptables臨時封鎖這些異常IP,封鎖規則每5分鐘單IP請求量超過3000次,即5分鐘內單IP並發超過10,封鎖此IP,另外為了防止封錯,指令碼自動每 5分鐘解禁5分鐘前封鎖的IP地址。
實現:
為了簡單管理,使用shell+crontab實現指令碼處理。
指令碼:
#!/bin/sh ##Author:bbzsxjj ##Email:bbzsxjj@163.com ##Usage:auto deny ip by iptables ##Ver:1.0 timenow=`date +'%H%M00'` timelast=`date +'%H%M00' -d '-5min'` lastnum=1000000 ##日誌的行數,可以根據自己的業務頻率選取 limitnum=3000 ##並發限制,300*10 ipbin=/sbin/iptables NeedDenyiplist=/opt/sbin/ipdeny.list NeedPurgeiplist=/opt/sbin/ippurge.list LogFile=/data/logs/haproxy.log CreateList(){ if [ -f ${LogFile} ] then if [ -f ${NeedDenyiplist} ] then mv ${NeedDenyiplist} ${NeedPurgeiplist} fi tail -n${lastnum} ${LogFile}|awk '{gsub(/:/,"",$3);if($3>='${timelast}' && $3<='${timenow}'){a[$6]++}}END{for(i in a){if(a[i]>'${limitnum}'){print $6}}}' >>${NeedDenyiplist} ##這裡需要根據日誌的格式進行處理,具體的需要根據實際情況修改處理方法 if [ `wc -l ${NeedDenyiplist}|awk '{print $1}'` -eq 0 ] then rm -rf ${NeedDenyiplist} fi fi
}
DenyIP(){ for Dip in `cat ${NeedDenyiplist}|grep -E -v '^$|#'` do ${ipbin} -I INPUT -s ${Dip} -p tcp --dport 80 -j DROP done } PurgeIP(){ for Dip in `cat ${NeedPurgeiplist}|grep -E -v '^$|#'` do ${ipbin} -D INPUT -s ${Dip} -p tcp --dport 80 -j DROP done }
main(){ CreateList if [ -f ${NeedPurgeiplist} ] then PurgeIP fi if [ -f ${NeedDenyiplist} ] then DenyIP fi } main
|
之後添加crontab:
###denyip
*/5 * * * * /bin/sh /opt/sbin/denyip.sh >/dev/null 2>&1;