限制請求數

限制請求數動作統計每個關鍵字在固定時間視窗內的請求總數。請求數超過拒絕閾值後,OpenResty Edge 對該關鍵字的後續請求執行指定的拒絕動作;進入新的時間視窗後,計數器重新計數。

適用場景

  • 限制登入嘗試、驗證碼傳送或密碼重置等敏感操作的呼叫次數。
  • 對 API 配額或週期內允許的請求總數進行控制。
  • 限制短時間內重複提交、批次查詢等自動化行為。

如果希望平滑持續流量,並在調節閾值和拒絕閾值之間延遲請求,請使用限制請求速率

工作原理

OpenResty Edge 根據一個或多個關鍵字對請求分組。每個分組在自己的固定時間視窗內獨立計數;計數超過拒絕閾值後,系統執行拒絕動作。新的時間視窗開始時,該分組的計數器重置為零。

配置方法

在目標應用的頁面規則中選擇 CC 攻擊防禦動作 > 限制請求數,然後配置關鍵字、拒絕閾值、時間視窗和拒絕動作。

限制請求數配置

引數說明

  1. 關鍵字:用於對請求分組並分別計數。預設使用客戶端 IP 地址,也可以選擇 URI、URI 引數等選項。支援組合多個關鍵字。選擇 URI 引數或 Cookie 時,還需要指定相應的引數或 Cookie 名稱。詳見關鍵字
  2. 拒絕閾值:一個時間視窗內允許的請求數上限。請求數超過該值後,系統執行拒絕動作。
  3. 時間視窗:請求計數的固定時間區間,單位為秒。進入新的時間視窗後,計數器重新計數。
  4. 拒絕動作:達到拒絕條件後執行的操作。詳見拒絕動作

關鍵字

限制請求數的關鍵字選項

可選的關鍵字包括:

  • 客戶端 IP 地址:例如 1.1.1.1
  • URI:例如 /openresty
  • URI 查詢引數:例如 /openresty?arg1=val1 中的 arg1
  • 請求 Cookie:例如 Cookie: c1=v1 中的 c1
  • X-Forwarded-For 中的第一個 IP 地址:例如 X-Forwarded-For: 1.1.1.1, 1.1.1.2 中的 1.1.1.1
  • X-Forwarded-For 中的最後一個 IP 地址:例如 X-Forwarded-For: 1.1.1.1, 1.1.1.2 中的 1.1.1.2
  • 指定的 HTTP 請求頭:例如 Host
  • 加密 Cookie:根據 OpenResty Edge 生成的加密 Cookie 區分客戶端。請求沒有攜帶加密 Cookie 時,系統需要回退到其他關鍵字,因此加密 Cookie 必須與其他關鍵字組合使用

使用 X-Forwarded-For 前,應確保該請求頭由可信代理維護,不能由客戶端任意偽造。

拒絕動作

達到拒絕條件後,系統可以執行以下預設動作。預設動作為 返回錯誤頁

限制請求數的拒絕動作

  • 關閉請求連線:立即終止與客戶端的連線,不再響應請求。
  • 返回錯誤頁:返回錯誤頁面,預設狀態碼為 503。
  • 完成 hCaptcha 驗證:要求客戶端透過 hCaptcha 挑戰。
  • 完成 OpenResty Edge Captcha 驗證:使用 OpenResty Edge 的驗證碼系統驗證使用者。
  • 重定向驗證:將請求重定向到驗證頁面,驗證透過後才能繼續訪問。
  • JavaScript 挑戰:要求客戶端瀏覽器執行 JavaScript 程式碼,以區分瀏覽器和簡單的自動化程式。
  • 私有訪問 Token:請求客戶端認證,沒有有效 Token 時執行配置的回退動作。 需要配置回退動作、必要的 頁面模板 和 清除時間(預設 60 秒)。詳見 私有訪問 Token。 此動作在 OpenResty Edge 26.9.1-1 中首次引入。
  • 標記為拒絕:僅將請求標記為拒絕,並繼續執行後續規則。此動作於 24.9.1-7 中首次引入。
  • 封禁 IP 地址:在作業系統層面丟棄來源 IP 的所有資料包。此動作於 26.3.1-1 中首次引入。

配置示例

以下配置表示:在每個 60 秒的時間視窗內,同一客戶端 IP 地址的第 1 個請求不受限制;請求數超過 1 後,系統返回 503 錯誤。

限制請求數示例

釋出配置後,可以使用 curl 模擬客戶端訪問。第一次訪問不會觸發限制;由於測試頁面不存在,源站返回 404:

$ curl -i -H 'host: test.com' http://node-host/404.html
HTTP/1.1 404 Not Found
Date: Fri, 04 Sep 2020 04:43:20 GMT
Content-Type: text/html
Content-Length: 150
Connection: keep-alive
Server: openresty+

<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>openresty</center>
</body>
</html>

在同一時間視窗內緊接著傳送第二個請求,將觸發限制並返回 503:

$ curl -i -H 'host: test.com' http://node-host/404.html
HTTP/1.1 503 Service Temporarily Unavailable
Date: Fri, 04 Sep 2020 04:43:21 GMT
Content-Type: text/html
Content-Length: 194
Connection: keep-alive
Server: openresty+

<html>
<head><title>503 Service Temporarily Unavailable</title></head>
<body>
<center><h1>503 Service Temporarily Unavailable</h1></center>
<hr><center>openresty</center>
</body>
</html>

等待當前時間視窗結束後再次請求,確認計數已經重置。

注意事項

  • 固定時間視窗會在視窗邊界重新計數。設定閾值時,應考慮業務是否可能在相鄰視窗邊界出現正常突發。
  • 只按客戶端 IP 地址計數時,共享 NAT 或代理後的使用者會共用額度。可以結合 URI、Cookie 或其他可信標識細分請求。
  • 對瀏覽器使用者優先考慮驗證碼等可恢復的拒絕動作;只有在確認來源 IP 惡意時,才使用作業系統層封禁。