multi-backend SSL Passthrough Loadbalancing with VMware NSX

Currently i'm working on a NSX project that involves automation of NSX loadbalancers to provide loadbalancing as a catalog item. Now, while i would normally prefer deploying dedicated loadbalancers on-demand, a big constraint in this environment is the fact that the ISP takes a significant time to configure the GSLB for new services, so on-demand loadbalancers go straight out of the window. The second issue is that all SSL connections must be terminated on the backend, so we can't do SSL offloading or reencryption.

So what we're looking at now is loadbalancing traffic to multiple backends, based on the hostname of the request. The GSLB has been configured to forward any traffic intended for *.cloudapp.glsb.domain.tld towards a pool of NSX loadbalancers intended for all applications running on the cloud management platform.

As you may know, SSL passthrough doesn't allow the inspection of the actual traffic. Fortunately, when using a "relatively" new browser or operating system (SNI was introduced in 2003), we now have support for SNI (Server Name Indication), which allows for multiple certificates on a shared IP. Before SNI was commonplace, SSL was the bane of shared hosting platforms as each HTTPS server required its own dedicated IP address. Nowadays, SNI is mostly used in the hosting world to run multiple ssl-backed applications on the same IP address. And as it turns out, HAProxy (which is used by the NSX loadbalancer) supports SNI inspection out of the box.

So as it turns out, loadbalancing SSL passthrough requests to different backends based on the SNI request is extremely easy:

First off, we start with the regular configuration of the NSX loadbalancer. We'll create a profile, set it to HTTPS, and ensure "Enable SSL Passthrough" is checked.

Next, configure your Pools and virtual servers as you'd do normally, and finally create an application rule with the following content (replacing your backend pools and hostnames as applicable):

tcp-request inspect-delay 5s tcp-request content accept if { req_ssl_hello_type 1 }
tcp-request content reject
use_backend HTTPS_pt_app1 if { req_ssl_sni -i }
use_backend HTTPS_pt_app2 if { req_ssl_sni -i }

Assign the application rule to your virtual server, and that's all there is to it. Your loadbalancer should now correctly select the backend pool based on the hostname in the HTTPS handshake, allowing you to use multiple backends even with SSL passthrough.

Obviously, the tcp-request could be tuned for your own purposes (inspection delays can be significantly lower on LAN than on WAN, for example), and you could even do fancy things with wildcard or regex matching on the req_ssl_sni statement, but for the purpose of this blog we've shown that SSL passthrough does not need to limit your ability to perform dynamic backend selection in NSX.