使用Nginx、Nginx Plus防止服務器DDoS攻擊

分佈式拒絕服務攻擊(DDoS)指的是經過多臺機器向一個服務或者網站發送大量看似合法的數據包使其網絡阻塞、資源耗盡從而不能爲正經常使用戶提供正常服務的攻擊手段。隨着互聯網帶寬的增長和相關工具的不斷髮布,這種攻擊的實施難度愈來愈低,有大量IDC託管機房、商業站點、遊戲服務商一直飽受DDoS攻擊的困擾,那麼如何緩解甚至解決DDoS呢?最近Rick Nelson在Nginx的官方博客上發表了一篇文章,介紹了如何經過Nginx和Nginx Plus緩和DDoS攻擊php

Rick Nelson首先介紹了DDoS攻擊的一些特色,例如攻擊的流量一般來源於一些固定的IP地址,每個IP地址會建立比真實用戶多得多的鏈接和請求;同時因爲流量所有是由機器產生的,其速率要比人類用戶高的多。此外,進行攻擊的機器其User-Agent頭也不是標準的值,Referer頭有時也會被設置成可以與攻擊關聯起來的值。針對這些特色,Rick Nelson認爲Nginx和Nginx Plus有不少可以經過調節或控制流量來應對或者減輕DDoS攻擊的特性。html

限制請求率 將Nginx和Nginx Plus可接受的入站請求率限制爲某個適合真實用戶的值。例如,經過下面的配置讓一個真正的用戶每兩秒鐘才能訪問一次登陸頁面:nginx

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

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

在該配置中, limit_req_zone指令配置了一個名爲 one的共享內存 zone用來存儲$binary_remote_addr的請求狀態,location塊中/login.html的 limit_req指令引用了共享內存zoneweb

限制鏈接的數量 將某個客戶端IP地址所能打開的鏈接數限制爲真實用戶的合理值。例如,限制每個IP對網站/store部分打開的鏈接數不超過10個:後端

limit_conn_zone $binary_remote_addr zone=addr:10m;

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

該配置中, limit_conn_zone指令配置了一個名爲 addr的共享內存 zone用來存儲 $binary_remote_addr的請求,location塊中/store/的 limit_conn指令引用了共享內存zone,並將最大鏈接數設置爲10.緩存

關閉慢鏈接 關閉那些一直保持打開同時寫數據又特別頻繁的鏈接,由於它們會下降服務器接受新鏈接的能力。Slowloris就是這種類型的攻擊。對此,能夠經過 client_body_timeoutclient_header_timeout指令控制請求體或者請求頭的超時時間,例如,經過下面的配置將等待時間控制在5s以內:服務器

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

設置IP黑名單 若是能識別攻擊者所使用的客戶端IP地址,那麼經過 deny指令將其屏蔽,讓Nginx和Nginx Plus拒絕來自這些地址的鏈接或請求。例如,經過下面的指令拒絕來自123.123.123.三、123.123.123.5和123.123.123.7的請求:網絡

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

設置IP白名單 若是容許訪問的IP地址比較固定,那麼經過 allowdeny指令讓網站或者應用程序只接受來自於某個IP地址或者某個IP地址段的請求。例如,經過下面的指令將訪問限制爲本地網絡的一個IP段:分佈式

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

經過緩存削減流量峯值 經過啓用緩存並設置某些緩存參數讓Nginx和Nginx Plus吸取攻擊所產生的大部分流量峯值。例如,經過 proxy_cache_use_stale指令的 updating參數告訴Nginx什麼時候須要更新過時的緩存對象,避免因重複發送更新請求對後端服務器產生壓力。另外, proxy_cache_key指令定義的鍵一般會包含嵌入的變量,例如默認的鍵 $scheme$proxy_host$request_uri包含了三個變量,若是它包含 $query_string變量,那麼攻擊者能夠經過發送隨機的 query_string值來耗盡緩存,所以,若是沒有特別緣由,不要在該鍵中使用 $query_string變量。工具

阻塞請求 配置Nginx和Nginx Plus阻塞如下類型的請求:

  • 以某個特定URL爲目標的請求
  • User-Agent頭中的值不在正常客戶端範圍以內的請求
  • Referer頭中的值可以與攻擊關聯起來的請求
  • 其餘頭中存在可以與攻擊關聯在一塊兒的值的請求

例如,經過下面的配置阻塞以/foo.php爲目標的攻擊:

location /foo.php {
    deny all;
}

或者經過下面的配置阻塞已識別出的User-Agent頭的值是foo或者bar的DDoS攻擊:

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

限制對後端服務器的鏈接數 一般Nginx和Nginx Plus實例可以處理比後端服務器多得多的鏈接數,所以能夠經過Nginx Plus限制到每個後端服務器的鏈接數。例如,經過下面的配置限制Nginx Plus和每一臺後端服務器之間創建的鏈接數很少於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;
}

另外,Rick Nelson還提到了如何處理基於範圍的攻擊如何處理高負載的問題,以及如何使用Nginx Plus Status模塊發現異常的流量模式,定位DDoS攻擊。

相關文章
相關標籤/搜索