2

Consider the following network topology:

Load balancer topology

  1. There are exactly two HTTPS servers, S1 and S2.
  2. 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.)
  3. 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.
  4. The clients request something like https://example.com. The DNS resolves example.com to the IP address of LB, which in turn forwards the packet to either S1 or S2.
  5. 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.
  6. 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:

  1. 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.
  2. 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.
  3. 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.

3

That's exactly what session tickets are for. While session ids are only some kind of reference which "point" to the session information stored on the server, session tickets contain all what is needed inside the session ticket, including the key material. Nothing is stored on the server side for the session.

Of course it would be a bad idea to have these information in plain text because than an attacker could just take the session ticket to extract the keys and decrypt the traffic. Therefore the session tickets are somehow protected - the details depend on the actual implementation. Usually this means they are encrypted with some server side secret and protected against manipulation with some MAC or HMAC. And as long as all servers share the same implementation and encryption key they can deal with the tickets issued by another server.

Given that session tickets include all key material it is essential that they are properly protected. If the servers are using the same encryption key for the tickets all the time it is sufficient for an attacker to attack one of these servers, get the encryption key and then use this to decrypt all previously sniffed session tickets and thus all previously sniffed traffic. The best way is therefore to regularly rotate the secrets in order to limit exposure of such critical information.

Given that a session ticket can store arbitrary information it can also store an ID for the encryption secret which makes it possible to use a new encryption key but being able to handle tickets protected by the old key for a while. Whenever such an old ticket gets received it can be decrypted if the old key is still known and then a new ticket protected by the new key can be issued.

Note that this mainly describes session tickets up to and including TLS 1.2. With TLS 1.3 the session handling mechanism was reworked. For more information see Botching Forward Secrecy - The sad state of server-side TLS Session Resumption implementations and The Future of Session Resumption - Forward secure PSK key agreement in TLS 1.3.

  • Thanks a lot - very informative links. Especially, the first link has a section session resumption with multiple servers, which explains exactly what I was looking for. – M.S. Dousti Jul 8 at 23:33

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.