HAproxy route to default backend, when req.hdr(host) is not in map file

Hello,

I have configured my HAproxy CE 1.8.19-1+deb10u3 with two backends. To decide which host (req.hdr(host)) belongs to which backend, I use maps, because I can configure them quite easily via REST with Dataplane. But, before I started using haproxy, I already had a lot of vhosts (= subdomains) and if I don’t have to do it, I don’t want to write them all to the map file, just the new ones. Which shouldn’t be a problem, because all my already existing vhosts were configured on one server (= backend), and all new vhosts will be configured either on the same server ( = then don’t create a new map entry) or on the new server ( = then create a new map entry).

So my HAproxy has to look if the called domain (e.g. abc.example.com) is in the map file. If it is, then the backend from the map value should be used. If the host is not in the map file, then a hardcoded backend should be used.

An important point is that when using SSL, the HAproxy should not do an SSL termination (so instead a SSL pass-through) !

Right now I have following configuration (snippet) :

frontend http_in 
  mode http
  bind *:80
  option forwardfor
  option httplog
  use_backend %[req.hdr(host),lower,map_str(/etc/haproxy/maps/my_backends.map,http-hardcoded_backend)]

# HTTPS Frontend
frontend https_in 
  mode tcp
  bind *:443
  option tcplog
  tcp-request inspect-delay 5s
  use_backend %[req.hdr(host),lower,map_str(/etc/haproxy/maps/my_backends.map,https-hardcoded_backend)]

# == BACKEND - SECTION ==
#
# hardcoded_backend = my old server
backend http-hardcoded_backend
  mode http
  option forwardfor
  server OLDSERVER 10.0.150.22:80

backend https-hardcoded_backend
  mode tcp
  option ssl-hello-chk
  server OLDSERVER 10.0.150.22:443

# http(s) backend from map value
backend http-mapvalue
  mode http
  option forwardfor
  server MAPVALUE 10.0.150.20:80

backend https-mapvalue
  mode tcp
  option ssl-hello-chk
  server MAPVALUE 10.0.150.20:443

For HTTP, this works (so when I visit a host, which is inside the host file, I get to the “http-mapvalue” backend. When the host is not in the host file, I get to the “http-hardcoded_backend” ), but over HTTPS I get following error message (with cURL):
curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to abc.my.domain:443
one both backends.

EDIT:
By adding tcp-request content accept if { req_ssl_hello_type 1 } I get at least requests and therefore logs on my HAproxy. I guess this works now but for some reason, the haproxy doesnt detect the right backend?

[16/Dec/2020:16:09:09.461] https_in https_in/<NOSRV> -1/-1/14 0 SC 1/1/0/0/0 0/0

On HTTP everything works (still) fine, but on HTTPS, which has the same use_backend line it doesn’t.

HTTPS is encrypted, meaning you cannot access the HTTP header.

IF your SSL certificates do not have any overlaps, then you can use SNI instead.

tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend %[req_ssl_sni,lower,map_str(/etc/haproxy/maps/my_backends.map,https-hardcoded_backend)]