1. 程式人生 > >nginx防止DDOS攻擊配置

nginx防止DDOS攻擊配置

轉自:http://www.escorm.com/archives/452

防禦DDOS是一個系統工程,攻擊花樣多,防禦的成本高瓶頸多,防禦起來即被動又無奈。DDOS的特點是分散式,針對頻寬和服務攻擊,也就 是四層流量攻擊和七層應用攻擊,相應的防禦瓶頸四層在頻寬,七層的多在架構的吞吐量。對於七層的應用攻擊,我們還是可以做一些配置來防禦的,例如前端是 Nginx,主要使用nginx的http_limit_conn和http_limit_req模組來防禦。 ngx_http_limit_conn_module 可以限制單個IP的連線數,ngx_http_limit_req_module 可以限制單個IP每秒請求數,通過限制連線數和請求數能相對有效的防禦CC攻擊。下面是配置方法:

一. 限制每秒請求數 
ngx_http_limit_req_module模組通過漏桶原理來限制單位時間內的請求數,一旦單位時間內請求數超過限制,就會返回503錯誤。配置需要在兩個地方設定:

nginx.conf的http段內定義觸發條件,可以有多個條件 
在location內定義達到觸發條件時nginx所要執行的動作 
例如:

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s; //觸發條件,所有訪問ip 限制每秒10個請求
    ...
    server {
        ...
        location  ~ \.php$ {
            limit_req zone=one burst=5 nodelay;   //執行的動作,通過zone名字對應
               }
           }
     }

引數說明:

$binary_remote_addr  二進位制遠端地址
zone=one:10m    定義zone名字叫one,併為這個zone分配10M記憶體,用來儲存會話(二進位制遠端地址),1m記憶體可以儲存16000會話
rate=10r/s;     限制頻率為每秒10個請求
burst=5         允許超過頻率限制的請求數不多於5個,假設1、2、3、4秒請求為每秒9個,那麼第5秒內請求15個是允許的,反之,如果第一秒內請求15個,會將5個請求放到第二秒,第二秒內超過10的請求直接503,類似多秒內平均速率限制。
nodelay         超過的請求不被延遲處理,設定後15個請求在1秒內處理。

二.限制IP連線數 
ngx_http_limit_conn_module的配置方法和引數與http_limit_req模組很像,引數少,要簡單很多

http {
    limit_conn_zone $binary_remote_addr zone=addr:10m; //觸發條件
    ...
    server {
        ...
        location /download/ {
            limit_conn addr 1;    // 限制同一時間內1個連線,超出的連線返回503 } } }

三.白名單設定 
http_limit_conn和http_limit_req模組限制了單ip單位時間內的併發和請求數,但是如果Nginx前面有lvs或者 haproxy之類的負載均衡或者反向代理,nginx獲取的都是來自負載均衡的連線或請求,這時不應該限制負載均衡的連線和請求,就需要geo和map 模組設定白名單:

geo $whiteiplist  {
        default 1;
        10.11.15.161 0; } map $whiteiplist $limit { 1 $binary_remote_addr; 0 ""; } limit_req_zone $limit zone=one:10m rate=10r/s; limit_conn_zone $limit zone=addr:10m;

geo模組定義了一個預設值是1的變數whiteiplist,當在ip在白名單中,變數whiteiplist的值為0,反之為1。如果在白名單中 whiteiplist=0 => limit==>10moneaddr=>=>whiteiplist=1=>limit=””=>不會儲存到10m的會話狀態(one或者addr)中=>不受限制反之,不在白名單中=>whiteiplist=1=>limit=二進位制遠端地址 =>儲存進10m的會話狀態中 => 受到限制

四.測試 
使用ab命令來模擬CC攻擊,http_limit_conn和http_limit_req模組要分開測試,同時注意 http_limit_conn模組只統計正在被處理的請求(這些請求的頭資訊已被完全讀入)所在的連線。如果請求已經處理完,連線沒有被關閉時,是不會 被統計的。這時用netstat看到連線數可以超過限定的數量,不會被阻止。

ab -n 請求數 -c 併發 http://10.11.15.174/i.php

如果被阻止前臺會返回503,同時在nginx的error_log中會看到如下錯誤日誌: 
被限制連線數:

2015/01/28 14:20:26 [error] 4107#0: *65525 limiting connections by zone "addr", client: 10.11.15.161, server: , request: "GET /i.php?=PHPE9568F35-D428-11d2-A769-00AA001ACF42 HTTP/1.1", host: "10.11.15.174", referrer: "http://10.11.15.174/i.php"

被限制請求數:

2015/01/28 14:18:59 [error] 4095#0: *65240 limiting requests, excess: 5.772 by zone "one", client: 10.11.15.161, server: , request: "GET /i.php?=PHPE9568F34-D428-11d2-A769-00AA001ACF42 HTTP/1.1", host: "10.11.15.174", referrer: "http://10.11.15.174/i.php"

五.其它一些防CC的方法 
1.Nginx模組 ModSecurity、http_guard、ngx_lua_waf

ModSecurity 應用層WAF,功能強大,能防禦的攻擊多,配置複雜 
ngx_lua_waf 基於ngx_lua的web應用防火牆,使用簡單,高效能和輕量級 
http_guard 基於openresty 
2.軟體+Iptables

fail2ban 通過分析日誌來判斷是否使用iptables攔截 
DDoS Deflate 通過netstat判斷ip連線數,並使用iptables遮蔽 
開頭說過抗DDOS是一個系統工程,通過優化系統和軟體配置,只能防禦小規模的CC攻擊,對於大規模攻擊、四層流量攻擊、混合攻擊來說,基本上系統和應用軟體沒掛,頻寬就打滿了。下面是我在工作中使用過的防禦DDOS的方式:

高防伺服器和帶流量清洗的ISP 通常是美韓的伺服器,部分ISP骨幹供應商有流量清洗服務,例如香港的PCCW。通常可以防禦10G左右的小型攻擊 
流量清洗服務 例如:akamai(prolexic),nexusguard 我們最大受到過80G流量的攻擊,成功被清洗,但是費用非常貴 
CDN 例如:藍訊 網宿 cloudflare 等,CDN針對DDOS的分散式特點,將流量引流分散,同時對網站又有加速作用,效果好,成本相對低。 
總結一下:發動攻擊易,防禦難。七層好防,四層難防;小型能防,大型燒錢