DEV Community

Ramer Labs
Ramer Labs

Posted on

7 Tips for Hardening TLS and HTTP/2 on Nginx for Production

Why TLS Hardening Matters

Transport Layer Security (TLS) is the first line of defense for any public‑facing web service. A mis‑configured TLS stack can expose your site to downgrade attacks, weak cipher exploitation, and even data leakage. When you add HTTP/2 to the mix, you gain performance benefits—but only if the underlying TLS configuration is rock‑solid. This guide walks you through seven practical steps to lock down TLS and enable HTTP/2 on Nginx, targeting SREs who need a secure, high‑performance edge.


1. Enforce Modern Protocol Versions

Older protocols like SSLv3, TLS 1.0, and TLS 1.1 are considered insecure. Nginx lets you specify exactly which versions to negotiate.

ssl_protocols TLSv1.2 TLSv1.3;   # Only allow TLS 1.2 and 1.3
ssl_prefer_server_ciphers on;   # Server decides the cipher order
Enter fullscreen mode Exit fullscreen mode

TLS 1.3 brings forward secrecy by default and reduces handshake latency, while TLS 1.2 remains necessary for older browsers that don’t yet support 1.3.


2. Curate a Strong Cipher Suite

A curated cipher list eliminates weak algorithms (e.g., DES, 3DES, RC4) and prefers AEAD ciphers with forward secrecy.

ssl_ciphers \
  "TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:" \
  "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:" \
  "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256";
Enter fullscreen mode Exit fullscreen mode

The ordering matters: Nginx will pick the first mutually supported cipher. The list above mirrors Mozilla’s "Intermediate" recommendation, balancing compatibility and security.


3. Enable HTTP/2 Safely

HTTP/2 requires TLS on most browsers, and Nginx can enable it with a single directive. However, you should also turn off the server_tokens directive to avoid leaking version information.

listen 443 ssl http2;
server_tokens off;
Enter fullscreen mode Exit fullscreen mode

If you need to support HTTP/1.1 for legacy clients, Nginx will automatically fall back.


4. Harden Header Security

Security‑related headers add another layer of protection against click‑jacking, MIME sniffing, and mixed‑content issues.

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header Referrer-Policy "no-referrer-when-downgrade";
add_header Content-Security-Policy "default-src 'self'";
Enter fullscreen mode Exit fullscreen mode

The HSTS header tells browsers to always use HTTPS for the next two years and signals readiness for the Chrome preload list.


5. Configure OCSP Stapling

OCSP stapling reduces latency and protects against certificate revocation attacks. It requires a valid ssl_trusted_certificate that contains the full chain of your CA.

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/ssl/certs/ca-bundle.crt;
resolver 8.8.8.8 8.8.4.4 valid=300s;   # Google's DNS for OCSP queries
Enter fullscreen mode Exit fullscreen mode

With stapling enabled, the server presents the OCSP response during the TLS handshake, eliminating the extra round‑trip to the CA.


6. Optimize Session Resumption

TLS session tickets and session caches speed up repeat connections. For most production environments, enabling both is safe.

ssl_session_cache shared:SSL:10m;   # Approx. 4000 sessions
ssl_session_timeout 1d;
ssl_session_tickets on;            # Enable tickets (default in modern Nginx)
Enter fullscreen mode Exit fullscreen mode

If you have strict compliance requirements, you can disable tickets and rely solely on server‑side caches.


7. Test, Monitor, and Automate Renewal

A hardened configuration is only useful if you know it works. Use tools like Qualys SSL Labs, testssl.sh, or openssl s_client to verify protocol and cipher support.

# Quick OpenSSL sanity check
openssl s_client -connect example.com:443 -tls1_3 -servername example.com
Enter fullscreen mode Exit fullscreen mode

Set up automated monitoring with Prometheus + node_exporter to alert on TLS handshake failures or expired certificates. Combine this with certbot or acme.sh for zero‑downtime renewal.

# Example certbot renewal hook that reloads Nginx
#!/bin/sh
/usr/sbin/nginx -s reload
Enter fullscreen mode Exit fullscreen mode

Putting It All Together

Below is a minimal yet production‑ready server block that incorporates the seven tips:

server {
    listen 443 ssl http2;
    server_name www.example.com;

    # TLS basics
    ssl_certificate     /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers "TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256";

    # Session handling
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets on;

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/ssl/certs/ca-bundle.crt;
    resolver 8.8.8.8 8.8.4.4 valid=300s;

    # Security headers
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options DENY;
    add_header Referrer-Policy "no-referrer-when-downgrade";
    add_header Content-Security-Policy "default-src 'self'";
    server_tokens off;

    # Application root
    root /var/www/html;
    index index.html index.htm;
}
Enter fullscreen mode Exit fullscreen mode

Deploy the block, reload Nginx (nginx -s reload), and run a quick SSL Labs scan. You should see an "A+" rating with no protocol or cipher warnings.


Final Thoughts

Hardening TLS and enabling HTTP/2 on Nginx is a low‑effort, high‑impact investment for any production site. By following these seven steps you gain stronger encryption, faster handshakes, and better visibility into potential misconfigurations. Remember to treat TLS as a living component: schedule regular scans, keep your OpenSSL library up to date, and automate certificate renewals. For deeper dives into Nginx performance tuning and real‑world case studies, check out https://lacidaweb.com for practical guides and community insights.

Top comments (0)