X

Best Practices from Oracle Development's A‑Team

Load Balancing SSL Traffic in OCI

OCI provides a load balancing service which can be leveraged to distribute incoming traffic from clients amongst a set of servers. A simple example can illustrate this feature. 

I have two compute instances in OCI running Apache HTTP Server. The Apaches are listening on port 80 for incoming requests. I have defined a Load Balancer in OCI which routes traffic to these two Backend servers. The Load Balancer accepts http requests over port 80 as shown in the figure above. From the browser, the first time I send a http request I get the following response:

 

Notice “… Apache httpd 1 …”  in the body of the message returned by the server. The response is from Apache httpd 1. Now, when I reload the page, I get the following response:

 

This time the response is from the second server Apache httpd2. If I reload the page again, the first server would respond and so on and so forth. In other words, the servers are alternately serving the incoming requests, i.e. in round robin. This distribution of traffic is managed by the load balancer.

The distribution of traffic by OCI need not be just round robin. Load balancing policies can be used to define the criteria to distribute incoming requests amongst the Backend Set.

An interesting aspect of load balancing is that although the Backend servers serve the requests, they are themselves hidden from the clients. From the clients’ perspective, it is just the load balancer which is serving the requests. The clients initiate connection with the Load Balancer: the IP address in the browser is that of the Load Balancer.

 

SSL Traffic

Although the above example is useful in explaining the load balancing concepts, it has practical limitation since the traffic is insecure. OCI supports SSL (TLS v1.2) for secure transport between clients and backend servers. There are 3 uses cases which need to be considered –

  • SSL Termination: in this scenario, an organization has deemed that the Backend servers serve just HTTP or TCP based requests, i.e. no HTTPS or SSL requests. However, the client requests (say from browser) still need to be secured. Both these requirements are satisfied by having the Load Balancer play the role of an intermediary where the SSL connection terminates at the Load Balancer and the connections between the Load Balancer and the Backend servers are unsecured.
  • SSL Tunneling: In this scenario, it is required that the entire transport channel between the client and the Backend server is secured. In other words, no intermediate entity including the Load Balancer should be able to see any of the contents of either the request or the response.
  • End To End SSL: in this scenario, the SSL connection from the client terminates at the Load Balancer and then a new SSL connection is initiated from the Load Balancer to the Backend server. This configuration is useful if the Load Balancer needs to filter HTTP headers in requests and responses.

OCI supports all of the above 3 use cases. Let us look into these use cases in more detail.

 

SSL Termination

In the above figure, SSL is getting terminated at the Load Balancer which in turn establishes new unsecured TCP connections to the two Backend servers. To illustrate this scenario, I will use a Backend Set comprising of two Oracle Linux compute instances: lb-nossl-backend-1 and lb-nossl-backend-2. I have installed Apache HTTP Server on both the instances. On each compute instance, I have opened just the http service using the firewall-cmd, resulting in the Apache servers accepting only HTTP connections over port 80. I have added the statement – “This is Apache httpd #n nossl running on OCI” – to each Apache’s /var/www/html/index.html file where #n is 1 or 2 for the two Backends.

After configuring the two Backends, I define a Backend Set “Backend-NoSSL” and add the two Backends to this set as follows:

where 10.0.1.4 and 10.0.0.8 are the private addresses of the above two Backends. Note that the Load Balancer uses port 80 to communicate with both the Apache servers.

Since the SSL is getting terminated at the Load Balancer, the Load Balancer should have its own pair of <private key, public certificate>. This will ensure that client communication with the Load Balancer is secured. For this illustration, I have used openssl to generate <key, cert> pair. The certificate is a self-signed certificate in the pem format with the Common Name as “LB-SSL”. The pair <key.pem, cert.pem> > is uploaded onto the OCI and associated with the Load Balancer. The entry is named LB-Cert-1 as shown in the figure below.

After the certificate pair is uploaded it gets listed under the Certificate section of the Load Balancer as shown below:

 

Next, I will define a Listener as in the following figure:

Note the following in the above configuration:

  1. The Listener listens on port 443.
  2. The “Use SSL” check box is selected
  3. The certificate bundle LB-Cert-1 is chosen.
  4. The Backend Set “Backend-NoSSL” created in the previous steps is selected to complete the configuration of the Listener.
  5. “Verify Peer Certificate” in the above figure is used for client authentication.

Now we are ready to do some testing. To start with, I issue the following request to the Load Balancer:

Reloading the page gives us the following:

There are few takeaways from the above run –

  1. The server certificate is LB-SSL in both the cases. This shows that the client has established SSL connection with the Load Balancer; LB-SSL was the certificate associated with the <key, cert> pair LB-Cert-1 which is configured with the Listener.
  2. The responses are from the Apache HTTP Servers which accept only HTTP requests on port 80. This implies SSL Termination is working.
  3. Lastly, the two Backends alternate in serving requests in accordance with the load balancing policy which is round robin.

 

SSL Tunneling

In the above figure, the TCP connection is tunneled through the Load Balancer all the way to a Backend.  Thus the SSL connections get terminated at the Backend servers. To illustrate this scenario, I will use a Backend Set comprising of two new Oracle Linux compute instances - lb-ssl-backend-1, lb-ssl-backend-2. Unlike the SSL Termination scenario where the two servers had just Apache HTTP Server installed,  here I have installed Apache with mod_ssl package on both the instances. The installation generates a self-signed certificate with the hostname as the Common Name of the certificate. On each compute instance, I have opened just the https service using the firewall-cmd, resulting in the Apache servers accepting only SSL connections over port 443. I have added the statement – “This is Apache httpd #n SSL running on OCI” – to each Apache’s /var/www/html/index.html file where #n is 1 or 2 for lb-ssl-backend-1 and lb-ssl-backend-2 respectively.

After configuring the two Backends, I define a Backend Set and add them to this set.

10.0.0.7 and 10.0.1.3 are the private IP addresses of lb-ssl-backend-1 and lb-ssl-backend-2 respectively. Note that the Load Balancer uses port 443 to communicate with both the Apache servers.

I have used a system generated name for my Backend Set. The following figure shows the set after the two Backends are added.

 

Notice that the health of the overall set as well as both the Backends are displayed as "OK".  This is driven by the health check policy which in this case (SSL Tunneling) configures the Load Balancer to use TCP over port 443 to check the health of the Backends.

 

Next, I define a Listener as follows:

Note the following in the above configuration:

  1. For SSL Tunneling, the “Protocol” field should be “TCP”. This has some ramifications and we will discuss them shortly.
  2. Also, the “Use SSL” check box should remain unselected (default) as shown in the figure below.
  3. The Backend Set selected is the one which we defined in the previous step.

In SSL Tunneling mode, the Load Balancer works at the TCP protocol level. Since the TCP payload is SSL records, hence encrypted, the Load Balancer does not have any insight into the data being transported.  OCI Load Balancer supports many advanced features such as session persistence which rely on HTTP artifacts.  Since such information is unavailable to the Load Balancer in SSL Tunneling mode, these features cannot be used in this mode.

Now we are ready to do some testing. To start with, I issue the following request to the Load Balancer:

Note that the response is returned by the Backend lb-ssl-backend-1. Also, the certificate is that of the Backend itself. Reloading the page gives us the following:

This time the response is from the other Backend lb-ssl-backend-2.  Also the certificate is that of lb-ssl-backend-2.

The takeaways from the above run are as follows –

  1. The two Backends alternate in serving requests.
  2. The server certificate is that of the Backend which responds. This shows that the client establishes SSL connection with the Backend servers.
  3. The responses are from the Apache HTTP Servers which accept only HTTPs requests on port 443. This implies SSL Tunneling is working – the Load Balancer merely routes the SSL payload to the Backends.

 

End To End SSL

In the above figure, the SSL connection from the user is getting terminated at the Load Balancer which then initiates new SSL connections to the Backend servers. To illustrate this use case, I will reuse the Backend Set of the SSL Tunneling where both the Backends - lb-ssl-backend-1 and lb-ssl-backend-2 - accept just HTTPS requests.  

The Backend Set configuration is as follows:

The configuration will include the following:

  1. “Use SSL” flag is checked 
  2. LB-Cert-1 certificate bundle is chosen.

The above configuration ensures that the Load Balancer will initiate SSL connections with the Backends.

With the Backend Set ready, let’s define the Listener. The Listener is very similar to SSL Termination use case with the exception of the Backend Set. This time the Load Balancer initiates SSL connections with the two Backends lb-ssl-backend-1 and lb-ssl-backend-2.

Now let us run few requests. The first request is as follows:

The Backend lb-ssl-backend-1 responds. Note the server certificate. Reloading the page results in lb-ssl-backend-2 responding.

 

The takeaways from the above run are as follows –

  1. The server certificate is LB-SSL. This shows that the client has established SSL connection with the Load Balancer; LB-SSL was the certificate associated with the <key, cert> pair LB-Cert-1 which is configured with the Listener.
  2. The responses are from the Apache HTTP Servers which accept only HTTPS requests on port 443. This implies End To End SSL is working – the SSL connection from the client terminates at the Load Balancer, while the Load Balancer creates a fresh SSL connection to the Backend.
  3. Lastly, the two Backends alternate in serving requests.

Summary

OCI provides a comprehensive load balancing functionality including handling of SSL secured transport. To recap, there are three primary use cases –

  • SSL Termination:  the SSL connection originating from the client gets terminated at the Load Balancer and the Load Balancer forwards the contents to the Backend servers as unsecured data.
  • SSL Tunneling:  the SSL connection gets terminated at the Backend. The Load Balancer merely routes the SSL traffic to the Backends.
  • End To End SSL:  the SSL connection gets terminated at the Load Balancer, but it then initiates a new SSL connection to the Backends.

OCI supports all three use cases.

 

 

 

 

 

 

 

 

 

 

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha