haproxy 如何在任何重定向之前处理 /.well-known?

haproxy 如何在任何重定向之前处理 /.well-known?

我想创建一个监听端口 80 的 haproxy 配置,并且:

  1. 当路径以 /.well-known/acme-challenge 开头时,无论域名是什么,都使用 use_backend

  2. 将 http 重定向到 https 以获取多个域的其他路径,egatest 到https://a.test

我尝试了这种配置:

use_backend certbot_80 if { path -m reg ^/.well-known/acme-challenge/ } 
redirect prefix https://a.test if { hdr_reg(host) '^a\.test(?::.*)?$' }

但它不起作用,因为 haproxy 进程在 use_backend 之前重定向。

这有效:

acl certbot path -m reg ^/.well-known/acme-challenge/
redirect prefix https://a.test if ! certbot { hdr_reg(host)  '^a\.test(?::.*)?$' }
use_backend certbot_80 if certbot

但是我必须在每次重定向中专门排除 certbot 条件。如果我有更多路径需要先处理,我必须在每次重定向中排除所有路径。

有没有办法可以做到这一点,同时保持每种情况都与其他情况分开?

我之前使用的是 pound,它按顺序处理混合重定向和后端。

答案1

恐怕无法处理use_backend之前的redirect语句。我相信 HAPROXY 在收到来自客户端的整个 HTTP 请求后才会评估重定向,并且只有在发现客户端不会被重定向后才会选择后端。

您无需修改​​每个重定向规则即可添加其他排除路径。您可以改用唯一的 ACL。例如,此配置代码片段将起作用:

acl noredirects path -m reg ^/.well-known/acme-challenge/
acl noredirects path -m beg /static/ /images/ /css/
acl noredirects req.hdr(host) -i httpsite.example.com
redirect prefix https://a.test if ! noredirects { req.hdr(host) -m reg ^a\.test(?::.*)?$ }
use_backend certbot_80 if noredirects

您还可以在后端处理重定向。例如:

frontend http *:80
    acl certbot  path -m beg /.well-known/acme-challenge/
    acl httpsite path -m beg /public/
    use_backend certbot_80 if certbot
    use_backend httpbackend if httpsite
    default_backend redirector

backend redirector
    redirect prefix https://a.test if { req.hdr(host) -m reg ^a\.test(?::.*)?$ }
    redirect prefix https://b.test if { req.hdr(host) -m reg ^b\.test(?::.*)?$ }

backend httpbackend
    server httpserver httpserver.example.com:80

答案2

使用现代 HAProxy(使用 2.2 LTS 测试),语法非常直观:

frontend http *:80
    acl path_certbot path_beg /.well-known/acme-challenge/
    http-request redirect scheme https unless { ssl_fc } || path_certbot
    use_backend certbot_80 if path_certbot
    default_backend std_backend

backend certbot
    server certbot localhost:80

backend std_backend
    <your_backend>
  • 第一行创建一个命名条件 (path_certbot),如果 URL 以以下格式开头,则为真/.well-known/acme-challenge/
  • 第二行将所有传入请求重定向(使用 HTTP/302)到 https,除非请求已经是 https,或者 path_certbot 条件被激活

相关内容