Certbot with HAproxy and SSL Passtrough

#1

Hi there,

I just start to learn about SSL, webservers and this stuff. So bare with me… :slight_smile:

Resently I purchased a Web-Rootserver and there installed Proxmox. In short this is a Debian Linux with WebGUI for KVM and LXC. I just use LXC cause my Root Server is a KVM Machine already.

With my Root Server comes an external IPv4 Adress and I can connect to the WebGUI of Proxmox using the external IP and the Port 8006. Promox also using it´s on ACME Client to get Let´s Encrypt Certificates for it´s WebGUI.

Since I want to use some different LXC Containers on this system, and all of them should be accessable from the web, I created a virtual Interface and redirected everything on Port 80 and 443 coming from external to a haproxy machine running on that virtual interface. I also redirected Port 1936 for the haproxy stats.

Then I created the following rules for haproxy:

global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon

    tune.ssl.default-dh-param 4096
    ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!$
    ssl-default-bind-options no-sslv3

defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http

frontend main_http
bind *:80
mode http

    acl test01 hdr(host) -i test01.die-dormanns.de
    acl test02 hdr(host) -i test02.die-dormanns.de

    use_backend test01.die-dormanns.de if test01
    use_backend test02.die-dormanns.de if test02

    backend test01.die-dormanns.de
            mode http
  		balance roundrobin
            option httpchk HEAD / HTTP/1.0
            server test1-01 10.60.10.201:80 check
  		server test2-01 10.60.10.203:80 check

    backend test02.die-dormanns.de
            mode http
  		balance roundrobin
            option httpchk HEAD / HTTP/1.0
            server test2-01 10.60.10.202:80 check
  		server test2-02 10.60.10.204:80 check

frontend main_https
bind *:443
mode tcp
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }

    acl test01.ssl req_ssl_sni -i test01.die-dormanns.de
    acl test02.ssl req_ssl_sni -i test02.die-dormanns.de

    use_backend test01.die-dormanns.de.ssl if test01.ssl
    use_backend test02.die-dormanns.de.ssl if test02.ssl

    backend test01.die-dormanns.de.ssl
            mode tcp
  		balance roundrobin
            option ssl-hello-chk
            server test1-01 10.60.10.201:443 check
  		server test2-01 10.60.10.203:443 check

    backend test02.die-dormanns.de.ssl
            mode tcp
  		balance roundrobin
            option ssl-hello-chk
            server test2-01 10.60.10.202:443 check
  		server test2-02 10.60.10.204:443 check

listen stats
bind *:1936
mode http
stats enable
stats uri /
stats hide-version
stats auth

Now I was able to connect to some webservers with http and after creating a SSL Cert via Certbot, also via https. Works like a charme.

But for me there is now one downside. I´m now unable to issue a cert for the Proxmox system and haproxy itself. Since all traffic at port 80 is redirected to haproxy.

Is there some way to solve this problem?

After all, every LXC container should be able to get it´s own SSL cert via Certbot or some other ACME Client. Also haproxy and Proxmox should get one.

Could you help me out please?

Kind regards,

JAD

#2

This is one of the more creative Proxmox setups I’ve seen … there is usually a way to do this in a much more straightforward way.

What you probably want to do, is to intercept only the port 80 /.well-known/acme-challenge request for the hostname of your Proxmox host, and route it to the Certbot process running on the Proxmox host:

So it would look something like (untested):

frontend main_http
    # ...
    use_backend certbot_standalone if { hdr(host) -i PROXMOX.die-dormanns.de } { path_beg /.well-known/acme-challenge/ }

backend certbot_standalone
    # Substitute 127.0.0.1 for wherever Certbot actually is running
    server certbot_standalone_01 127.0.0.1:402

and then on the Proxmox host:

certbot certonly --standalone --http-01-port 402 -d PROXMOX.die-dormanns.de