haproxy how to process /.well-known before any redirects?
Solution 1:
I'm afraid it is not possible to process use_backend
before redirect
statements. I believe HAPROXY evaluates redirects after it receives the entire HTTP request from the client and chooses a backend only after it discovers that the client will not be redirected.
You do not need to modify every redirect rule in order to add additional exclusion paths. You can use an unique ACL instead. For example, this configuration snippet would work:
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
You can also process redirections on a backend. For example:
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
Solution 2:
With a modern HAProxy (tested with 2.2 LTS), the syntax is intuitive:
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>
- the first line creates a named condition (path_certbot) that is true it the url starts with
/.well-known/acme-challenge/
- the second line redirects (with a HTTP/302) all the incoming requests to https, unless the request was already https, or the path_certbot condition is activated