我目前正在使用 1.5dev-17 重新配置 HAProxy。我想要做的是,当没有后端可用于特定请求时返回 404 错误。
我们当前的配置使用 default_backend 来路由到我们的 django 应用服务器,但是当有大量探测请求(如渗透测试)与其他配置的后端都不匹配时,我们的 django 服务器在尝试满足这些无效请求时会陷入停顿,最终返回 404。
我想从 HAProxy 提供 404 服务,而不是委托给 django 后端。我目前正在通过 hack 实现此目的:
frontend www
...
default_backend nomatch
backend nomatch
errorfile 503 /var/www/http/404.http
我在 404.http 文件中的标头中设置了 404 状态代码。这可行,但感觉非常不对劲。有没有更好的方法使用 HAProxy 实现这一点?或者我应该使用常规后端并让它处理 404 响应?
答案1
如果您可以接受以下任一响应代码:200、400、403、405、408、429、500、502、503 或 504。
然后你可以做这样的事情:
frontend www
...
default_backend no-match
backend no-match
mode http
http-request deny deny_status 400
http-request
:http://cbonte.github.io/haproxy-dconv/1.7/configuration.html#4-http-request- 接受的响应代码描述如下
errorfile
:http://cbonte.github.io/haproxy-dconv/1.7/configuration.html#errorfile
编辑:HAProxy 的较新版本也支持 404 作为返回代码:https://docs.haproxy.org/2.4/configuration.html#3.8-errorfile
答案2
在想要类似的东西之后,我想出了同样的东西。感觉不对,但在实践中效果很好,而且比试图将特定网址列入黑名单要干净得多。只需留下评论,这样就不会有人认为这是不正确的。
答案3
这不是 OP 要求的,但如果你在使用 TCP 模式时偶然发现了这一点(就像我一样),那么你想要使用的相应指令是tcp-request content
。因此,你应该:
frontend my-tcp
...
default_backend no-match
backend no-match
tcp-request content reject
当然,在 TCP 模式下没有 HTTP 响应代码。如果您愿意,也可以使用silent-drop
代替。reject
请注意不能使用tcp-request connection
因为backend
它不能在部分中使用。如果您尝试将其放在某个frontend
部分中,haproxy
则会发出警告:
'tcp-request' 规则放置在 'use_backend' 规则之后,仍将先处理
...这意味着它会覆盖您的所有use_backend
和default_backend
指令。
虽然从技术上来说能使用tcp-response content
,在这个用例中没有充分的理由这样做(与使用 相比)tcp-request content
。