Set SNI based on the Host header on the outgoing TLS connections

Hi,

I have the requirement that an incoming SNI is passed along to the backend.
On the backend the SNI is returned as ~ and not the actual requested SNI from HaProxy.

This is the config in play:

frontend development-sites
  bind 10.145.50.110:443 ssl crt /root/.vault/development.nethavn.dev.pem
  mode tcp
  option tcplog
  log-format "%ci:%cp [%t] %ft %b/%s %ST %B sni:%[ssl_fc_sni]"
  tcp-request inspect-delay 5s
  tcp-request content accept if { req_ssl_hello_type 1 }

  default_backend nethavn-sites-dp
backend nethavn-sites-dp
  mode tcp
  server nethavn-sites-dp 10.0.0.135:91 check send-proxy-v2 sni req.hdr(host)

I’m not sure what else I can check/set. The SNI is correctly passed to the frontend just fine and it is confirmed via the specific logging I set. The sni parameter in the backend was added to test if it worked with it, but also no luck there.

Could you help me? Google/StackOverflow wasn’t really helpful sadly.
Thanks!

It’s absolutely not clear what you want to do.

Do you just want to pass TCP traffic from 10.145.50.110:443 to 10.0.0.135:91? Then stop terminating SSL and just connect the two without SSL termination, that is, without ssl keyword and certificate configuration.

Then SNI is never touched because the TCP payload is unchanged.

Do you want to terminate SSL for whatever reason? Then you need reencrypt the traffic again on your backend (putting ssl keyword and verification configuration in the backend server statement).

Currently you are terminating SSL on the frontend and sending plaintext traffic to the backend on port 91. Of course plaintext traffic cannot have SNI, because it is not SSL.

Accessing the HTTP Host header is not possible when in TCP mode, you need to be in HTTP mode for that.

Thanks Lukas.

I want HaProxy to be serving the client with the certificate and TLS. So the termination should remain.
However I need the SNI to be passed to the backend by any means necessary.

Does this clarify things?

Then you need to reencrypt on the backend, like I said:

The Backend (:91) is running without a SSL configuration. I’m not 100% sure if I understand your answer.
I did this now:

# nethavn Sites DP
backend nethavn-sites-dp
  mode tcp
  server nethavn-sites-dp 10.0.0.135:91 send-proxy-v2 ssl verify none sni req.hdr(host)

I have not changed anything else. But I might need to?

Thank you.

You need to clarify:

Does your backend server 10.0.0.135 on port 91 support the binary proxy-v2 protocol? If not, you need to remove send-proxy-v2.

Is your backend server 10.0.0.135 on port 91 actually SSL enabled? If not, there is no way to send SNI.

Again, if you want to access the HTTP headers (like with req.hdr(host)) you are required to switch it all to http mode (replace mode tcp with mode http).

Thank You, no, the Backend was not SSL enabled. I just did this now and it works flawlessly.
Thanks for your help und guidance.

Have a nice rest of the day!

For anyone else, this is the final solution:

frontend development-sites
  bind 10.145.50.110:443 ssl crt /root/.vault/development.nethavn.dev.pem
  mode http
  option tcplog
  log-format "%ci:%cp [%t] %ft %b/%s %ST %B sni:%[ssl_fc_sni]"
  tcp-request inspect-delay 5s
  tcp-request content accept if { req_ssl_hello_type 1 }

  default_backend nethavn-sites-dp
backend nethavn-sites-dp
  mode http
  server nethavn-sites-dp 10.0.0.135:91 check send-proxy-v2 sni req.hdr(host)

And then the backend (:91) needs to be SSL enabled in order to pass down the SNI.