The pentest praises the A+ grade on SSL Labs. Two weeks later, a banking-sector client cannot connect: TLS 1.2 was disabled, and their outbound proxy still negotiates a cipher suite your nginx rejects. The infra team pasted a config block from a forum in 2019. Nobody knows how to read it — let alone update it when Mozilla or Let's Encrypt publish new guidance.
Configuring TLS is not about optimizing a report. It is holding two promises at once: robust exchanges against attackers, and real compatibility with your audience's browsers, mobile apps and corporate proxies.
Intermediate vs Modern: the right profile, not the strictest
Mozilla maintains three configuration levels. Only two matter in production:
| Profile | When to use | Trade-off |
|---|---|---|
| Intermediate | Public sites, SaaS, e-commerce | TLS 1.2 + 1.3, modern suites, broad compatibility |
| Modern | Internal APIs, clients you control | TLS 1.3 focus, less legacy |
| Old / Obsolete | — | No longer use |
For a site hosted with a European provider and a varied audience, Intermediate is almost always the right starting point. Modern only makes sense if you know your client fleet — and nobody goes through an outdated corporate TLS proxy.
The Mozilla SSL Configuration Generator produces ready blocks for nginx, Apache or Caddy. Copy them, but document who validated them, when, and for which server version.
A TLS configuration only an external consultant understands will not be patched at the next OpenSSL incident.
TLS 1.2, TLS 1.3 and what to cut without hesitation
TLS 1.3 simplifies negotiation and removes many historical bad choices. That is progress — not a reason to drop TLS 1.2 overnight.
In practice:
- Keep TLS 1.2 and 1.3 on a public site until you have client metrics (handshake logs, support tickets, browser analytics).
- Cut without mercy SSLv3, TLS 1.0, TLS 1.1, RC4, 3DES and "export" ciphers.
- Prefer ECDHE for Perfect Forward Secrecy and AES-GCM or ChaCha20 for symmetric encryption.
Test beyond SSL Labs: a real browser, an old Android if your traffic justifies it, and ideally a client behind a corporate proxy if you sell B2B.
Certificates, full chain and renewal
Perfect cipher configuration does not fix a badly served certificate. Frequent mistakes:
- Incomplete chain — server does not send intermediate; some clients error, others do not.
- Silent expiry — Let's Encrypt renews every 90 days, but only if HTTP-01 or DNS-01 challenge succeeds and nginx reloads afterward. See ACME: monitor certificate renewal.
- Poorly planned wildcard — convenient for ten subdomains, but a stolen key opens the whole scope. Wildcard renewal requires automated DNS-01.
Monitor expiry three weeks before deadline — not the day before. SSL Labs does not replace a Prometheus alert or a cron reading certbot certificates.
To choose between Let's Encrypt and a paid certificate for your context, see Let's Encrypt or paid certificate.
HSTS, OCSP stapling and related headers
These settings do not replace good TLS config, but complement it:
OCSP stapling — server attaches OCSP response to handshake, speeding client verification. On nginx: ssl_stapling on; and verify chain is correct.
HSTS (Strict-Transport-Security) — browser stops trying plain HTTP for the stated duration. Enable includeSubDomains and preload only when HTTPS works on all concerned subdomains. Premature HSTS makes HTTP rollback very painful.
Headers like X-Content-Type-Options, Referrer-Policy or Content Security Policy belong to the same hardening effort — but remain distinct from cipher choice. Do not merge them into one copied "security snippet".
Shared hosting, VPS or CDN: who configures what?
| Context | TLS control | Responsibility |
|---|---|---|
| Shared | Host panel, little custom cipher | Verify TLS on, valid cert, HTTPS redirect |
| VPS / cloud | nginx, Caddy, Apache — full control | Mozilla config + renewal + reload after renew |
| CDN in front of origin | Visitor TLS terminated at CDN | Separate origin cert; do not leave origin HTTP plain |
If Cloudflare or a CDN terminates TLS, the public domain's SSL Labs grade may not describe what your origin serves internally. Check both ends of the chain.
Compare offers where you keep nginx control via our directory and comparison tool.
The peak: the A+ grade that breaks production
Here is what "max security" checklists forget to say.
Maintainable beats esoteric: Mozilla Intermediate profile, monitored renewal, compatibility test before cutting TLS 1.2.
Decide and move forward without blind spots
In half a day you can put TLS on solid ground:
- Generate an Intermediate profile from Mozilla for your exact web server.
- Replace the old snippet — keep old config commented one week while testing.
- Check SSL Labs and a real user journey (login, API, mobile).
- Set up certificate expiry alert — not just HTTP uptime check.
- Document who changes config, where, and how to reload server after ACME renewal.
- Schedule annual review — ideally after a major Chrome or Firefox release.
For a simple brochure site, SSL certificate for a brochure site may be enough before opening nginx. For heavier stacks, follow with ACME renewal once Let's Encrypt is in place.
Frequently asked questions
Is TLS 1.3 alone enough in production?
Rarely for a public site. TLS 1.2 + 1.3 with Intermediate profile covers most cases. Measure before cutting 1.2.
Where to find up-to-date configuration?
Mozilla SSL Configuration Generator — Intermediate for general production, Modern if you control all clients.
Should you enable HSTS and OCSP stapling?
Stapling yes if supported. HSTS after HTTPS validation on all concerned hosts — not on day one of migration.
Wildcard certificate or one per subdomain?
Wildcard to simplify ops; separate certs to isolate scope. Automated wildcard = ACME DNS-01.
Good TLS configuration is updated every year — not pasted once for SSL Labs glory.