nginx網站攻擊防護


1.上上個月架構全部遷移上雲以后,總的來說比較穩定,業務量也上來,可愛的壞人也來了,7X24小時不停惡意攻擊我的網站,第一次收到報警是網站流入流量1分鍾以內連續3次超過1000000bps,換算下1M/s秒,平時沒那么大流量的啊,當時剛好在朋友家玩,於趕緊開本本連vpn檢查,發現全是訪問同一個頁面的請求,而且是正常訪問http 200,應該是被惡意攻擊了。

發現問題
發現問題第一反應,趕緊將請求地址截圖發給開發們看看,問問這個具體是什么?
最后得知是為短信驗證碼接口,據后來統計在被持續攻擊的一個多小時中損失16000多條短信。

http://s1.51cto.com/wyfs02/M00/86/0C/wKioL1ezzmTirjx1AANO6vFE_KI482.png

 解決問題:一期防攻擊策略:
發現問題當然要立馬解決了,當時思路就是統計nginx日志,當單個ip在10秒鍾內訪問 /account/sendPhoneCode次數超過5次,就禁用這個ip,正常用戶不可能有么大的訪問量,於是就有了下面的防攻擊shell腳本。

這個腳本加在定時任務里每分鍾執行一次,半夜0點自動重啟動防火牆,釋放IP,基本上防止了攻擊,大概使用了半個月

#!/bin/bash
#write: lijing QQ 858080796
#date:  20160528 v2.0
#description:攔截非法IP
  
#定義變量
RETVAL=0
Date=$(date '+%Y-%m-%d')
Time=$(date '+%Y:%H:%M' -d '-1 minute')
MON=$(date|awk -F" " '{print $2}')
TODAY=$(date|awk -F" " '{print $3}')
Log="/data/logs/nginx/access.log "
LINE="70000"
  
#關鍵字
Key01="sendPhoneCode"
  
Status=/tmp/statuS_deny_ip
  
/sbin/service iptables status > $Status
  
#定義函數
#禁止時間函數
secure_deny_time(){
Time01=$(date "+%H:%M:%S" -d " -10 second")
Time02=$(date "+%H:%M:%S" -d " -9  second")
Time03=$(date "+%H:%M:%S" -d " -8  second")
Time04=$(date "+%H:%M:%S" -d " -7  second")
Time05=$(date "+%H:%M:%S" -d " -6  second")
Time06=$(date "+%H:%M:%S" -d " -5  second")
Time07=$(date "+%H:%M:%S" -d " -4  second")
Time08=$(date "+%H:%M:%S" -d " -3  second")
Time09=$(date "+%H:%M:%S" -d " -2  second")
Time10=$(date "+%H:%M:%S" -d " -1  second")
    echo  "$Time01  $Time02 $Time03 $Time04 $Time05 $Time06 $Time07 $Time08 $Time09 $Time10 "
}
#       禁止關鍵字函數
secure_key(){
    tail -n $LINE $LOG |grep "$TODAY\/$MON"|grep -v ^$|grep $TIME|grep $1 |grep $2 |grep $3  |grep $4 |awk -F " " '{print $1}' |sort >> $Deny
    echo " grep "$TODAY\/$MON" $LOG |grep -v ^$|grep $TIME|grep $1 |grep $2 |grep $3  |grep $4 |awk '{print $1}' |sort"
        }
#執行防火牆攔截函數
secure_deny_ip()
{
        cat $Deny
        echo ......................
        cat $Deny02
    for i in $IP;do
        NUM=$(cat $Deny02|grep $i|awk -F" " '{print $1}')
       if [ -z $NUM ];then
            echo " "
        else
            if [ $NUM -ge $Dot ];then
                for y in $i;do
                    grep $y $Status  >/dev/null 2>&1 
                    RETVAL=$?
                                        [ $RETVAL != 0  ] && echo "/sbin/iptables -I INPUT -s $y  -j DROP"
[ $RETVAL != 0  ] && /sbin/iptables -I INPUT -s $y  -j DROP 
                                        [ $RETVAL != 0  ] && echo "$(date "+%H:%M:%S") $y " >> /tmp/$Date
                    #[ $RETVAL != 0  ] && /sbin/iptables -I INPUT -s $y -p  tcp  -j REJECT
                done
            fi
        fi
    done
}
  
  
NUMBER="1 2 3 4 5 6"
for  NUMBER in  $NUMBER   ;do
sleep 10s
#定義點擊次數 Dot
Dot=5
Deny=/tmp/secure_deny_tmp_$NUMBER
Deny02=/tmp/secure_deny_$NUMBER
#第1次,檢查當前時間以前10s.  如: 0-10秒
echo "第$NUMBER 次,檢查當前時間以前第$NUMBER 個10s.大於 $Dot 次攻擊阻止"
echo > $Deny
for LOG in `echo $Log` ;do
    secure_deny_time
    for TIME in $Time01  $Time02 $Time03 $Time04 $Time05 $Time06 $Time07 $Time08 $Time09 $Time10 ;do
        secure_key  $Key01 
    done
       cat $Deny|sort|uniq -c > $Deny02         
   IP=$(cat $Deny02|awk -F" " '{print $2}')
        secure_deny_ip 
done
done
exit

 二期防攻擊策略:

Shell腳本運行的半個月時間里,雖然防止了攻擊,但是公司客服反饋有客戶被誤殺,最嚴重的是公司有次活動,10秒內發5個短信請求很正常啊,誤殺了部分用戶,被防火牆禁止IP不能訪問任何服務於是得從nginx應用層找方法,不能用老套方法禁IP了,在網上在找幾天的資料解決,幾乎沒有相同的案例,只能自己創造了。

天道酬勤,終於有了兩個思路:
一是nginx結合lua來防攻擊(在網上看得我雲里霧里的,最后不會lua選擇放棄這個方案)。
二是利用ngx_http_referer_module(當時看了2天官網英文資料,http://nginx.org/en/docs/http/ngx_http_referer_module.html,這個頁面的讓我找到方法,尤其是nginx的if 語句)。

對比攻擊日志和正常日志發現,其$http-referer是不同的,如下圖:
    正常訪問:

http://s2.51cto.com/wyfs02/M02/86/0C/wKioL1ezz-eDhzMVAACRSeF04-E267.png

攻擊訪問:

http://s2.51cto.com/wyfs02/M01/86/0C/wKioL1ezzx6gBIqmAANuq4j46Ls244.png

最終解決思路:
        1、去掉了原來的 攔截ip策略,不載攔截ip。
        2、啟用nignx的location 匹配/account 的$http-referer的過濾,當不是正常$http-referer,直接在再nginx處理。
Nginx配置如下:

location ~ /account(/.*)  { 
if ($http_referer ~  "https://www.xxxxxxxx.net/account/sendPhoneCode") {
   #如果匹配就直接返回200,返回404,也行啊,自己定。給可愛的攻擊者,不傳給后端web
                return 200;        }
    #不匹配,傳給后端web
 proxy_pass  http://web_group/account/;
}

整個防攻擊到現在沒有出現任何問題,效果杠杠的。后期會增加第三期,主要是我們NB的開發,從程序級解決,如增加各種驗證啊。

 

http://qiaomiao.blog.51cto.com/484197/1839337

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM