Consider the following network topology:
- There are exactly two HTTPS servers, S1 and S2.
- There are exactly two HTTPS clients, C1 and C2. Notice this, as there are often many more clients for two servers. But in this case, there are only two clients. (You may ask why? Because C1 and C2 are also servers, serving many clients while being served by S1 and S2 as well.)
- There is a load balancer between the clients and server, LB. Here, LB performs load balancing in a round-robin fashion at transport layer (TCP). Therefore, LB does not perform SSL-offloading or anything related to application layer.
- The clients request something like
https://example.com
. The DNS resolvesexample.com
to the IP address of LB, which in turn forwards the packet to either S1 or S2. - LB is configured to route packets in one TCP session (same src port, src address, dest port, dest address) to either S1 or S2, not both. Therefore, S1 and S2 need not be aware of the session information on the other server.
- For performance reasons, S1 and S2 can be configured to use TLS session resumption based on either session IDs or session tickets.
The following scenario shows the problem:
- C1 connects to
https://example.com
, and LB sends its traffic to S1. A TLS session is established (full handshake), with sessionID = 123456. After a while, C1 closes the connection. - Some time passes, and C1 connects to
https://example.com
again. This time, LB sends its traffic to S2. C1 offers to use sessionID = 123456, but S2 does not know this sessionID. So, S2 asks to set sessionID to something different, say sessionID = 789abc (full handshake). After a while, C1 closes the connection. - Some time passes, and C1 connects to
https://example.com
yet another time. This time, LB sends its traffic to S1, which does not know sessionID = 789abc. You get the idea: another full handshake occurs.
So, as a client goes back-and-forth between the servers, a full handshake occurs every time, and the performance is impacted.
What is the correct way to handle this scenario, so that the clients do not perform a full handshake in every new connection?
PS: If I had many clients, I'd configure LB to stick one client to one server for some amount of time. However, since there are only two clients, that would impact performance as well.
Edit: The link I cited above explains this, which I don't fully understand:
In practice, deploying session tickets across a set of load-balanced servers also requires some careful thinking and systems architecture: all servers must be initialized with the same session key, and an additional mechanism is required to periodically and securely rotate the shared key across all servers.