当没有 acls 匹配时,从 HAProxy 提供 404 服务

当没有 acls 匹配时,从 HAProxy 提供 404 服务

我目前正在使用 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

编辑: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_backenddefault_backend指令。

虽然从技术上来说使用tcp-response content,在这个用例中没有充分的理由这样做(与使用 相比)tcp-request content

相关内容