1. 程式人生 > >Nginx防攻擊的三種方法

Nginx防攻擊的三種方法

1. ngx_http_limit_conn_module 可以用來限制單個IP的連線數:

ngx_http_limit_conn_module 模組可以按照定義的鍵限定每個鍵值的連線數。特別的,可以設定單一 IP 來源的連線數。

並不是所有的連線都會被模組計數;只有那些正在被處理的請求(這些請求的頭資訊已被完全讀入)所在的連線才會被計數。

配置範例

http {
    limit_conn_zone $binary_remote_addr zone=addr:10m;

    ...

    server {

        ...

        location /download/ {
            limit_conn addr 1;
        }

指令

語法: limit_conn zone number;
預設值:
上下文: http, server, location

指定一塊已經設定的共享記憶體空間,以及每個給定鍵值的最大連線數。當連線數超過最大連線數時,伺服器將會返回503 (Service Temporarily Unavailable)錯誤。比如,如下配置

limit_conn_zone $binary_remote_addr zone=addr:10m;

server {
    location /download/ {
        limit_conn addr 1;
    }

表示,同一 IP 同一時間只允許有一個連線。

當多個 limit_conn 指令被配置時,所有的連線數限制都會生效。比如,下面配置不僅會限制單一IP來源的連線數,同時也會限制單一虛擬伺服器的總連線數:

limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;

server {
    ...
    limit_conn perip 10;
    limit_conn perserver 100;
}

如果當前配置層級沒有limit_conn指令,將會從更高層級繼承連線限制配置。

語法: limit_conn_log_level
info |notice |warn |error;
預設值:
limit_conn_log_level error;
上下文: http, server, location

這個指令出現在版本 0.8.18.

指定當連線數超過設定的最大連線數,伺服器限制連線時的日誌等級。

語法: limit_conn_zone $variable zone=name:size;
預設值:
上下文: http

設定儲存各個鍵的狀態的共享記憶體空間的引數。鍵的狀態中儲存了當前連線數。鍵的值可以是特定變數的任何非空值(空值將不會被考慮)。使用範例:

limit_conn_zone $binary_remote_addr zone=addr:10m;

這裡,設定客戶端的IP地址作為鍵。注意,這裡使用的是$binary_remote_addr變數,而不是$remote_addr變數。$remote_addr變數的長度為7位元組到15位元組不等,而儲存狀態在32位平臺中佔用32位元組或64位元組,在64位平臺中佔用64位元組。而$binary_remote_addr變數的長度是固定的4位元組,儲存狀態在32位平臺中佔用32位元組或64位元組,在64位平臺中佔用64位元組。一兆位元組的共享記憶體空間可以儲存3.2萬個32位的狀態,1.6萬個64位的狀態。如果共享記憶體空間被耗盡,伺服器將會對後續所有的請求返回503 (Service Temporarily Unavailable)錯誤。

語法: limit_zone name $variablesize;
預設值:
上下文: http

這條指令在 1.1.8 版本中已經被廢棄,應該使用等效的limit_conn_zone指令。該指令的語法也有變化:

limit_conn_zone$variablezone=name:size;


2. ngx_http_limit_req_module 可以用來限制單個IP每秒請求數

ngx_http_limit_req_module模組(0.7.21)可以通過定義的鍵值來限制請求處理的頻率。特別的,它可以限制來自單個IP地址的請求處理頻率。限制的方法是通過一種“漏桶”的方法——固定每秒處理的請求數,推遲過多的請求處理。

配置示例

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

    ...

    server {

        ...

        location /search/ {
            limit_req zone=one burst=5;
        }

指令

語法: limit_req zone=name [burst=number] [nodelay];
預設值:
上下文: http, server, location

設定對應的共享記憶體限制域和允許被處理的最大請求數閾值。如果請求的頻率超過了限制域配置的值,請求處理會被延遲,所以所有的請求都是以定義的頻率被處理的。超過頻率限制的請求會被延遲,直到被延遲的請求數超過了定義的閾值這時,這個請求會被終止,並返回503 (Service Temporarily Unavailable)錯誤。這個閾值的預設值等於0。比如這些指令:

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

server {
    location /search/ {
        limit_req zone=one burst=5;
    }

限制平均每秒不超過一個請求,同時允許超過頻率限制的請求數不多於5個。

如果不希望超過的請求被延遲,可以用nodelay引數:

limit_req zone=one burst=5 nodelay;
語法: limit_req_log_level info |notice |warn |error;
預設值:
limit_req_log_level error;
上下文: http, server, location

這個指令出現在版本 0.8.18.

設定你所希望的日誌級別,當伺服器因為頻率過高拒絕或者延遲處理請求時可以記下相應級別的日誌。延遲記錄的日誌級別比拒絕的低一個級別;比如,如果設定“limit_req_log_level notice”,延遲的日誌就是info級別。

語法: limit_req_zone $variable zone=name:sizerate=rate;
預設值:
上下文: http

設定一塊共享記憶體限制域的引數,它可以用來儲存鍵值的狀態。它特別儲存了當前超出請求的數量。鍵的值就是指定的變數(空值不會被計算)。示例用法:

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

這裡,狀態被存在名為“one”,最大10M位元組的共享記憶體裡面。對於這個限制域來說平均處理的請求頻率不能超過每秒一次。

鍵值是客戶端的IP地址。如果不使用$remote_addr變數,而用$binary_remote_addr變數,可以將每條狀態記錄的大小減少到64個位元組,這樣1M的記憶體可以儲存大約1萬6千個64位元組的記錄。如果限制域的儲存空間耗盡了,對於後續所有請求,伺服器都會返回503 (Service Temporarily Unavailable)錯誤。

請求頻率可以設定為每秒幾次(r/s)。如果請求的頻率不到每秒一次,你可以設定每分鐘幾次(r/m)。比如每秒半次就是30r/m。

3. nginx_limit_speed_module 可以用來對IP限速

https://github.com/yaoweibin/nginx_limit_speed_module