欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Nginx服務(wù)器抵御CC攻擊的相關(guān)配置講解

 更新時(shí)間:2016年01月06日 14:57:34   作者:moon  
這篇文章主要介紹了Nginx服務(wù)器抵御CC攻擊的相關(guān)配置講解,CC攻擊原理與DDoS基本相似而且技術(shù)含量低,注意防范即可,需要的朋友可以參考下

0x00 CC攻擊的基本原理
  CC攻擊利用代理服務(wù)器向網(wǎng)站發(fā)送大量需要較長計(jì)算時(shí)間的URL請求,如數(shù)據(jù)庫查詢等,導(dǎo)致服務(wù)器進(jìn)行大量計(jì)算而很快達(dá)到自身的處理能力而形成DOS。而攻擊者一旦發(fā)送請求給代理后就主動(dòng)斷開連接,因爲(wèi)代理并不因爲(wèi)客戶端這邊連接的斷開就不去連接目標(biāo)服務(wù)器。因此攻擊機(jī)的資源消耗相對很小,而從目標(biāo)服務(wù)器看來,來自代理的請求都是合法的。
  以前防CC攻擊的方法
  為了防范CC,以前的方法一個(gè)是限制每個(gè)IP的連接數(shù),這在地址范圍很廣闊的情況下比較難實(shí)現(xiàn);二是限制代理的訪問,因?yàn)橐话愕拇矶紩?huì)在HTTP頭中帶 X_FORWARDED_FOR字段,但也有局限,有的代理的請求中是不帶該字段的,另外有的客戶端確實(shí)需要代理才能連接目標(biāo)服務(wù)器,這種限制就會(huì)拒絕一些正常用戶訪問。
  CC攻擊用硬防難防住
  CC攻擊比DDOS攻擊更可怕的就是,CC攻擊一般是硬防很難防止住的。
  個(gè)人分析原因有三:
  一、因?yàn)镃C攻擊來的IP都是真實(shí)的,分散的;
  二、CC攻擊的數(shù)據(jù)包都是正常的數(shù)據(jù)包;
  三、CC攻擊的請求,全都是有效的請求,無法拒絕的請求。
  防CC攻擊思路
  防CC有效性在于攻擊方不接受服務(wù)器回應(yīng)的數(shù)據(jù),發(fā)送完請求后就主動(dòng)斷開連接,因此要確認(rèn)連接是否是CC,服務(wù)器端不立即執(zhí)行URL請求命令,而是簡單的返回一個(gè)頁面轉(zhuǎn)向的回應(yīng),回應(yīng)中包含新的URL請求地址。如果是正常訪問,客戶端會(huì)主動(dòng)再次連接到轉(zhuǎn)向頁面,對用戶來說是透明的;而對于CC攻擊者,由于不接收回應(yīng)數(shù)據(jù),因此就不會(huì)重新連接,服務(wù)器也就不需要繼續(xù)進(jìn)行操作。

0x01 驗(yàn)證瀏覽器行為

簡易版

我們先來做個(gè)比喻。

社區(qū)在搞福利,在廣場上給大家派發(fā)紅包。而壞人派了一批人形的機(jī)器人(沒有語言模塊)來冒領(lǐng)紅包,聰明工作人員需要想出辦法來防止紅包被冒領(lǐng)。

于是工作人員在發(fā)紅包之前,會(huì)給領(lǐng)取者一張紙,上面寫著“紅包拿來”,如果那人能念出紙上的字,那么就是人,給紅包,如果你不能念出來,那么請自覺。于是機(jī)器人便被識破,灰溜溜地回來了。

是的,在這個(gè)比喻中,人就是瀏覽器,機(jī)器人就是攻擊器,我們可以通過鑒別cookie功能(念紙上的字)的方式來鑒別他們。下面就是nginx的配置文件寫法。

if ($cookie_say != "hbnl"){
   add_header Set-Cookie "say=hbnl";
   rewrite .* "$scheme://$host$uri" redirect;
}

讓我們看下這幾行的意思,當(dāng)cookie中say為空時(shí),給一個(gè)設(shè)置cookie say為hbnl的302重定向包,如果訪問者能夠在第二個(gè)包中攜帶上cookie值,那么就能正常訪問網(wǎng)站了,如果不能的話,那他永遠(yuǎn)活在了302中。你也可以測試一下,用CC攻擊器或者webbench或者直接curl發(fā)包做測試,他們都活在了302世界中。

當(dāng)然,這么簡單就能防住了?當(dāng)然沒有那么簡單。

增強(qiáng)版

仔細(xì)的你一定會(huì)發(fā)現(xiàn)配置文件這樣寫還是有缺陷。如果攻擊者設(shè)置cookie為say=hbnl(CC攻擊器上就可以這么設(shè)置),那么這個(gè)防御就形同虛設(shè)了。我們繼續(xù)拿剛剛那個(gè)比喻來說明問題。

壞人發(fā)現(xiàn)這個(gè)規(guī)律后,給每個(gè)機(jī)器人安上了揚(yáng)聲器,一直重復(fù)著“紅包拿來,紅包拿來”,浩浩蕩蕩地又來領(lǐng)紅包了。

這時(shí),工作人員的對策是這樣做的,要求領(lǐng)取者出示有自己名字的戶口本,并且念出自己的名字,“我是xxx,紅包拿來”。于是一群只會(huì)嗡嗡叫著“紅包拿來”的機(jī)器人又被攆回去了。

當(dāng)然,為了配合說明問題,每個(gè)機(jī)器人是有戶口本的,被趕回去的原因是不會(huì)念自己的名字,雖然這個(gè)有點(diǎn)荒誕,唉。

然后,我們來看下這種方式的配置文件寫法

if ($cookie_say != "hbnl$remote_addr"){
   add_header Set-Cookie "say=hbnl$remote_addr";
   rewrite .* "$scheme://$host$uri" redirect;
}

這樣的寫法和前面的區(qū)別是,不同IP的請求cookie值是不一樣的,比如IP是1.2.3.4,那么需要設(shè)置的cookie是say=hbnl1.2.3.4。于是攻擊者便無法通過設(shè)置一樣的cookie(比如CC攻擊器)來繞過這種限制。你可以繼續(xù)用CC攻擊器來測試下,你會(huì)發(fā)現(xiàn)CC攻擊器打出的流量已經(jīng)全部進(jìn)入302世界中。

不過大家也能感覺到,這似乎也不是一個(gè)萬全之計(jì),因?yàn)楣粽呷绻芯苛司W(wǎng)站的機(jī)制之后,總有辦法測出并預(yù)先偽造cookie值的設(shè)置方法。因?yàn)槲覀冏霾町惢臄?shù)據(jù)源正是他們本身的一些信息(IP、user agent等)。攻擊者花點(diǎn)時(shí)間也是可以做出專門針對網(wǎng)站的攻擊腳本的。

完美版

那么要如何根據(jù)他們自身的信息得出他們又得出他們算不出的數(shù)值?

我想,聰明的你一定已經(jīng)猜到了,用salt加散列。比如md5("opencdn$remote_addr"),雖然攻擊者知道可以自己IP,但是他無法得知如何用他的IP來計(jì)算出這個(gè)散列,因?yàn)樗悄娌怀鲞@個(gè)散列的。當(dāng)然,如果你不放心的話,怕cmd5.com萬一能查出來的話,可以加一些特殊字符,然后多散幾次。

很可惜,nginx默認(rèn)是無法進(jìn)行字符串散列的,于是我們借助nginx_lua模塊來進(jìn)行實(shí)現(xiàn)。

rewrite_by_lua '
   local say = ngx.md5("opencdn" .. ngx.var.remote_addr)
   if (ngx.var.cookie_say ~= say) then
     ngx.header["Set-Cookie"] = "say=" .. say
     return ngx.redirect(ngx.var.scheme .. "://" .. ngx.var.host .. ngx.var.uri)
   end
';

通過這樣的配置,攻擊者便無法事先計(jì)算這個(gè)cookie中的say值,于是攻擊流量(代理型CC和低級發(fā)包型CC)便在302地獄無法自拔了。

大家可以看到,除了借用了md5這個(gè)函數(shù)外,其他的邏輯和上面的寫法是一模一樣的。因此如果可以的話,你完全可以安裝一個(gè)nginx的計(jì)算散列的第三方模塊來完成,可能效率會(huì)更高一些。

這段配置是可以被放在任意的location里面,如果你的網(wǎng)站有對外提供API功能的話,建議API一定不能加入這段,因?yàn)锳PI的調(diào)用也是沒有瀏覽器行為的,會(huì)被當(dāng)做攻擊流量處理。并且,有些弱一點(diǎn)爬蟲也會(huì)陷在302之中,這個(gè)需要注意。

同時(shí),如果你覺得set-cookie這個(gè)動(dòng)作似乎攻擊者也有可能通過解析字符串模擬出來的話,你可以把上述的通過header來設(shè)置cookie的操作,變成通過高端大氣的js完成,發(fā)回一個(gè)含有doument.cookie=...的文本即可。

那么,攻擊是不是完全被擋住了呢?只能說那些低級的攻擊已經(jīng)被擋住而來,如果攻擊者必須花很大代價(jià)給每個(gè)攻擊器加上webkit模塊來解析js和執(zhí)行set-cookie才行,那么他也是可以逃脫302地獄的,在nginx看來,確實(shí)攻擊流量和普通瀏覽流量是一樣的。那么如何防御呢?下節(jié)會(huì)告訴你答案。

0x02 請求頻率限制

不得不說,很多防CC的措施是直接在請求頻率上做限制來實(shí)現(xiàn)的,但是,很多都存在著一定的問題。

那么是哪些問題呢?

首先,如果通過IP來限制請求頻率,容易導(dǎo)致一些誤殺,比如我一個(gè)地方出口IP就那么幾個(gè),而訪問者一多的話,請求頻率很容易到上限,那么那個(gè)地方的用戶就都訪問不了你的網(wǎng)站了。

于是你會(huì)說,我用SESSION來限制就有這個(gè)問題了。嗯,你的SESSION為攻擊者敞開了一道大門。為什么呢?看了上文的你可能已經(jīng)大致知道了,因?yàn)榫拖衲莻€(gè)“紅包拿來”的揚(yáng)聲器一樣,很多語言或者框架中的SESSION是能夠偽造的。以PHP為例,你可以在瀏覽器中的cookie看到PHPSESSIONID,這個(gè)ID不同的話,session也就不同了,然后如果你杜撰一個(gè)PHPSESSIONID過去的話,你會(huì)發(fā)現(xiàn),服務(wù)器也認(rèn)可了這個(gè)ID,為這個(gè)ID初始化了一個(gè)會(huì)話。那么,攻擊者只需要每次發(fā)完包就構(gòu)造一個(gè)新的SESSIONID就可以很輕松地躲過這種在session上的請求次數(shù)限制。

那么我們要如何來做這個(gè)請求頻率的限制呢?

首先,我們先要一個(gè)攻擊者無法杜撰的sessionID,一種方式是用個(gè)池子記錄下每次給出的ID,然后在請求來的時(shí)候進(jìn)行查詢,如果沒有的話,就拒絕請求。這種方式我們不推薦,首先一個(gè)網(wǎng)站已經(jīng)有了session池,這樣再做個(gè)無疑有些浪費(fèi),而且還需要進(jìn)行池中的遍歷比較查詢,太消耗性能。我們希望的是一種可以無狀態(tài)性的sessionID,可以嗎?可以的。

rewrite_by_lua '
   local random = ngx.var.cookie_random
   if(random == nil) then
     random = math.random(999999)
   end
   local token = ngx.md5("opencdn" .. ngx.var.remote_addr .. random)
   if (ngx.var.cookie_token ~= token) then
     ngx.header["Set-Cookie"] = {"token=" .. token, "random=" .. random}
     return ngx.redirect(ngx.var.scheme .. "://" .. ngx.var.host .. ngx.var.uri)
   end
';

大家是不是覺得好像有些眼熟?是的,這個(gè)就是上節(jié)的完美版的配置再加個(gè)隨機(jī)數(shù),為的是讓同一個(gè)IP的用戶也能有不同的token。同樣的,只要有nginx的第三方模塊提供散列和隨機(jī)數(shù)功能,這個(gè)配置也可以不用lua直接用純配置文件完成。

有了這個(gè)token之后,相當(dāng)于每個(gè)訪客有一個(gè)無法偽造的并且獨(dú)一無二的token,這種情況下,進(jìn)行請求限制才有意義。

由于有了token做鋪墊,我們可以不做什么白名單、黑名單,直接通過limit模塊來完成。

http{
   ...
   limit_req_zone $cookie_token zone=session_limit:3m rate=1r/s;
}

然后我們只需要在上面的token配置后面中加入

limit_req zone=session_limit burst=5;

于是,又是兩行配置便讓nginx在session層解決了請求頻率的限制。不過似乎還是有缺陷,因?yàn)楣粽呖梢酝ㄟ^一直獲取token來突破請求頻率限制,如果能限制一個(gè)IP獲取token的頻率就更完美了。可以做到嗎?可以。

http{
   ...
   limit_req_zone $cookie_token zone=session_limit:3m rate=1r/s;
   limit_req_zone $binary_remote_addr $uri zone=auth_limit:3m rate=1r/m;
}
location /{
   limit_req zone=session_limit burst=5;
   rewrite_by_lua '
   local random = ngx.var.cookie_random
   if (random == nil) then
     return ngx.redirect("/auth?url=" .. ngx.var.request_uri)
   end
   local token = ngx.md5("opencdn" .. ngx.var.remote_addr .. random)
   if (ngx.var.cookie_token ~= token) then
     return ngx.redirect("/auth?url=".. ngx.var.request_uri)
   end
';
}
location /auth {
   limit_req zone=auth_limit burst=1;
   if ($arg_url = "") {
     return403;
   }
   access_by_lua '
     local random = math.random(9999)
     local token = ngx.md5("opencdn" .. ngx.var.remote_addr .. random)
     if (ngx.var.cookie_token ~= token) then
       ngx.header["Set-Cookie"] = {"token=" .. token, "random=" .. random}
       return ngx.redirect(ngx.var.arg_url)
     end
   ';
}

我想大家也應(yīng)該已經(jīng)猜到,這段配置文件的原理就是:把本來的發(fā)token的功能分離到一個(gè)auth頁面,然后用limit對這個(gè)auth頁面進(jìn)行頻率限制即可。這邊的頻率是1個(gè)IP每分鐘授權(quán)1個(gè)token。當(dāng)然,這個(gè)數(shù)量可以根據(jù)業(yè)務(wù)需要進(jìn)行調(diào)整。

需要注意的是,這個(gè)auth部分我lua采用的是access_by_lua,原因在于limit模塊是在rewrite階段后執(zhí)行的,如果在rewrite階段302的話,limit將會(huì)失效。因此,這段lua配置我不能保證可以用原生的配置文件實(shí)現(xiàn),因?yàn)椴恢廊绾斡门渲梦募趓ewrite階段后進(jìn)行302跳轉(zhuǎn),也求大牛能夠指點(diǎn)一下啊。

當(dāng)然,你如果還不滿足于這種限制的話,想要做到某個(gè)IP如果一天到達(dá)上限超過幾次之后就直接封IP的話,也是可以的,你可以用類似的思路再做個(gè)錯(cuò)誤頁面,然后到達(dá)上限之后不返回503而是跳轉(zhuǎn)到那個(gè)錯(cuò)誤頁面,然后錯(cuò)誤頁面也做個(gè)請求次數(shù)限制,比如每天只能訪問100次,那么當(dāng)超過報(bào)錯(cuò)超過100次(請求錯(cuò)誤頁面100次)之后,那天這個(gè)IP就不能再訪問這個(gè)網(wǎng)站了。

于是,通過這些配置我們便實(shí)現(xiàn)了一個(gè)網(wǎng)站訪問頻率限制。不過,這樣的配置也不是說可以完全防止了攻擊,只能說讓攻擊者的成本變高,讓網(wǎng)站的扛攻擊能力變強(qiáng),當(dāng)然,前提是nginx能夠扛得住這些流量,然后帶寬不被堵死。如果你家門被堵了,你還想開門營業(yè),那真心沒有辦法了。

然后,做完流量上的防護(hù),讓我們來看看對于掃描器之類的攻擊的防御。

0x03 防掃描

ngx_lua_waf模塊

這個(gè)是一個(gè)不錯(cuò)的waf模塊,這塊我們也就不再重復(fù)造輪子了??梢灾苯佑眠@個(gè)模塊來做防護(hù),當(dāng)然也完全可以再配合limit模塊,用上文的思路來做到一個(gè)封IP或者封session的效果。

0x04 總結(jié)

本文旨在達(dá)到拋磚引玉的作用,我們并不希望你直接單純的復(fù)制我們的這些例子中的配置,而是希望根據(jù)你的自身業(yè)務(wù)需要,寫出適合自身站點(diǎn)的配置文件。

相關(guān)文章

  • Windows設(shè)置nginx開機(jī)自啟動(dòng)的方法

    Windows設(shè)置nginx開機(jī)自啟動(dòng)的方法

    這篇文章主要介紹了Windows設(shè)置nginx開機(jī)自啟動(dòng)的方法,通過兩種方式實(shí)現(xiàn)nginx的開機(jī)自啟動(dòng):winws和window計(jì)劃程序,每種方式給大家介紹的非常詳細(xì)需要的朋友可以參考下
    2022-11-11
  • Nginx端口映射配置方法

    Nginx端口映射配置方法

    這篇文章主要介紹了Nginx端口映射配置方法和多端口映射,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-06-06
  • 聊聊Django+uwsgi+nginx服務(wù)器部署問題

    聊聊Django+uwsgi+nginx服務(wù)器部署問題

    這篇文章主要介紹了Django+uwsgi+nginx服務(wù)器部署的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • Nginx設(shè)置靜態(tài)頁面壓縮和緩存過期時(shí)間的方法

    Nginx設(shè)置靜態(tài)頁面壓縮和緩存過期時(shí)間的方法

    這篇文章主要介紹了Nginx設(shè)置靜態(tài)頁面壓縮和緩存過期時(shí)間的方法,也是服務(wù)器架設(shè)后的必備設(shè)置,需要的朋友可以參考下
    2015-07-07
  • Nginx主機(jī)域名配置實(shí)現(xiàn)

    Nginx主機(jī)域名配置實(shí)現(xiàn)

    本文主要介紹了Nginx主機(jī)域名配置實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • 解讀nginx反向代理location和proxy_pass的映射關(guān)系

    解讀nginx反向代理location和proxy_pass的映射關(guān)系

    這篇文章主要介紹了解讀nginx反向代理location和proxy_pass的映射關(guān)系,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Nginx 502 Bad Gateway錯(cuò)誤常見的4種原因和解決方法

    Nginx 502 Bad Gateway錯(cuò)誤常見的4種原因和解決方法

    這篇文章主要介紹了Nginx 502 Bad Gateway錯(cuò)誤常見的4種原因和解決方法,本文適用FastCGI環(huán)境,其中多數(shù)原因通過配置相關(guān)參數(shù)即可解決,需要的朋友可以參考下
    2015-05-05
  • nginx rewrite功能使用場景分析

    nginx rewrite功能使用場景分析

    這篇文章主要介紹了nginx rewrite功能使用,rewrite是Nginx服務(wù)器提供的一個(gè)重要基本功能,主要作用用來實(shí)現(xiàn)URL地址重寫,需要的朋友可以參考下
    2022-05-05
  • Nginx安裝及配置詳細(xì)分析

    Nginx安裝及配置詳細(xì)分析

    這篇文章主要介紹了Nginx在各種系統(tǒng)和環(huán)境中的安裝及配置詳細(xì)分析。
    2017-11-11
  • Nginx增添api接口的實(shí)現(xiàn)方法

    Nginx增添api接口的實(shí)現(xiàn)方法

    這篇文章給大家介紹了Nginx增添api接口的方法,文章通過代碼示例介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,具有一定的參考價(jià)值,需要的朋友可以參考下
    2023-10-10

最新評論