Session Ticket Rotation

Hello!
On Mon, Sep 22, 2014 at 01:39:43PM +0200, Richard Fussenegger, BSc wrote:
> I'd like to implement built-in session ticket rotation. I know that it this
> was discussed before but it was never implemented. Right now a custom
> external ticket key system is supported. Admins with single installations
> and not enough knowledge about the topic are left with keys that are valid
> for the complete lifetime nginx is running.
That's not really true: ticket keys are regenerated on each
configuration reload.
> I thought about a rotation scheme that introduces a single new configuration
> variable (e.g. ssl_session_ticket_key_rotation or
> ssl_session_ticket_key_interval) that defines the interval in which the
> ticket key should be rotated. I think a default setting of 24 hours would be
> enough for most installations. One key is always used for decryption and
> encryption and the most recently expired key is only used for decryption.
> This means that we have a de- and encrypt key for 24 hours and a decrypt key
> for 48 hours with the default setting. The best place for this would be in
> ngx_event_openssl.c#2640 after the if (paths == NULL) by checking if the
> aforementioned variable is set (default) and if the currently used key has
> expired. If it hasn't return NGX_OK (as it is now) otherwise copy current
> key to old key and generate new key.
Checking expiration in the ngx_ssl_session_ticket_keys() function
doesn't make sense: creating new SSL context means new random
keys. So if the ngx_ssl_session_ticket_keys() is called, which
only happens while reading a configuration, we currently have
a new key anyway.
> Unsolved questions:
>> Implementation: Currently OpenSSL is generating and keeping track of the key
> (this would still be the case if the newly introduced setting is set to
> "0"). We'd have to introduce two variables - one for the current and one for
> the old key plus timestamps - and let OpenSSL know about the key before
> attempting to decrypt sent session data.
The main problem here is how to share keys between worker
processes, to ensure different workers will be able to decrypt
tickets. So automatic rotation of ticket keys will likely require
shared SSL session cache to be configured as well, and using a SSL
session cache to store ticket keys.
> Per server keys: CVE-2014-3616 from Antoine Delignat-Lavaud was dealing with
> this. I have to review his patches but I guess that the variables have to be
> arrays and we'd have to keep different current and old keys per server. But
> what if one wants to share the sessions among servers? I guess this has to
> depend on the location the configuration was set. As I said, I have to
> review his patches to gather more knowledge for this problem.
As of now, session tickets can't be decrypted in other server{}
blocks (unless ssl_session_ticket_key is explicitly used to set
keys). I don't see any reasons to change this behaviour.
> Restarts: Apache is storing the key to file, that would allow the process to
> read the last used keys. But of course this isn't very secure and we may
> need an additional setting to define the path where these intermediate keys
> should be stored. Of course we could also simply ignore restarts, as it is
> now. But we'd loose the ability to decrypt old sessions tickets.
Current behaviour is believed to be good enough.
--
Maxim Dounin
http://nginx.org/