NGINX TLS/SSL Hardening Prompt
Harden your NGINX TLS config to a modern, A-grade baseline — protocols, cipher suites, HSTS, OCSP stapling, session settings — without breaking older clients you actually need to support.
- Target user
- Engineers tightening NGINX TLS for compliance or an SSL Labs score
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT, Cursor
The prompt
You are a senior security engineer who hardens NGINX TLS for production. You balance a strong cipher policy against real client compatibility, and you never enable HSTS preload without warning about its irreversibility.
I will provide:
- My current TLS-related directives (`ssl_protocols`, `ssl_ciphers`, certs, etc.): [PASTE TLS CONFIG]
- The oldest clients I must support (browsers, mobile, API clients, legacy integrations): [DESCRIBE CLIENTS]
- My OpenSSL/NGINX version: [PASTE nginx -V OUTPUT OR VERSION]
- Whether I want HSTS, and whether preload is acceptable: [DESCRIBE]
Harden it:
1. **Protocols** — set `ssl_protocols` to TLSv1.2 + TLSv1.3 (drop 1.0/1.1) unless a stated legacy client forbids it; if so, call out the exact risk.
2. **Ciphers** — give a modern `ssl_ciphers` list with `ssl_prefer_server_ciphers`, prioritizing AEAD/forward-secrecy suites; for TLS 1.3 note that ciphers are negotiated separately. Explain any suite you keep for compatibility.
3. **HSTS** — `add_header Strict-Transport-Security` with `max-age`, `includeSubDomains`, and `preload` ONLY if I confirmed it, with an explicit warning that preload is hard to undo.
4. **OCSP stapling** — `ssl_stapling on`, `ssl_stapling_verify on`, `ssl_trusted_certificate`, and a `resolver` with a timeout; explain what stapling does and how to verify it.
5. **Session + DH** — `ssl_session_cache`, `ssl_session_timeout`, disabling session tickets if forward secrecy matters, and `ssl_dhparam` guidance for non-ECDHE.
6. **Redirect + headers** — a clean HTTP→HTTPS redirect and a note on where security headers belong.
Output: (a) the hardened `server {}` TLS block, fully commented, (b) a compatibility note listing which clients you may drop, (c) verification commands: `nginx -t`, `openssl s_client -connect host:443 -status`, and what to look for. Apply only after `nginx -t` passes and reload; never hot-edit the live TLS config.
Why this prompt works
TLS hardening is a tradeoff, not a checklist — the strongest cipher policy is useless if it locks out a payment partner stuck on an old library. The prompt makes you state the oldest clients you must support up front, so the model tightens protocols and ciphers against real constraints and explicitly flags what it would drop.
HSTS preload and OCSP stapling are the two settings teams most often get wrong: preload is effectively irreversible, and stapling fails silently without a resolver. Forcing the model to warn on preload and include the ssl_stapling_verify + resolver lines prevents the two classic footguns.
The openssl s_client -status verification step turns an opaque config change into something you can prove. You see the negotiated protocol and the stapled OCSP response with your own eyes, behind an nginx -t gate, instead of trusting that a reload did what you hoped.