I am new to HAProxy and got most parts working as expected. The current setup is: If I add a new site to one of the balanced (behind the LB) servers, the certificate is issued and served by the Load Balancer. So SSL Termination is working fine with regular Let's Encrypt certificates, but I have a limitation in this setup by the service I am using:
If I add a new site to a balanced server and want to use a wildcard *.wilddomain.com certificate, it is not issued by the Load Balancer, but by the balanced server (10.0.0.10). As LE validation is done over DNS, the wildcard certificate is valid and available on the balanced server now.
So now I have a Load Balancer with several "regular" LE certs which are used corretly, and a server behind which holds the wildcard certificate.
My question is: How can I set up HAProxy to passthrough to the wildcard certificate only for a specific domain (wilddomain.com) while serving all other certificates directly from the LB with SSL Termination.
My current config is this:
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 # Default SSL material locations ca-base /etc/ssl/certs crt-base /etc/ssl/private # Default ciphers to use on SSL-enabled listening sockets. # For more information, see ciphers(1SSL). This list is from: # https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ # An alternative list with additional directives can be obtained from # https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy ssl-default-bind-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-> 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 # Default Let's Encrypt backend server used for renewals and requesting certificates backend letsencrypt-backend server letsencrypt 127.0.0.1:8888 # Load balancer settings frontend load-balancer bind *:80 bind *:443 ssl crt /etc/ssl/domain1.com/domain1.com.pem crt /etc/ssl/domain2.com/domain1.com.pem redirect scheme https code 301 if !{ ssl_fc } # See if its an letsencrypt request acl letsencrypt-acl path_beg /.well-known/acme-challenge/ use_backend letsencrypt-backend if letsencrypt-acl mode http default_backend webservers # Backend webservers (the attached servers to the load balancer) backend webservers balance roundrobin option forwardfor cookie SRVNAME insert http-request set-header X-Forwarded-Port %[dst_port] http-request add-header X-Forwarded-Proto https if { ssl_fc } # Server www1 server www1 10.0.0.10:80 weight 1 check # Server www2 server www2 10.0.0.11:80 weight 1 check EDIT I
I came a bit further by adding the following to the above config, but this produces "load-balancer/2: SSL handshake failure" in the HAProxy logs.
frontend wildcard_tcp bind *:443 option tcplog mode tcp tcp-request inspect-delay 5s tcp-request content accept if { req_ssl_hello_type 1 } acl is_wilddomain req_ssl_sni -m end wilddomain.com use_backend wildcard_server_tcp if is_wilddomain backend wildcard_server_tcp mode tcp server ssl-wildcard-server 10.0.0.10:443 Is this a suitable and correct solution? Or is there a better / more performant one? Would it be even possible to have a very basic backend server that is only responsible for the ssl-offload? So only for issuing, renewing and serving the certificates?
Thanks so much!
wilddomain.comis provided, you want haproxy to build a L4 tunnel that leaves the backend server do the ssl-offload?