TCP frontend verify SNI, then redirect HTTP and HTTPS traffic

Hello,

over at the OPNsense forum I created a widely used tutorial for configuring HAProxy with Let’s Encrypt on OPNsense. To me this setup can always be improved. This is way I am coming here for advise.

Current setup

Only TCP port 80 and 443 are exposed to the WAN.
The SNI_frontend defaults to redirecting traffic using an address on the localhost to the HTTP_frontend and HTTPS_frontend.
This is so I can also have TCP based services like OpenVPN exposed using port 443.
All of the above is currently working just fine.

The HTTPS_frontend is currently defaulting to the SUSPICIOUS_SNI_backend with only a http-request silent-drop rule on it, that will take action if no matching SNI record can be found in a mapfile or rule.
While this is also working fine it still presents the user with “Error: Secure connection failed”.

Setting this http-request silent-drop directly on the SNI_frontend works as intended and the connection times out.

What is the goal?
In short I would like to perform the SNI check directly on the SNI_frontend.

  1. HAProxy should verifiy the FQDN that is beeing accessed against a mapfile.
  2. The mapfile contains only the valid FQDNs redirecting them all to the SSL_backend.
  3. If no matching FQDN can be found the http-request silent-drop should take action.

Attempted config

The below config is working fine for HTTP traffic.
Valid FQDNs accessing the SNI_frontend using HTTP get redirected to the HTTP_frontend via the SSL_backend and from there redirected to HTTPS_frontend.
Invalid/Unknown FQDNs receive the http-request silent-drop.

However the below config is not working at all for HTTPS traffic. No matter if the FQDN is valid or not.
HTTPS traffic is always presented with “Error: Secure connection failed”.
The log indicates that the traffic gets stuck at the SNI_frontend.
The HTTPS_frontend gets no hits whatsoever.

logfile
2023-12-05T13:43:45	Informational	haproxy	Connect from CLIENT_PUBLIC_IP:38137 to HAPROXY_PUBLIC_IP:443 (0_SNI_frontend/TCP)	
2023-12-05T13:43:42	Informational	haproxy	Connect from CLIENT_PUBLIC_IP:61996 to HAPROXY_PUBLIC_IP:80 (1_HTTP_frontend/HTTP)	
2023-12-05T13:43:42	Informational	haproxy	Connect from CLIENT_PUBLIC_IP:61996 to HAPROXY_PUBLIC_IP:80 (0_SNI_frontend/TCP)
relevant config export
# Frontend: 0_SNI_frontend (Listening on 0.0.0.0:80, 0.0.0.0:443)
frontend 0_SNI_frontend
    bind 0.0.0.0:80 name 0.0.0.0:80 
    bind 0.0.0.0:443 name 0.0.0.0:443 
    mode tcp
    default_backend SUSPICIOUS_SNI_backend

    # logging options
    # ACL: VALID_SNI_HTTP_condition
    acl acl_656a32a6dc8cf7.04655470 req.proto_http
    # ACL: VALID_SNI_SSL_condition
    acl acl_656a3297938019.26511022 req.ssl_hello_type 1

    # ACTION: TCP_RequestInspectDelay_rule
    # NOTE: actions with no ACLs/conditions will always match
    tcp-request inspect-delay 5s 
    # ACTION: VALID_SNI_REDIRECT_rule
    # NOTE: actions with no ACLs/conditions will always match
    use_backend %[req.hdr(host),lower,map_dom(/tmp/haproxy/mapfiles/6569ef70ad5e48.90806906.txt)] 
    # ACTION: VALID_SNI_HTTP_rule
    tcp-request content accept if acl_656a32a6dc8cf7.04655470
    # ACTION: VALID_SNI_SSL_rule
    tcp-request content accept if acl_656a3297938019.26511022
VALID_SNI_mapfile
# domain.com
cloud.domain.com SSL_backend
subdomain.domain.com SSL_backend
...

I hope someone can point me in the right direction.

Thank you very much!
TheHellSite