使用 haproxy 对每个 url 每个 ip 进行速率限制

使用 haproxy 对每个 url 每个 ip 进行速率限制

我们的服务器不断受到攻击。这不是 DDOS。只是一个 IP 每秒攻击一个 URL 超过 200 次。目前我正在通过 IP 表阻止用户。我们正在使用 HAproxy 进行负载平衡。有没有办法根据用户的 IP 和被攻击的 URL 来限制用户?

我不想仅基于 IP 进行阻止,因为 NAT 用户可能会受到影响。假设我想在某个 IP 在 5 分钟内访问同一网址(如 www.example.com/somepage.php?some=option&other=option2)超过 3000 次时显示 503 错误页面?这意味着同一 IP 可以访问其他网址(如 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 标头的连接字符串上应用转换器的方法。

我应用哈希函数是为了确保您不会在 stick-table 中存储巨大的字符串,因为这很容易导致拒绝服务。如果您认为由于可能的冲突太多,此哈希函数不适合您,您还可以通过对每个连接的组件应用 crc32 来使其更大(当然,在存储数据并切换到更大的 stick-table 存储时将其删除),如下所示:

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 }

请注意,对于 stick 表中的每个条目,最后一个解决方案将使用比第一个解决方案多 7 倍的内存。当然,碰撞风险也会小得多。

相关内容