I have one domain with several sub-domains. All of them point to my VPS. I use docker in swarm mode to run my web services and my (HA)proxy. I also use Certbot/Let’s Encrypt in standalone to get the certificate for my domain.
Everything seems to be working fine except the HAproxy configuration for certbot. Here is my HAProxy config:
defaults
mode http
log global
option httplog
option dontlognull
timeout check 5s
timeout connect 5s
timeout client 50s
timeout client-fin 50s
timeout server 50s
timeout tunnel 1h
resolvers docker
nameserver dns1 127.0.0.11:53
resolve_retries 3
timeout resolve 1s
timeout retry 1s
hold other 10s
hold refused 10s
hold nx 10s
hold timeout 10s
hold valid 10s
hold obsolete 10s
# HTTP(S) frontend
frontend web-in
bind *:80
bind *:443 ssl crt /etc/ssl/haproxy.pem
# test URI to see if its a letsencrypt request
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
use_backend be-letsencrypt if letsencrypt-acl
# sub-domains
acl sub1 hdr(host) -i sub1.mydomain.com
acl sub2 hdr(host) -i sub2.mydomain.com
acl sub3 hdr(host) -i sub3.mydomain.com
# figure out which one to use
use_backend be-sub1 if sub1
use_backend be-sub2 if sub2
use_backend be-sub3 if sub3
# Default
default_backend maintenance
# Backend | LE
backend be-letsencrypt
server letsencrypt dockerhost:8888 check resolvers docker init-addr none
# Sub1
backend be-sub1
option forwardfor
http-request add-header X-Forwarded-Proto https
redirect scheme https code 301 if !{ ssl_fc }
server sub1-server webservice1:8080 check resolvers docker init-addr libc,none
# ... Sub2, Sub3 ...
# Default backend
backend maintenance
balance roundrobin
I expect all the following urls:
mydomain.com/.well-known/acme-challenge/
sub1.mydomain.com/.well-known/acme-challenge/
sub2.mydomain.com/.well-known/acme-challenge/
sub3.mydomain.com/.well-known/acme-challenge/
to resolve to dockerhost:8888
. But instead I always get 503 Service Unavailable
.
To test the configuration I run dockercloud/hello-world
on the port 8888
docker run --rm -d -p 8888:80 dockercloud/hello-world
I know that dockerhost:8888
resolution work fine as I can test it with the following configuration:
# Sub1
backend be-sub1
server letsencrypt dockerhost:8888 check resolvers docker init-addr none
Meaning that when I hit my syb-domain sub1.mydomain.com
I end up on the dockercloud/hello-world
"Hello world!" page.
So why path based resolution doesn't work ? Am I missing something ?
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
use_backend be-letsencrypt if letsencrypt-acl