Configruation of a HAProxy for different subdomains and SSL Termination

HAProxy started in 2000 and is, besides Apache, one of the main reverse proxies and load balancer. The basic config, I would like to show here, is called haproxy.cfg. It includes the support of subdomains but no load balancing. Subdomains are located in front of the top and second-level-domain. For example, the en of https://en.wikipedia.org/ is a subdomain.

Starting with the config with the standard timeouts and location of the:

global
  stats socket /var/run/api.sock user haproxy group haproxy mode 660 level admin expose-fd listeners
  log stdout format raw local0 info

defaults
  mode http
  timeout client 10s
  timeout connect 5s
  timeout server 10s
  timeout http-request 10s
  log global

The next block contains the frontend stats. This part is optional. It requires the accessiblility to this port and allows the access to a panel with some stats via the browser

frontend stats
  bind *:8404
  stats enable
  stats uri /
  stats refresh 10s

Now starts the fun, the definition of the mode and the ports, through which the traffic enters. In this case we bind to port 80 for normal http requests. The second port, we bind is port 443. It is used for SSL traffic, which can be identified by the s in https. To allow https we must provide the respective certificates, which can be obtained for example from letsencrypt.com. In this case the default path is given to the certificates in a docker container including the name of the certificate. Multiple certificates can be concatenated with the keyword crt.

In the last step of this part, we redirect all traffic, which arrives on without https to https to ensure a save connection

frontend http_in
  mode http
  bind *:80
  bind *:443 ssl crt /usr/local/etc/haproxy/certificates/mydomain.com.pem crt /usr/local/etc/haproxy/certificates/subdomain.mydomain.com.pem
  http-request redirect scheme https unless { ssl_fc }

The next step is the splitting of the incoming traffic based on the subdomains test1 and test2 on the docker container in the network. Therefore ACL (Access Control List) must be defined. The second step includes the mapping to a backend. The first rule, which is true will be applied. Therefore, the fallback httpd is defined at the ending. Finally, the definition of the backends is shown.

  acl web1 hdr_dom(host) -i test1.mydomain.com
  acl web2 hdr_dom(host) -i test2.mydomain.com

  use_backend web1 if web1
  use_backend web2 if web2
  use_backend httpd_app_1

  #backend web1
  mode http
  server web1 web1:8080

  #backend web2
  mode http
  server web2 web2:8080

  backend httpd_app_1
  mode http
  server httpd_app_1 httpd_app_1:8080