TLS & HTTPS With Nginx

Every public website and API should be served over HTTPS, and Nginx is one of the most common places to terminate TLS. It holds the certificate and private key, negotiates encryption with clients, and forwards plain or re-encrypted traffic to backends. A correct configuration protects users' data, earns browser trust, enables HTTP/2 and HTTP/3, and passes security scanners. A careless one leaves weak protocols enabled, redirect loops, or expired certificates that take the site down.

Modern best practice is well established: automated certificates from Let's Encrypt (or your cloud CA), TLS 1.2 and 1.3 only, strong cipher suites, HSTS, and OCSP stapling. See HTTPS & TLS for the protocol fundamentals.

TL;DR

Quick Example

Core Concepts

Certificates

Automating With ACME

Let's Encrypt issues free 90-day certificates via the ACME protocol, and shorter lifetimes are coming. Automation is mandatory:

Protocols and Ciphers

HSTS

Strict-Transport-Security tells browsers to use HTTPS for your domain for max-age seconds, preventing downgrade and SSL-stripping attacks. Roll out gradually (a short max-age first, then a long one), add includeSubDomains only when every subdomain supports HTTPS, and consider preload only when you're sure it's permanent. See security headers.

OCSP Stapling and Session Resumption

HTTP/2 and HTTP/3

http2 on; enables HTTP/2 multiplexing over TLS, which is standard for all modern browsers. HTTP/3 runs over QUIC (UDP): enable it with listen 443 quic, advertise it with Alt-Svc, and open UDP 443 in firewalls. See HTTP/3 and QUIC.

TLS to Upstreams and mTLS

If traffic between Nginx and backends crosses untrusted networks, encrypt it:

Mutual TLS (ssl_verify_client on with ssl_client_certificate) requires clients to present certificates, which is common for service-to-service APIs and zero trust networks.

Best Practices

Automate Renewal and Monitor Expiry

Expired certificates are one of the most common, and most avoidable, outages. Automate renewal, and independently alert on certificate expiry (blackbox exporter probes, uptime monitors) at least 14 days out.

Use Proven Configuration Templates

Start from Mozilla's generator for your Nginx and OpenSSL versions, rather than copying old snippets with outdated ciphers or directives.

Test Your Configuration

Use SSL Labs' server test, testssl.sh, or nmap --script ssl-enum-ciphers to verify protocols, ciphers, chain completeness, and HSTS. Aim for an A or A+.

Terminate Once, Deliberately

Decide where TLS terminates (CDN, cloud load balancer, Nginx, or the app) and configure forwarded headers correctly downstream, so apps know the original scheme. See Nginx reverse proxy.

Common Mistakes

Serving Only the Leaf Certificate

Incomplete chains cause "unable to verify the first certificate" errors in curl, mobile apps, and API clients.

Enabling HSTS Before HTTPS Works Everywhere

A long-lived includeSubDomains HSTS header makes browsers refuse HTTP for every subdomain, breaking any that don't yet have valid HTTPS, and it can't be revoked quickly for returning visitors.

Redirect Loops Behind Another Proxy

If a load balancer terminates TLS and talks HTTP to Nginx, a blanket "redirect to HTTPS" in Nginx loops forever. Redirect based on X-Forwarded-Proto from the trusted load balancer, or perform redirects at the edge.

FAQ

How do I get a free TLS certificate for Nginx?

Use Let's Encrypt via an ACME client such as Certbot (certbot --nginx or certonly --webroot), acme.sh, or cert-manager in Kubernetes. Certificates are valid for 90 days, so enable automatic renewal and reload Nginx after each renewal.

Which TLS versions should I support?

TLS 1.2 and TLS 1.3. Older versions (SSL 3.0, TLS 1.0, 1.1) are insecure and deprecated by browsers and standards. Only keep TLS 1.2 ciphers with forward secrecy and authenticated encryption.

Does HTTPS slow down my site?

Negligibly on modern hardware, and HTTPS unlocks HTTP/2 and HTTP/3, which usually make sites faster. Session resumption, OCSP stapling, ECDSA certificates, and TLS 1.3 (one round-trip handshake) keep the overhead minimal.

Should TLS terminate at Nginx or at the load balancer?

Either works. Terminating at a managed cloud load balancer or CDN simplifies certificate management at the edge. Terminating (or re-encrypting) at Nginx keeps traffic encrypted closer to the application. Security policies may require encryption all the way to the backend.

Related Topics

References