Introduction
TLS session tickets allow clients to resume TLS sessions without a full handshake, improving performance. The session ticket is encrypted with a server-held key. When this key is rotated (for security compliance), clients with tickets encrypted under the old key cannot resume their sessions, causing connection failures. In load-balanced environments, if session ticket keys are not synchronized across all backend servers, clients routed to different servers cannot resume sessions.
Symptoms
- Intermittent TLS handshake failures after key rotation
- Clients experience
SSL routines:tls_process_ticket:ticket decryption failure - Session resumption rate drops to zero after key change
- Load-balanced services show inconsistent TLS behavior depending on which backend is hit
- Mobile apps with persistent connections suddenly disconnect
Common Causes
- Session ticket key rotated on one server but not others in a load-balanced pool
- Client holds a ticket encrypted with an expired key
- Automated key rotation script does not distribute keys to all nodes
- Load balancer and backend servers using different session ticket keys
- Key rotation interval too short for client session lifetime
Step-by-Step Fix
- 1.Check session ticket configuration:
- 2.```bash
- 3.# Nginx
- 4.grep -r "ssl_session_ticket" /etc/nginx/
- 5.# Apache
- 6.grep -r "SSLSessionTickets" /etc/apache2/
- 7.
` - 8.Generate a new session ticket key:
- 9.```bash
- 10.openssl rand 48 > /etc/nginx/ssl/session_ticket.key
- 11.chmod 600 /etc/nginx/ssl/session_ticket.key
- 12.
` - 13.Distribute the key to all load balancer nodes:
- 14.```bash
- 15.# Copy to all nodes (example using scp)
- 16.for node in lb1 lb2 lb3; do
- 17.scp /etc/nginx/ssl/session_ticket.key $node:/etc/nginx/ssl/
- 18.ssh $node "chmod 600 /etc/nginx/ssl/session_ticket.key && systemctl reload nginx"
- 19.done
- 20.
` - 21.Configure Nginx to use the shared session ticket key:
- 22.```nginx
- 23.ssl_session_tickets on;
- 24.ssl_session_ticket_key /etc/nginx/ssl/session_ticket.key;
- 25.# Can specify multiple keys for rotation:
- 26.ssl_session_ticket_key /etc/nginx/ssl/session_ticket_key_1.key;
- 27.ssl_session_ticket_key /etc/nginx/ssl/session_ticket_key_2.key;
- 28.
` - 29.Implement safe key rotation with overlap:
- 30.```bash
- 31.# Generate new key
- 32.openssl rand 48 > /etc/nginx/ssl/session_ticket_new.key
# Deploy new key as secondary on all nodes first for node in lb1 lb2 lb3; do scp session_ticket_new.key $node:/etc/nginx/ssl/session_ticket_key_2.key done
# Reload all nodes (both keys active) for node in lb1 lb2 lb3; do ssh $node "systemctl reload nginx" done
# After clients have refreshed, make the new key primary # and remove the old key from configuration ```
- 1.Verify session resumption is working:
- 2.```bash
- 3.# First connection (full handshake)
- 4.openssl s_client -connect server:443 -sess_out session.pem </dev/null
- 5.# Second connection (should resume)
- 6.openssl s_client -connect server:443 -sess_in session.pem </dev/null 2>&1 | \
- 7.grep "Reused, TLS"
- 8.# Should show: "Reused, TLSv1.3"
- 9.
`
Prevention
- Synchronize session ticket keys across all load balancer nodes using configuration management
- Use at least two session ticket keys during rotation for seamless transition
- Monitor session resumption rates and alert on sudden drops
- Set session ticket key rotation interval to at least 24 hours (not minutes)
- Document the session ticket key rotation procedure as part of security compliance runbooks