Nginx限制訪問速率和最大併發連接數模塊–limit (防止DDOS攻擊)
Tengine版本採用http_limit_req_module進行限制
具體連接請參考 http://tengine.taobao.org/document_cn/http_limit_req_cn.html
和官方nginx類似,不過支持多個變量,並且支持多個limit_req_zone的設置。比如:
limit_req_zone $binary_remote_addr zone=one:3m rate=1r/s;
limit_req_zone $binary_remote_addr $uri zone=two:3m rate=1r/s; # $uri:不帶客戶端請求參數
limit_req_zone $binary_remote_addr $request_uri zone=thre:3m rate=1r/s; # $request_uri:帶客戶端請求
- 1
- 2
- 3
參數
上面的第二個指令表示當相同的ip地址並且訪問相同的uri,會導致進入limit req的限制(每秒1個請求)。
Nginx官方版本限制IP的連接和併發分別有兩個模塊:
點擊以下超鏈接可查看對應模塊的官方詳細介紹
limit_req_zone 用來限制單位時間內的請求數,即速率限制,採用的漏桶算法 “leaky bucket”
limit_req_conn 用來限制同一時間連接數,即併發限制
其中limit_req_conn模塊可以根據源IP限制單用戶併發訪問的連接數或連接到該服務的總併發連接數
什麼是漏桶算法?
我們假設系統是一個漏桶,當請求到達時,就是往漏桶裏“加水”,而當請求被處理掉,就是水從漏桶的底部漏出。水漏出的速度是固定的,當“加水”太快,桶就會溢出,也就是“拒絕請求”。從而使得桶裏的水的體積不可能超出桶的容量。主要目的是控制數據注入到網絡的速率,平滑網絡上的突發流量。漏桶算法提供了一種機制,通過它,突發流量可以被整形以便爲網絡提供一個穩定的流量。
示例如下:
http {
limit_conn_log_level error;
limit_conn_status 503;
limit_conn_zone $binary_remote_addr zone=one:10m;
limit_conn_zone $server_name zone=perserver:10m;
limit_req_zone $binary_remote_addr zone=allips:100m rate=10r/s; 其中$binary_remote_addr有時需要根據自己已有的log_format變量配置進行替換
server {
…………………….
limit_conn one 100;
limit_conn perserver 1000;
limit_req zone=allips burst=5 nodelay;
………………….
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
參數解釋:
Zone=one或allips 表示設置了名爲“one”或“allips”的存儲區,大小爲10兆字節
rate=10r/s 的意思是允許1秒鐘不超過10個請求
burst=5 表示最大延遲請求數量不大於5。 如果太過多的請求被限制延遲是不需要的 ,這時需要使用nodelay參數,服務器會立刻返回503狀態碼。
limit_conn one 100表示最大併發連接數100
limit_conn perserver 1000表示該服務提供的總連接數不得超過1000,超過請求的會被拒絕
示例如下:
http {
limit_req_zone $binary_remote_addr zone=one:100m rate=10r/m;
server {
…………………….
…………………….
limit_req zone=one burst=1 nodelay;
………………….
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
rate=10r/m 的意思是允許1秒鐘不超過1個請求,最大延遲請求數量不大於5.
如果請求不需要被延遲,添加nodelay參數,服務器會立刻返回503狀態碼。如果沒有該字段會造成大量的tcp連接請求等待。
http{
limit_zone one $binary_remote_addr 10m;
server
{
......
limit_conn one 1;
......
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
這裏的 one 是聲明一個 limit_zone 的名字,$binary_remote_addr
是替代 $remore_addr
的變量,10m
是會話狀態儲存的空間
limit_conn one 1 ,限制客戶端併發連接數量爲1, allow only one connection per an IP address at a time(每次).
按照字面的理解,lit_req_zone的功能是通過漏桶原理來限制用戶的連接頻率,(這個模塊允許你去限制單個地址指定會話或特殊需要的請求數 )
而 limit_zone 功能是限制一個客戶端的併發連接數。(這個模塊可以限制單個地址的指定會話或者特殊情況的併發連接數)
一個是限制併發連接一個是限制連接頻率,表面上似乎看不出來有什麼區別,那就看看實際的效果吧~~~
在我的測試機上面加上這兩個參數下面是我的部分配置文件
http{
limit_zone one $binary_remote_addr 10m;
#limit_req_zone $binary_remote_addr zone=req_one:10m rate=1r/s;
server
{
......
limit_conn one 1;
#limit_req zone=req_one burst=120;
......
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
解釋一下 limit_zone one $binary_remote
_addr 10m;
這裏的 one 是聲明一個 limit_zone 的名字,$binary_remote_addr
是替代 $remore_addr
的變量,10m是會話狀態儲存的空間
limit_conn one 1 ,限制客戶端併發連接數量爲1
limit_zone兩種工作情況
- limit_reqzone=one burst=10 ;
i.默認情況下是這樣配置的,這樣每個請求就會有一個delay時間,
limit_req_zone$binary_remote_addr zone=one:100m rate=10r/m;
就是每分鐘有10個令牌供用戶使用,按照a的配置情況,就會有一個delay,每個請求時間就是60/10,那每個請求時間就是6s。 limit_reqzone=one burst=10 nodelay;
a). 添加nodelay配置,這樣就是根據你的網絡狀況訪問,一分鐘訪問夠10次後,服務器直接返回503。
b). Eg:imit_req_zone$binary_remote_addr zone=one:100m rate=10r/m;
就是每分鐘有10個令牌供用戶使用,按照b的配置情況,就會根據網絡情況訪問url,如果一分鐘超過10個令牌,服務器返回503,等待下一個一分鐘領取訪問令牌。
rate=10r/m 的意思是每個地址每分鐘只能請求10次,也就是說根據漏桶原理burst=1 一共有1塊令牌,並且每分鐘只新增10塊令牌,
1塊令牌發完後多出來的那些請求就會返回503
加上 nodelay之後超過 burst大小的請求就會直接返回503,如果沒有該字段會造成大量的tcp連接請求等待。
http{
...
#定義一個名爲allips的limit_req_zone用來存儲session,大小是10M內存,
#以$binary_remote_addr 爲key,限制平均每秒的請求爲20個,
#1M能存儲16000個狀態,rete的值必須爲整數,
#如果限制兩秒鐘一個請求,可以設置成30r/m
limit_req_zone $binary_remote_addr zone=allips:10m rate=20r/s;
...
server{
...
location {
...
#限制每ip每秒不超過20個請求,漏桶數burst爲5
#brust的意思就是,如果第1秒、2,3,4秒請求爲19個,
#第5秒的請求爲25個是被允許的。
#但是如果你第1秒就25個請求,第2秒超過20的請求返回503錯誤。
#nodelay,如果不設置該選項,嚴格使用平均速率限制請求數,
#第1秒25個請求時,5個請求放到第2秒執行,
#設置nodelay,25個請求將在第1秒執行。
limit_req zone=allips burst=5 nodelay;
...
}
...
}
...
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
限制下載速度:
location /download {
limit_rate 128k;
}
- 1
- 2
- 3
如果想設置用戶下載文件的前10m大小時不限速,大於10m後再以128kb/s限速可以增加以下配內容,修改nginx.conf文件
location /download {
limit_rate_after 10m;
limit_rate 128k;
}
- 1
- 2
- 3
- 4