前言
最近遇到一個問題,我網站一個小應用,都快要下線了,結果老不消停,負載彪高,響應緩慢,檢查超時等等,正常的用戶請求每天在1000+左右,這樣的pv量,完全不是問題,查看了cookie_log,發現有5G之多,看了下日誌,果然是***,於是就開始了我的防***之旅。
一、現象
1、負載很高,4核的機器,負載到40以上
2、http check超時10s
3、頁面訪問慢如蝸牛甚至直接503;
二、分析原因:
應用架構爲apache+jboss,系統爲redhat,正常每天的訪問量在500~1000,日常負載保持在0左右(基於此,該業務已經納入下線計劃中)。如此低的訪問量,根本不會出現負載高、響應慢的情況,看了訪問日誌,有5G之多,毫無疑問,這肯定是***了。
***特徵:A、IP分散;B、請求的URL爲POST登錄請求;C、***的agent爲同一個:Mozilla/4.0 (compatible; Win32; WinHttp.WinHttpRequest.5)
***必須要攔截啊,不然我就舒坦不了,下面就開始了我的攔截之旅。
三、***防禦:
1、最直接和簡單的,就是iptables了吧,原理很簡單,就是找出***IP,然後通過Iptables,將***IPdrop掉,封裝了兩個腳本,如下:
A、腳本一,獲取***IP並加入到iptables裏面:get_hack_iplist.sh
#/bin/bash #Edit:[email protected] #Date:2013-06-22 #Function:get hack ip list from cookie_log,then to iptables #cookie_log path cookie_log="/home/app/logs/cookie_logs/`date "+%w"`/cookie_log" ip_counts="/home/app/fuck_hack/log/ip_hack.txt" ip_counts_temp="/home/app/fuck_hack/log/ip_hack.txt.temp" record_black_list="/home/app/fuck_hack/log/record_black_list.txt" #get counts Ip from cookie_log function get_ip_counts(){ tail -n 10000 $cookie_log | awk '{print $1,$5}' | sort | uniq -c | sort -rg | head >$ip_counts #quchong awk '{a[$2]+=$1}END{for(i in a)print i,a[i]}' $ip_counts >$ip_counts_temp } #add ip black list to iptables function add_to_iptables(){ echo "date: `date "+%Y-%m-%d %H:%M:%S"`">>$record_black_list while read line do #get Ip ip=`echo $line | awk '{print $1}'` #232.* is beside if [ `echo $ip | grep '^232'|wc -l` -eq 1 ];then continue fi #get times count=`echo $line | awk '{print $2}'` if [ $count -ge 10 ];then echo -e "\t$ip\t$count">>$record_black_list /sbin/iptables -A INPUT -s $ip -p tcp -j DROP fi done<$ip_counts_temp } get_ip_counts add_to_iptable
B、腳本二,清除iptables,這一步是爲了防止誤殺或者ip太多,導致iptables性能問題:clear_iptables.sh
#!/bin/bash #edit :[email protected] #date :2013-06-22 #fucntion:clear iptables link log="/home/app/fuck_hack/log/clear_iptables.log" echo "date: `date "+%Y-%m-%d %H:%M:%S"`">>$log /sbin/iptables -X && /sbin/iptables -F if [ $? -eq 0 ];then echo -e "\tclear iptables link OK!">>$log fi
3、把這兩個腳本放到crontab下面去,定時執行,如下:
iptables裏面
#每隔2分鐘,掃一次黑名單,將黑名單加入iptables裏面 */2 * * * * sh /home/app/fuck_hack/get_hack_iplist.sh >/dev/null 2>&1 #爲防止誤殺及iptables性能,每小時的03分,清理一次iptables 3 */1 * * * sh /home/app/fuck_hack/clear_iptables.sh >/dev/null 2>&1
至此,最簡單的利用iptables來防***的就實現了。
2、沒消停幾天,問題有出現了,負載高,響應慢,我懷疑還是***的ip太分散,切***頻率太高,iptable的攔截ip畢竟有限,這次嘗試了網上介紹的一種方案,利用apache的 mod_evasive 模塊攔截。
mod_evasive 介紹
mod_evasive 是Apache(httpd)服務器的防DDOS的一個模塊。對於WEB服務器來說,是目前比較好的一個防護DDOS***的 擴展模塊。雖然並不能完全防禦DDOS***,但在一定條件下,還是起到緩服Apache(httpd)服務器的壓力。如配合iptables、硬件防火牆等防火牆設備配合使用,可能有更好的效果。
mod_evasive 的官方地址:http://www.zdziarski.com
詳細的配置我這裏就不多說了,我參考的是開源中國裏面的一片分享,地址:http://www.oschina.net/question/17_1564
詳細的配置和參數說明都有,下面是我的配置:
LoadModule evasive20_module /usr/app/apache2/modules/mod_evasive20.so <IfModule mod_evasive20.c> DOSHashTableSize 85420 DOSPageCount 5 DOSPageInterval 1 DOSSiteCount 5 DOSSiteInterval 1 DOSBlockingPeriod 3600 </IfModule>
我這裏配置的都很小,規則比較嚴格。生效的話,會在/tmp目錄下,生成dos-ip的文件,每個ip就爲一個***ip,每個文件的內容,就爲該ip***的次數。
3、以上配置雖然生效了,負載有降低,http也能正常打開了,但發現效果不明顯,沒有詳細的分析過,我初步懷疑可能還是訪問量太大了,模塊在做過濾等的性能問題,再加上apache的版本太老,因此效果可能沒有發揮出來。
實在是沒轍了,***牛逼,逼的我不得不回到公司的終極武器上,XXX***防禦模塊,經過一般努力,終於配置上線,頓時,在控制檯上,***原形畢露,各種ip,各種agent。長吸一口氣,起身,一杯咖啡下肚,陰笑一聲,選擇,全部,目的,黑洞。
至此,徹底封殺了***的噁心,害得小爺陪你玩了好幾天。
備註,沒有第一時間考慮該模塊是因爲該業務的系統和apache版本都太老了,倉庫裏的XXX模塊版本都不支持,最後逼的開發不知道從那個旮旯裏找出來一個版本,抱着試試的態度,安裝配置完成並生效。