TCP Load Balancer In Front of TLS/SSL Endpoints - ssl

Last week I was playing with a load balancer for my TLS-enabled endpoints (share the same certificate) and was surprised it is possible to have TPC load balancer in place in front of SSL endpoint. Having that configured it was possible to communicate with TCP load balancer as like it configured to support TLS/SSL. So, I would like to ensure such a network configuration is fully working solution:
TLS/SSL session and handshake workflow are stateless, meaning it is possible to start handshake with a primary server and end it with a mirror. Is it true?
Are there any hidden dangers I must be aware of?
If previous statements are true, what the reason to to do all TLS/SSL work on a load balancer itself?
P.s. the reason I do not do TLS/SSL work on a load balancer is that I need to balance multiple proprietary endpoint only supports SSL/TLS.

TLS/SSL session and handshake workflow are stateless, meaning it is possible to start handshake with a primary server and end it with a mirror. Is it true?
No. I suspect your load balancer is using TCP keep-alive so that the handshake is completing on the same server every time.
Are there any hidden dangers I must be aware of?
You may be incurring a significant performance penalty. HTTPS has "session keys" that are, probably by default, unique to the server. If you aren't able to do something like sticky sessions with the load balancer, then you will do a full handshake every time a client moves from one server to the other.
You also will have session tickets that won't work between servers, so session resumption will probably not work either, and fall back to a full handshake. Some servers support configuring a common session ticket key, like nginx.
If previous statements are true, what the reason to to do all TLS/SSL work on a load balancer itself?
Well, they aren't entirely true. There are other benefits though. The main one being that the load balancer can be more intelligent since it can see the plaintext of the session. An example might be examining the request's cookies to determine which server to send the request to. This is a common need for blue/green deployments.

Related

What is purpose of decryption of data at both the load balancer and then the web server?

I heard that to alleviate the web server of the burden of performing the SSL Termination, it is moved to load balancers and then HTTP connection is made from the LB to the web server. However, in order to ensure security, an accepted practice is to re encrypt the data on the LB and then transmit it to the web server. If we are eventually sending the encrypted data to the web servers, what is the purpose of having a LB terminate SSL in the first place ?
A load balancer will spread the load over multiple backend servers so that each backend server takes only a part of the load. This balancing of the load can be done in a variety of ways, also depending on the requirements of the web application:
If the application is fully stateless (like only serving static content) each TCP connection can be send to an arbitrary server. In this case no SSL inspection would be needed since the decision does not depend on the content of the traffic.
If the application is instead stateful the decision which backend to use might be done based on the session cookie, so that requests end up at the same server as the previous requests for the session. Since the session cookie is part of the encrypted content SSL inspection is needed. Note that in this case often a simpler approach can be used, like basing the decision on the clients source IP address and thus avoiding the costly SSL inspection.
Sometimes load balancers also do more than just balance the load. They might incorporate security features, like a Web Application Firewall, they might sanitize the traffic or similar. These features work on the content so SSL inspection is needed.

What is the difference between HTTPS Load-Balancer w/ non-TLS backend and HTTPS Load-Balancer w/ TLS backend

I'm trying to configure load balancer to serve in HTTPS with certificates provide by Lets Encrypt, even though I couldn't do it yet, reading this article gives steps how to configure
Self-signed certs
Network Load-Balancer w/ TLS backend
HTTPS Load-Balancer w/ non-TLS backend
HTTPS Load-Balancer w/ TLS backend
As I'm intersting only in HTTPS, I wonder what is the difference between this two:
HTTPS Load-Balancer w/ non-TLS backend
HTTPS Load-Balancer w/ TLS backend
But I meant not the obvious reason that is the first one is not encrypted from load balancer to backend, I mean in performance and HTTP2 conection, for example will I continue to get all the benefits from http2 like multiplexing and streaming? or is the first option
HTTPS Load-Balancer w/ non-TLS backend
only an illusion but I won't get http2?
To talk HTTP/2 all web browsers require the use of HTTPS. And even without HTTP/2 it's still good to have HTTPS for various reasons.
So the point your web browser needs to talk to (often called the edge server), needs to be HTTPS enabled. This is often a load balancer, but could also be a CDN, or just a single web server (e.g. Apache) in front of an application server (e.g. Tomcat).
So then the question is does the connection from that edge server to any downstream servers need to be HTTPS enabled? Well, ultimately the browser will not know, so not for it. Then you're down to two reasons to encrypt this connection:
Because the traffic is still travelling across an insecure channel (e.g. CDN to origin server, across the Internet).
Many feel it's disingenuous to make the user think they are on a secure (with a green padlock) then in fact they are not for the full end to end connection.
This to me is less of an issue if your load balancer is in a segregated network area (or perhaps even on the same machine!) as the server it is connecting to. For example if the load balancer and the 2 (or more) web servers is is connecting to are both in a separate area in a DMZ segregated network or their own VPC.
Ultimately the traffic will be decrypted at some point and the question for server owners is where/when in your networking stack that happens and how comfortable you are with it.
Because you want HTTPS for some other reason (e.g. HTTP/2 all the way through).
On this one I think there is less of a good case to be made. HTTP/2 primarily helps high latency, low bandwidth connections (i.e. browser to edge node) and is less important for low latency, high bandwidth connections (as load balancer to web servers often are). My answer to this question discusses this more.
In both the above scenarios, if you are using HTTPS on your downstream servers, you can use self-signed certificates, or long lived self-signed certificates. This means you are not bound by the 30 days LetsEncrypt limitations, nor does it require you to purchase longer certificates from another CA. As the browser never sees these certificates you only need your load balancer to trust them, which is in your control to do for self-signed certificates. This is also useful if the downstream web servers cannot talk to LetsEncrypt to be able to get certificates from there.
The third option, if it really is important to have HTTPS and/or HTTP/2 all the way through, is to use a TCP load balancer (which is option 2 in your question so apologies for confusing the numbering here!). This just forwards TCP packets to the downstream servers. The packets may still be HTTPS encrypted but the load balancer does not care - it's just forwarding them on and if they are HTTPS encrypted then the downstream server is tasked with decrypting them. So you still can have HTTPS and HTTP/2 in this scenario, you just have the end user certificates (i.e. the LetsEncrypt ones) on the downstream web servers. This can be difficult to manage (should the same certificates be used on both? Or should they have different ones? Do we need to have sticky sessions so HTTPS traffic always hits the sae downstream server). It also means the load balancer cannot see or understand any HTTP traffic - they are all just TCP packets as far as it is concerned. So no filtering on HTTP headers, or adding new HTTP headers (e.g. X-FORWARDED_FOR with the orignal IP address.)
To be honest it is absolutely fine, and even quite common, to have HTTPS on the load balancer and HTTP traffic on downstream servers - if in a secure network between the two. It is usually the easiest to set up (one place to manage HTTPS certificates and renewals) and the easiest supported (e.g. some downstream servers may not easily support HTTPS or HTTP/2). Using HTTPS on this connection either by use of self-signed certificates or CA issued certificates is equally fine, though requires a bit more effort, and the TCP load balancer option is probably the most effort.

ssl negotiation happens multiple times for same domain

I've done a speedtest with webpagetest. My website is SSL secured. For some reason the SSL Negotiation happens twice.
There is one SSL negotiation for the index html which seems to be correct. The second request is done by fetch. I assume that the second SSL negotiation is not neccessary.
fetch("/api/menu")
For the remaining requests to the same domain there are no more negotiations.
There is first a TCP connect for menu which is then followed by the SSL setup. This means that it is not using the previously established TCP connection for the new connection but creates a new one. And this new one of course needs SSL too.
It is quite normal that browsers have several connections open to the same site when HTTP/1.1 is in use since only a single request can be handled at a time within one connection (this is different with HTTP/2). Since in your case the first connection is still in use for other requests, creating a new connection might speed up the total delivery time.
It can also be seen that the second SSL setup takes less time than the first. This is probably because it is doing a session resume, i.e. using the same SSL session as established in the first connection which speeds up the TLS handshake.

SSL Handshakes on connection setup

When I test my website performance I noticed SSL handshakes are happening as part of connection setup. I understand the first request (of the page) needs the full SSL handshake.
But, if you notice from the pingdom test, only certain other resources are doing the SSL handshake. The remaining requests in the page do not.
Can someone please explain the logic behind this.
Resources that are loaded via HTTPS will have their own SSL handshake if new TCP connections are used to retrieve them. If HTTP keep-alives are used, resources on the same server may be retrieved using existing connections. Resources retrieved via HTTP instead of HTTPS, or reside on different servers/domains, will have to use separate connections.
Your test results are fairly useless for diagnosing this, without knowing which resources are being retrieved, where they are being retrieved from, and what protocol they are being retrieved with.

Is it standard to use HTTPS from client to Load Balancer, but not from LB to app server?

Just wondering if it is a standard practice to use AWS Load Balancer to handle the HTTPS and forward it to the application as HTTP so none of the app instances have to worry about ssl certificates.
Yes, that's a common practice. One of the most important optimizations you could do for a website is to perform the SSL offloading geographically as close as possible to the client.
The SSL handshake consists in a couple of exchanges between the client and the server in order to establish the SSL session. And by having the SSL offloading as close as possible to the user you are reducing the network latency. The load balancer could then dispatch the request to your webfarm which could be situated anywhere in the world.