Haproxy for HTTPS as a web proxy to internal lan

Hi All,

I configured an haproxy ( 1.8.19 ) on a debian 10 running on AWS services, then I configured a static VPN from AWS to our office.

I created config for HTTP on default port with particular ACL for a specific domain.
This is an example under HTTP

frontend apache_front_http
bind *:80
mode http
acl www_net req.hdr(Host) -i www.xxxx.it
acl www_net req.hdr(Host) -i xxxx.it

    use_backend backend_www if www_net
    default_backend    apache_back_http

backend backend_www
mode http
server webserver-www 192.168.10.38:80 check. ( this is an office’s IP )

backend apache_back_http
mode http
server webserver 77.xx.xxx.xxx:80 check ( this is a public ip )

With HTTP everything is working fine.

The issue begin when i try to use HTTPS
the ACL doesn’t work and all traffic are instradate to the default_backend

These are my last test configuration for HTTPS

frontend apache_front_https
bind *:443
option tcplog
mode tcp

     acl www_net_s req.hdr(Host) if { req_ssl_sni -i xxxx.it }
     acl www_net_s req.hdr(Host) if { req_ssl_sni -i www.xxxx.it }

     use_backend backend_www_S if www_net_s
     default_backend apache_back_https

backend backend_www_S
mode tcp
option ssl-hello-chk
server webserver-www-S 192.168.10.38:443 check

backend apache_back_https
mode tcp
option ssl-hello-chk
server webserver-ccs 77.xx.xx.xxx:443 check

Can someone can explain me the issue and why it doesn’t work.

Thanks

acl www_net_s req.hdr(Host) if { req_ssl_sni -i xxxx.it }

This compares the - in TCP mode not existing - Host header with the strings if, {, req_ssl_sni, -i, xxxx.it and }.

Not what you want.

You need to decide whether you want to terminate SSL on haproxy (installing certificates on haproxy), so that you can actually use http mode and inspect the Host header.

Or you don’t touch SSL and leave it as is, by looking at the SNI value to decide which backend to pick. However you have to a) wait for the entire client_hello to be accessible in the buffer, an b) the certificates on the backend must not overlap with each other, otherwise a browser will reuse a connection it isn’t supposed to reuse.

Something like:

frontend apache_front_https
 bind *:443
 option tcplog
 mode tcp
 
 tcp-request inspect-delay 5s
 tcp-request content accept if { req_ssl_hello_type 1 }
 
 acl www_net_s req_ssl_sni -i xxxx.it
 acl www_net_s req_ssl_sni -i www.xxxx.it

 use_backend backend_www_S if www_net_s
 
 default_backend apache_back_https

Thanks, now it works fine.