maxuru ~ % cat nginx/tls-protocols-and-ciphers
Configure nginx TLS protocols and ciphers
/etc/nginx/nginx.confssl_protocols TLSv1.2 TLSv1.3;ssl_prefer_server_ciphers off;ssl_session_cache shared:SSL:10m;ssl_session_timeout 1d;ssl_session_tickets off;sudo nginx -t && sudo systemctl reload nginxCheck your version first — that first line may already be the default
Section titled “Check your version first — that first line may already be the default”ssl_protocols TLSv1.2 TLSv1.3; is now nginx’s own default, so on a current
build the first line of the block above changes nothing. It is worth writing
anyway — an explicit protocol line survives a distro that patches defaults, and
it documents intent — but you should know which of these you are doing.
nginx moved to that default in two steps, and its own changelog dates both:
| Release | Change |
|---|---|
| 1.23.4 (28 Mar 2023) | TLSv1.3 enabled by default |
| 1.27.3 (26 Nov 2024) | TLSv1 and TLSv1.1 disabled by default |
So:
- nginx 1.27.3 or newer — the default is already
TLSv1.2 TLSv1.3. Setting it is a verify, not a fix. - anything older — TLS 1.0 and 1.1 are still enabled by default and the line is a real change.
That second case is not hypothetical. nginx’s legacy branches are 1.28.x and 1.26.x, and distribution packages sit further back still, so a long-term server is exactly where the line does work. Check before assuming:
nginx -vThe rest of the block is not a no-op on any version. ssl_session_tickets off;
differs from the default, and the two ssl_ciphers facts below — that it does
not control TLS 1.3, and that a hand-written list ages badly — are the parts of
this page that actually change outcomes.
Why it matters
Section titled “Why it matters”TLS 1.0 and 1.1 are obsolete, deprecated by the IETF, and rejected by current browsers. Leaving them enabled doesn’t help anyone reach your site — the clients that would need them can’t complete a modern handshake anyway — but it does keep you failing compliance scans and offering downgrade surface.
ssl_protocols TLSv1.2 TLSv1.3 is the whole control. The rest of this page is
about not making things worse.
Don’t hand-write ssl_ciphers
Section titled “Don’t hand-write ssl_ciphers”The same argument as SSH ciphers applies, for the same reason: cipher lists age badly, and a list pasted from a 2016 blog post encodes 2016’s opinions forever.
Use the Mozilla SSL Configuration Generator. It produces a current list for
your nginx and OpenSSL versions, and it is maintained by people who track this
full time. Pick the intermediate profile unless you have a specific reason —
modern drops TLS 1.2 entirely, which is more compatibility loss than most sites
can absorb.
If you inherit a config with a long ssl_ciphers line, the question isn’t
whether the ciphers are bad — they’re probably fine. It’s whether anyone will
revisit them when the next weakness lands. A generated config that you regenerate
is more durable than a curated one that you won’t.
ssl_ciphers does not control TLS 1.3
Section titled “ssl_ciphers does not control TLS 1.3”This surprises people who carefully craft a cipher list and then wonder why their scan still shows suites they didn’t list.
ssl_ciphers configures TLS 1.2 and below only. TLS 1.3 has its own separate
cipher suite set, and nginx offers no directive for it — OpenSSL’s defaults apply
and they are deliberately short and all strong. There is nothing to tune, and
nothing you can break.
So a hand-written ssl_ciphers line governs a shrinking share of your traffic,
which is another reason not to spend effort on it.
ssl_prefer_server_ciphers off is deliberate
Section titled “ssl_prefer_server_ciphers off is deliberate”The old advice was on — let the server dictate the order. Current Mozilla
guidance for the intermediate profile is off, because modern clients pick
better than a fixed server-side ordering can. A phone with hardware AES and a
laptop without it want different suites, and only the client knows which it is.
ssl_session_tickets off is the other non-obvious one: tickets can undermine
forward secrecy unless the ticket key is rotated, and nginx has no built-in
rotation.
Related
Section titled “Related”- Enable HSTS — TLS is only useful if the browser insists on it.
- OCSP stapling — mostly moot now; read before enabling.