Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why do you recommend disable ssl_session_tickets in NGINX? #135

Closed
nodesocket opened this issue Apr 1, 2016 · 26 comments
Closed

Why do you recommend disable ssl_session_tickets in NGINX? #135

nodesocket opened this issue Apr 1, 2016 · 26 comments

Comments

@nodesocket
Copy link

Enabling should improve performance when used in conjunction with ssl_session_cache?

@tomato42
Copy link
Member

tomato42 commented Apr 1, 2016

Because proper rotation of session ticket encryption key is not implemented in nignx or Apache. Thus it is easier to recommend against its use that suggest use of 3rd party software to fix it.

@nodesocket
Copy link
Author

Very strange, I've never heard about session tickets not being secure. Also, Qualys SSLabs does not warn about using session tickets.

@tomato42
Copy link
Member

tomato42 commented Apr 3, 2016

The problem is not that they are insecure, or that they can't be made secure. The problem is that the way they are commonly implemented means that you don't provide forward secrecy if you use them - all encryption keys are ultimately encrypted with just one encryption key - the session ticket key.

see here for more in-depth explanation: https://www.imperialviolet.org/2013/06/27/botchingpfs.html

@rugk
Copy link

rugk commented Jul 20, 2016

Basically it would make Perfect Forward Secrecy useless.

What about closing this issue as the question has presumably been answered?

@gene1wood
Copy link
Collaborator

Ya, looks like this has been answered. Thanks for the question @nodesocket and thanks everyone for the details about why.

@szepeviktor
Copy link
Contributor

Apache docs is very clear about it:

Using them without restarting the web server with an appropriate frequency (e.g. daily) compromises perfect forward secrecy.

https://httpd.apache.org/docs/trunk/mod/mod_ssl.html

E.g. on Debian-based systems daily logrotate reloads Apache. I hope a reload is enough.

@tomato42
Copy link
Member

IIRC reload is not sufficient, but it was a long time ago I last looked into it.

@szepeviktor
Copy link
Contributor

IIRC reload is not sufficient, but it was a long time ago I last looked into it.

Thank you. Is there a programmatic way to clear the shared memory used by Apache for SSL?

@tomato42
Copy link
Member

whole shared memory? I don't know

the ticket keys? two or three years ago there wasn't

@szepeviktor
Copy link
Contributor

OK, so apache2ctl graceful

@april
Copy link
Contributor

april commented Mar 29, 2017

This is the same reason why we don't recommend using classic Diffie-Hellman key exchange. Sure, it can be done safely and correctly, but without web servers Doing The Right Thing (tm) automatically, it's prone to people screwing it up more often than not.

@szepeviktor
Copy link
Contributor

szepeviktor commented Mar 30, 2017

apache2ctl graceful does change the session ticket.

Command used: openssl s_client -purpose "sslserver" -verify_return_error -connect www.egeszseges-ivoviz.hu:443 -servername www.egeszseges-ivoviz.hu < /dev/null

Output: TLS session ticket: ...

@szepeviktor
Copy link
Contributor

Also 😄 service apache2 reload does change the session ticket.

@tomato42
Copy link
Member

Just because you cannot resume the session after a server reload does not mean that the ticket encryption key has changed - sessions being invalidated will have the same result

@szepeviktor
Copy link
Contributor

szepeviktor commented Apr 4, 2017

This is what I think.

This prints the TLS session ticket:

openssl s_client -purpose "sslserver" -verify_return_error \
 -connect www.egeszseges-ivoviz.hu:443 -servername www.egeszseges-ivoviz.hu \
< /dev/null 2> /dev/null | sed '/TLS session ticket:/,/^$/!d'

If I run it continuously the first 16 bytes don't change, only the rest.
When I reload apache apache2ctl graceful then the first 16 bytes also changes.
So I conclude that ticket encryption key is changed by the reload.

Am I right?

@tomato42
Copy link
Member

From what I can see in openssl sources, the first 16 bytes of the ticket is the "name" of the key (essentially random data), so it changing does suggest the encryption key is changing too, but without looking into apache sources I can't tell for sure.

maybe you could find the bug in issue tracker that references it, we would know in which version they fixed the reload behaviour

@jrchamp
Copy link
Contributor

jrchamp commented Apr 11, 2017

Is it bad that the first 16 bytes are the same for all tickets generated by that key? Seems like it allows an attacker to know how often the key is changing (or not changing).

@tomato42
Copy link
Member

correlating session resumption rates from clients will provide exact same information

sideshowbarker added a commit to whatwg/misc-server that referenced this issue Sep 5, 2017
See mozilla/server-side-tls#135

> proper rotation of session ticket encryption key is not
> implemented in nignx or Apache. Thus it is easier to recommend against
> its use that suggest use of 3rd party software to fix it.
> The problem is not that they are insecure, or that they can't be made
> secure. The problem is that the way they are commonly implemented means
> that you don't provide forward secrecy if you use them - all encryption
> keys are ultimately encrypted with just one encryption key - the session
> ticket key.
>
> see here for more in-depth explanation:
> https://www.imperialviolet.org/2013/06/27/botchingpfs.ht
andersk added a commit to andersk/zulip that referenced this issue Mar 9, 2019
Lengthen the session timeout and enlarge the session cache.  Disable
session tickets (see
mozilla/server-side-tls#135).  Upgrade
Diffie-Hellman parameters from fixed 1024-bit to custom 2048-bit.
Enable server-preferred cipher ordering, and OCSP stapling.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
andersk added a commit to andersk/zulip that referenced this issue Mar 9, 2019
Lengthen the session timeout and enlarge the session cache.  Disable
session tickets (see
mozilla/server-side-tls#135).  Upgrade
Diffie-Hellman parameters from fixed 1024-bit to custom 2048-bit.
Enable server-preferred cipher ordering, and OCSP stapling.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
andersk added a commit to andersk/zulip that referenced this issue Mar 9, 2019
Lengthen the session timeout and enlarge the session cache.  Disable
session tickets (see
mozilla/server-side-tls#135).  Upgrade
Diffie-Hellman parameters from fixed 1024-bit to custom 2048-bit.
Enable server-preferred cipher ordering, and OCSP stapling.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
andersk added a commit to andersk/zulip that referenced this issue Mar 11, 2019
Lengthen the session timeout and enlarge the session cache.  Disable
session tickets (see
mozilla/server-side-tls#135).  Upgrade
Diffie-Hellman parameters from fixed 1024-bit to custom 2048-bit.
Enable OCSP stapling.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
@thestinger
Copy link

nginx guarantees that it switches the built-in key on reload but that's not really what you want. You want to rotate them rather than suddenly invalidating all of the previous ones.

To do the right thing, you have to script it externally and reference the keys with ssl_session_ticket_key:

http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_ticket_key

You need that if you want to sync them across servers, but you shouldn't need this for the simple case.

It's a similar situation as OCSP stapling where you can use an approach like https://github.com/tomwassenberg/certbot-ocsp-fetcher to persistently cache a valid response externally and reference it from the server, but they don't give you an easy way to do the right thing internally, which is strange.

Neither of these things would be particularly hard for them to implement properly internally. It would be simpler than what you need to do with scripts...

@Seirdy
Copy link

Seirdy commented Nov 3, 2021

It's a similar situation as OCSP stapling where you can use an approach like https://github.com/tomwassenberg/certbot-ocsp-fetcher to persistently cache a valid response externally and reference it from the server, but they don't give you an easy way to do the right thing internally, which is strange.

Neither of these things would be particularly hard for them to implement properly internally. It would be simpler than what you need to do with scripts...

The GrapheneOS project already has this in place; see https://github.com/GrapheneOS/nginx-rotate-session-ticket-keys and the relevant nginx configs.

Incidentally, using certbot-ocsp-fetcher and the GrapheneOS scripts allows you to get 0-RTT working with the OCSP must-staple patch for BoringSSL-based Nginx servers.

@solracsf
Copy link

Does nginx 1.23.2 changes this?
https://nginx.org/en/CHANGES

TLS session tickets encryption keys are now automatically rotated when using shared memory in the "ssl_session_cache" directive.

@rugk
Copy link

rugk commented Oct 28, 2022

Wow finally, yeah! 🎉

@thestinger
Copy link

Before 1.23.2, it didn't explicitly purge state-based sessions from the cache either. Neither the stateless (session tickets) or stateful approaches provided proper forward secrecy. The only proper approach before 1.23.2 was configuring session ticket keys via external files in ramfs managed by a script reloading the nginx configuration after rotating them. Both approaches can now work without it. It's not explicitly mentioned in the release notes, but it changed too.

commit 3057e6e9ad3ccb0be5cd1546697871cfec4d1fa3
Author: Maxim Dounin <mdounin@mdounin.ru>
Date:   Wed Oct 12 20:14:43 2022 +0300

    SSL: explicit clearing of expired sessions.

    This reduces lifetime of session keying material in server's memory, and
    therefore can be beneficial from forward secrecy point of view.

jspricke pushed a commit to jspricke/apache2.debian that referenced this issue Jan 4, 2024
fixes #972695

Based on
mozilla/server-side-tls#135 and
https://www.imperialviolet.org/2013/06/27/botchingpfs.html
session tickets are a complicated mechanism that’s easy to get wrong.
Proper use also requires daily reloading of the server.
They are only relevant for TLS1.2.
If anyone needs the performance boost, they can enable it again.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests