I am setting up HaProxy for https in passthrough (tcp) mode without SSL/TLS termination. I want to be able to route traffic to different backends based on hostname requested by a client.

From HaProxy documentation I learned that there is unencrypted SNI field that I can use to setup ACL rule.

My question is: Do most of the browser supporting SNI feature, send this field by default? Do other tools like curl or wget send it too?


All modern browser support SNI and use it by default (there is probably not even a away to switch it off). Current versions of most tools like curl use SNI too by default, but not all. For example with openssl s_client* you explicitly need to specify -servername ...if you want to use SNI and in some programming languages SNI is only used by default if you use higher level HTTP libraries but not if you just use the lower level TLS bindings.

For more information see also SSLLabs: User Agent Capabilities.

* The behavior changed with openssl 1.1.0. From then on SNI is on by default but can be explicitly disabled with -noservername.

  • For Java over about the last year there was a bug where HttpsURLConnection failed to send SNI if you used a nondefault HostNameVerifier; there are about half a dozen Qs on SO about problems caused by this. (Now fixed.) Oct 16 '17 at 2:38
  • It's not enabled by default in openssl s_client. IT can be turned of with -noservername
    – RafalS
    Apr 15 '20 at 7:07
  • @RafalS: I think you mean that with current versions of openssl (starting around 1.1.0) it is now enabled by default and needs to be explicitly turned off if necessary with -noservername. Apr 15 '20 at 7:14

Yes, TLS clients send SNI and tools that don't send SNI are expected to not work (e.g. python older than 2.7.8), because many sites only work with SNI.

For example, any use of CDN requires SNI (unless you pay for a dedicated IPv4 address for your domain at the CDN provider, which is very expensive).

Many sites that actually do have dedicated IPv4 address(es) are configured to drop non-SNI connections or serve dummy certificates for non-SNI connections.

So you can just declare that your site requires SNI and it will be fine (unless you must maintain compatibility with clients so old they are almost definitely insecure and shouldn't be used).

One thing you should know is a quirk with HTTP/2 request multiplexing and TLS certificates that cover multiple domains. If a browser needs to perform a request to foo.com and opens a connection to your server and gets a certificate with both foo.com and bar.com in SAN, and soon after the same browser needs to perform a request to bar.com and DNS says it's the same IP address, since the certificate covers bar.com too, it will consider the already open connection to foo.com to be suitable and just multiplex the request for bar.com in that single HTTP/2 connection. If your backend "knows" that requests for bar.com cannot come to this server because connections with bar.com in SNI are handed to another server, you'll have a bug.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.