Haproxy reusing wrong backend when using tcp mode

This is because you are routing based on SNI. SNI is in the SSL client_hello, the initial packet of the SSL handshake, but once the initial packet is send and haproxy has made a routing decision (based on the unencrypted SNI value), the specific TCP connection stays on that backend. Haproxy becomes a TCP tunnel.

But because on the backend for backoffice.mydomain.com you are serving a certificate that is also valid for chat.mydomain.com (due to wildcard or multi-SAN certificates), the browser will use the same TCP/SSL connection for that, even though this is not what you expect.

Because service1.backoffice.mydomain.com is not a valid hostname in the certificate the backend for backoffice.mydomain.com is serving.

For example a wildcard certificate *.mydomain.com is INVALID for service1.backoffice.mydomain.com, so the browser does not reuse the connection, because it already knows that the backend server is not authoritative for this.

Solutions: either find a way to load-balance not based on SNI (for example, by terminating SSL on the first haproxy layer) and looking at the host header, or you need to make sure that one certificate is not valid for a different service (not using wildcard certificates, don’t add SANs for other services into your multi SAN certificate).

3 Likes