我想创建一个监听端口 80 的 haproxy 配置,并且:
当路径以 /.well-known/acme-challenge 开头时,无论域名是什么,都使用 use_backend
将 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 条件被激活