『葉狂人』的怕失憶筆記 Back-End

使用Nginx、Nginx Plus抵禦DDOS攻擊

DDOS是一種通過大流量的請求對目標進行轟炸式訪問,導致提供服務的服務器資源耗盡進而無法繼續提供服務的攻擊手段。

一般情況下,攻擊者通過大量請求與連接使服務器處於飽和狀態,以至於無法接受新的請求或變得很慢。

應用層DDOS攻擊的特徵

應用層(七層/HTTP層)DDOS攻擊通常由木馬程序發起,其可以通過設計更好的利用目標系統的脆弱點。例如,對於無法處理大量並發請求的系統,僅僅通過建立大量的連接,並週期性的發出少量數據包來保持會話就可以耗盡系統的資源,使其無法接受新的連接請求達到DDOS的目的。其他還有採用發送大量連接請求發送大數據包的請求進行攻擊的形式。因為攻擊是由木馬程序發起,攻擊者可以在很短時間內快速建立大量的連接,並發出大量的請求。

以下是一些DDOS的特證,我們可以據此特徵來抵抗DDOS(包括但不限於):

攻擊經常來源於一些相對固定的IP或IP段,每個IP都有遠大於真實用戶的連接數和請求數。
備註:這並不表明這種請求都是代表著DDOS攻擊。在很多使用NAT的網絡架構中,很多的客戶端使用網關的IP地址訪問公網資源。但是,即便如此,這樣的請求數和連接數也會遠少於DDOS攻擊。
因為攻擊是由木馬發出且目的是使服務器超負荷,請求的頻率會遠遠超過正常人的請求。
User-Agent通常是一個非標準的值
Referer有時是一個容易聯想到攻擊的值
使用Nginx、Nginx Plus抵抗DDOS攻擊

結合上面提到的DDOS攻擊的特徵,Nginx、Nginx Plus有很多的特性可以用來有效的防​​禦DDOS攻擊,可以從調整入口訪問流量和控制反向代理到後端服務器的流量兩個方面來達到抵禦DDOS攻擊的目的。

限制請求速度

設置Nginx、Nginx Plus的連接請求在一個真實用戶請求的合理範圍內。比如,如果你覺得一個正常用戶每兩秒可以請求一次登錄頁面,你就可以設置Nginx每兩秒鐘接收一個客戶端IP的請求(大約等同於每分鐘30個請求)。

limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m;

server {
  ...
  location /login.html {
    limit_req zone=one;
    ...
  }
}

limit_req_zone命令設置了一個叫one的共享內存區來存儲請求狀態的特定鍵值,在上面的例子中是客戶端IP($binary_remote_addr)。 location塊中的limit_req通過引用one共享內存區來實現限制訪問/login.html的目的。

限制連接數量

設置Nginx、Nginx Plus的連接數在一個真實用戶請求的合理範圍內。比如,你可以設置每個客戶端IP連接/store不可以超過10個。

limit_conn_zone $binary_remote_addr zone=addr:10m;

server {
  ...
  location /store/ {
    limit_conn addr 10;
    ...
  }
}

limit_conn_zone命令設置了一個叫addr的共享內存區來存儲特定鍵值的狀態,在上面的例子中是客戶端IP( $binary_remote_addr)。 location塊中limit_conn通過引用addr共享內存區來限製到/store/的最大連接數為10。
 

關閉慢連接

有一些DDOS攻擊,比如Slowlris,是通過建立大量的連接並週期性的發送一些數據包保持會話來達到攻擊目的,這種週期通常會低於正常的請求。這種情況我們可以通過關閉慢連接來抵禦攻擊。

client_body_timeout命令用來定義讀取客戶端請求的超時時間,client_header_timeout命令用來定於讀取客戶端請求頭的超時時間。這兩個參數的默認值都是60s,我們可以通過下面的命令將他們設置為5s:

server {
  client_body_timeout 5s;
  client_header_timeout 5s;
  ...
}

設置IP黑名單

如果確定攻擊來源於某些IP地址,我們可以將其加入黑名單,Nginx就不會再接受他們的請求。比如,你已經確定攻擊來自於從123.123.123.1到123.123.123.16的一段IP地址,你可以這樣設置:

location / {
  deny 123.123.123.0/28;
  ...
}

或者你確定攻​​擊來源於123.123.123.3、123.123.123.5、123.123.123.7幾個IP,可以這樣設置:

location / {
  deny 123.123.123.3;
  deny 123.123.123.5;
  deny 123.123.123.7;
  ...
}

設置IP白名單

如果你的網站僅允許特定的IP或IP段訪問,你可以結合使用allow和deny命令來限制僅允許你指定的IP地址訪問你的網站。如下,你可以設置僅允許192.168.1.0段的內網用戶訪問:

location / {
  allow 192.168.1.0/24;
  deny all;
  ...
}

deny命令會拒絕除了allow指定的IP段之外的所有其他IP的訪問請求。

使用緩存進行流量削峰

通過打開Nginx的緩存功能並設置特定的緩存參數,可以削減來自攻擊的流量,同時也可以減輕對後端服務器的請求壓力。以下是一些有用的設置:

proxy_cache_use_stale 的updating參數告訴Nginx什麼時候該更新所緩存的對象。只需要到後端的一個更新請求,在緩存有效期間客戶端對該對象的請求都無需訪問後端服務器。當通過對一個文件的頻繁請求來實施攻擊時,緩存功能可極大的降低到後端服務器的請求。
proxy_cache_key 命令定義的鍵值通常包含一些內嵌的變量(默認的鍵值$scheme$proxy_host$request_uri包含了三個變量)。如果鍵值包含$query_string變量,當攻擊的請求字符串是隨機的時候就會給Nginx代理過重的緩存負擔,因此我們建議一般情況下不要包含$query_string變量。
屏蔽特定的請求

可以設置Nginx、Nginx Plus屏蔽一些類型的請求:

針對特定URL的請求
針對不是常見的User-Agent的請求
針對Referer頭中包含可以聯想到攻擊的值的請求
針對其他請求頭中包含可以聯想到攻擊的值的請求
比如,如果你判定攻擊是針對一個特定的URL:/foo.php,我們就可以屏蔽到這個頁面的請求:

location /foo.php {
  deny all;
}

或者你判定攻擊請求的User-Agent中包含foo或bar,我們也可以屏蔽這些請求:

location / {
  if ($http_user_agent ~* foo|bar) {
    return 403;
  }
  ...
}

http_name變量引用一個請求頭,上述例子中是User-Agent頭。可以針對其他的http頭使用類似的方法來識別攻擊。

限製到後端服務器的連接數

一個Nginx、Nginx Plus實例可以處理比後端服務器多的多的並發請求。在Nginx Plus中,你可以限製到每一個後端服務器的連接數,比如可以設置Nginx Plus與website upstream中的每個後端服務器建立的連接數不得超過200個:

upstream website {
  server 192.168.100.1:80 max_conns=200;
  server 192.168.100.2:80 max_conns=200;
  queue 10 timeout=30s;
}

​max_conns參數可以針對每一個後端服務器設置Nginx Plus可以與之建立的最大連接數。 queue命令設置了當每個後端服務器都達到最大連接數後的隊列大小,timeout參數指定了請求在隊列中的保留時間。

處理特定類型的攻擊

有一種攻擊是發送包含特別大的值的請求頭,引起服務器端緩衝區溢出。 Nginx、Nginx Plus針對這種攻擊類型的防禦,可以參考[Using NGINX and NGINX Plus to Protect Against CVE-2015-1635](http://nginx.com/blog/nginx-protect-cve-2015-1635/ ?_ga=1.14368116.2137319792.1439284699)

優化Nginx性能

DDOS攻擊通常會帶來高的負載壓力,可以通過一些調優參數,提高Nginx、Nginx Plus處理性能,硬抗DDOS攻擊,

詳細參考:[Tuning NGINX for Performance](http://nginx.com/blog/tuning-nginx/?_ga=1.48422373.2137319792.1439284699)

識別DDOS攻擊

到目前為止,我們都是集中在如何是用Nginx、Nginx Plus來減輕DDOS攻擊帶來的影響。如何才能讓Nginx、Nginx Plus幫助我們識別DDOS攻擊呢? Nginx Plus Status module提供了到後端服務器流量的詳細統計,可以用來識別異常的流量。 Nginx Plus提供一個當前服務狀態的儀錶盤頁面,同時也可以在自定義系統或其他第三方系統中通過API的方式獲取這些統計信息,並根據歷史趨勢分析識別非正常的流量進而發出告警。

總結

Nginx和Nginx Plus可以作為抵禦DDOS攻擊的一個有力手段,而且Nginx Plus中提供了一些附加的特性來更好的抵禦DDOS攻擊並且當攻擊發生時及時的識別到。

『葉狂人』的怕失憶筆記, author
「心思別一直想著出錯的地方,把重點放在下一步要做什麼。精力要用來朝著找出答案的方向前進。」
《樂在工作》作者 丹尼斯魏特利