使用 haproxy 每個 url 每個 ip 進行速率限制

使用 haproxy 每個 url 每個 ip 進行速率限制

我們的伺服器不斷受到攻擊。它不是 DDOS。僅一個 ip 每秒訪問一個 url 的次數就會超過 200 次。目前我正在透過 ip 表阻止用戶。我們使用 HAproxy 進行負載平衡。有沒有辦法根據用戶的ip和被點擊的url來限制用戶?

我不想僅基於 IP 進行阻止,因為經過 NAT 處理的用戶可能會受到影響。假設我想顯示 503 錯誤頁面,如果某個特定 ip 在 5 分鐘內點擊相同的 url(例如 www.example.com/somepage.php?some=option&other=option2)超過 3000 次?這意味著相同的 IP 可以存取其他 url,例如 www.example.com/somepage.php?another=someotheroption。

答案1

該解決方案至少需要 haproxy 1.6。

首先,將以下內容新增至前端:

http-request set-header X-DOS-Protect %[src];%[req.fhdr(host)]%[capture.req.uri]

然後,在後端添加以下內容:

stick-table type integer size 1m expire 5m store http_req_rate(5m)
tcp-request inspect-delay 5s
tcp-request content track-sc0 req.fhdr(X-DOS-Protect),crc32(1) if HTTP
http-request tarpit if { sc0_http_req_rate gt 3000 }

我無法找到在前端進行追蹤的方法,因為我沒有找到在構成 X-DOS-Protect 標頭的連接字串上套用轉換器的方法。

我應用哈希函數是為了確保您不會在黏表中儲存巨大的字串,因為它很容易導致拒絕服務。如果您認為這個雜湊函數由於太多可能的衝突而不適合您,您還可以通過將 crc32 應用於每個連接的組件來使其更大(當然,在存儲數據並切換到一個更大的棒表存儲),如下所示:

http-request set-header X-DOS-Protect %[src,crc32(1)];%[req.fhdr(host),crc32(1)]%[capture.req.uri,crc32(1)]

stick-table type string len 30 size 1m expire 5m store http_req_rate(5m)
tcp-request inspect-delay 5s
tcp-request content track-sc0 req.fhdr(X-DOS-Protect) if HTTP
http-request tarpit if { sc0_http_req_rate gt 3000 }

請注意,對於棒表中的每個條目,最後一個解決方案將使用比第一個解決方案多 7 倍的記憶體。當然,碰撞的風險也會小得多。

相關內容