Nginx 限制連線數 (ngx_http_limit_conn_module)
說明
本篇文章介紹 Nginx 的限制連線數模組 ngx_http_limit_conn_module,說明可用指令和基本範例。限制連線數通常用來防止 DDOS 等惡意攻擊,該模組有以下指令:
- limit_conn_zone
- limit_conn
- limit_conn_dry_run
- limit_conn_log_level
- limit_conn_status
指令
limit_conn_zone
標題 | 內容 |
---|---|
語法 | limit_conn_zone key zone=name:size; |
預設值 | - |
Context | http |
這個指令是定義規則,相關的參數如下
key
:可以視為符合的條件,例如照 IP、Server Name 或國家等等不同條件,參考最後的範例。name
:唯一名稱。size
:配置多少記憶體。
簡單的例子
1 | limit_conn_zone $binary_remote_addr zone=perip:10m; |
limit_conn
標題 | 內容 |
---|---|
語法 | limit_conn zone number; |
預設值 | - |
Context | http , server , location |
設定連線數,相關的參數如下
zone
:limit_conn_zone 自訂的名稱number
:連線數
limit_conn_dry_run
標題 | 內容 |
---|---|
語法 | limit_conn_dry_run on | off; |
預設值 | off |
Context | http , server , location |
測試模式,可以在 log 中看到規則生效的訊息,但實際上不會真的擋掉連線。Log 大概如下:
1 | 2024/06/20 14:44:32 [error] 2473#2473: *8287599 limiting connections, dry run, by zone "perip", client: 123.123.123.123, server: example.com, request: "GET /mypath HTTP/1.1", host: "example.com" |
會看到有 dry run 的字樣。
limit_conn_log_level
標題 | 內容 |
---|---|
語法 | limit_conn_log_level info | notice | warn | error; |
預設值 | error |
Context | http , server , location |
設定限制連線相關 Log 的等級,相關 log 都會輸出到 error.log 中。由於預設 error.log 只記錄 error 等級,所以這邊如果改成 warn 的話預設會看不到。要搭配修改 error_log,例如:
1 | error_log /var/log/nginx/error.log warn; |
就會看到相關 log 變成 warn
1 | 2024/06/20 14:44:32 [warn] 2473#2473: *8287599 limiting connections, ... |
limit_conn_status
標題 | 內容 |
---|---|
語法 | limit_conn_status code |
預設值 | 503 |
Context | http , server , location |
設定限制連線發生時回應的 HTTP Status Code。只能設定 400 - 599 之間。否則會看到下面錯誤:
1 | nginx: [emerg] value must be between 400 and 599 in /etc/nginx/sites-enabled/example:16 |
範例
限制 IP
每個 IP 10 個連線
1 | limit_conn_zone $binary_remote_addr zone=perip:10m; |
限制 Server Name
每個 Server name 100 個連線
1 | limit_conn_zone $server_name zone=perserver:10m; |
特定 Path
一次只能下載一個,可巢狀
1 | server { |
限制 Socket 連線數,例如 ActionCable:
1 | server { |
多重條件
可同時多組
1 | server { |
白名單 / 黑名單
limit_conn
不能用在 if
下,也不能用變數,沒辦法直接做出不同 IP 給不同連線數的設定。但 limit_conn_zone
可以用變數,下面的寫法為指定 IP 為白名單,不限制連線:
1 | map $remote_addr $not_whitelist { |
利用這個機制可以做出不同 IP 不同連線:
1 | map $remote_addr $not_whitelist { |
反過來用也可以作為黑名單使用。
設定建議
建議可以限制 WebSocket 和下載等,會長時間連線的地方,避免被惡意地佔滿連線。連線數上限可參考 Rails ActionCable 效能測試。
延伸閱讀
Nginx 限制請求速率 (ngx_http_limit_req_module)
Rails ActionCable 效能測試
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 小殘的程式光廊!
Comment