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 nginxWhy 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.