HTTP/2 offers a significant performance boost over HTTP/1.1, but its security relies heavily on the underlying transport layer, primarily TLS. Without proper TLS configuration, HTTP/2 can expose your users and your infrastructure to serious vulnerabilities.

Here’s how to see HTTP/2 security in action, focusing on TLS, HSTS, and cipher suites.

First, let’s establish a baseline. Imagine a simple Nginx server configured for HTTP/2.

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

    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    # Basic TLS settings
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';

    # HSTS header
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

This configuration enables HTTP/2 on port 443, specifies TLS certificates, defines allowed TLS protocols, prioritizes server-side cipher suite negotiation, lists strong cipher suites, and enforces HSTS.

Let’s break down what’s happening and why it matters.

TLS: The Foundation of HTTP/2 Security

HTTP/2 requires TLS for most browsers (though technically not mandated by the RFC, browsers enforce it). This means all communication is encrypted. The strength of this encryption is determined by your TLS configuration.

  • TLS Protocols: ssl_protocols TLSv1.2 TLSv1.3; This line ensures only modern, secure TLS versions are used. TLSv1.2 and TLSv1.3 are widely considered secure. Older versions like TLSv1.0 and TLSv1.1 have known vulnerabilities and should be disabled. To check your server’s supported protocols, you can use openssl s_client -connect example.com:443 -tls1. If it connects, TLSv1 is enabled. If it fails, it’s disabled.

  • Cipher Suites: ssl_ciphers '...'; This is a critical setting. A cipher suite is a set of algorithms used to establish a secure TLS connection. It includes an authentication algorithm, a key exchange algorithm, an encryption algorithm, and a message authentication code (MAC) algorithm. The ssl_ciphers directive in Nginx defines the preferred order and the allowed suites.

    • Why ECDHE and GCM? The example cipher list prioritizes ECDHE (Elliptic Curve Diffie-Hellman Ephemeral) for key exchange and GCM (Galois/Counter Mode) for encryption. ECDHE provides Perfect Forward Secrecy (PFS), meaning that even if your server’s private key is compromised in the future, past communications encrypted with ephemeral keys derived from that session will remain secure. GCM modes are authenticated encryption modes, providing both confidentiality and integrity, and are generally faster than older modes like CBC.
    • Why CHACHA20-POLY1305? This is a modern, fast, and secure alternative to AES, especially beneficial on systems without hardware AES acceleration.
    • Checking Cipher Suites: You can use online tools like Qualys SSL Labs’ SSL Test (https://www.ssllabs.com/ssltest/) to analyze your server’s TLS configuration, including its supported cipher suites and their order. Manually, you can use openssl s_client -connect example.com:443 -cipher 'AES128-SHA' to test specific suites.
  • ssl_prefer_server_ciphers on;: This tells Nginx to use the order of cipher suites it defines, rather than letting the client dictate. This is crucial because clients might offer weaker suites first.

HTTP Strict Transport Security (HSTS): Forcing HTTPS

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

HSTS is an HTTP response header that tells browsers to only communicate with your domain over HTTPS.

  • max-age=31536000: This is the duration (in seconds) for which the browser should remember to only connect via HTTPS. 31536000 seconds is one year.
  • includeSubDomains: This directive ensures that all subdomains of your domain also enforce HSTS.
  • preload: This is an opt-in mechanism. If you include preload, you can submit your domain to a public HSTS preload list maintained by browsers. This means browsers will have a hardcoded list of domains that must be accessed via HTTPS, even on the very first visit before any HSTS header has been received. This protects against SSL stripping attacks.

To submit your site for preloading, you’ll typically visit a site like hstspreload.org and follow their instructions.

The Mental Model: How it All Fits Together

Think of TLS as the armored car that carries your data. It ensures that only the intended recipient can read the contents and that the contents haven’t been tampered with in transit. HTTP/2 leverages this secure channel.

HSTS is like a strict security guard at the entrance of your building. The guard, after the first successful HTTPS connection, tells everyone entering, "From now on, you must use the armored car (HTTPS) to get to this building. No exceptions." The preload directive is like giving the guard a list of buildings that always require the armored car, even for first-time visitors.

The cipher suite selection is about choosing the right type of lock and key for that armored car. You want strong, modern locks that are difficult to pick and that offer a fresh set of keys for each trip (PFS).

The Counterintuitive Part: HSTS and Initial Connections

It’s easy to think HSTS protects you from the very first time someone visits your site. However, HSTS, by its nature, is a header sent after a successful connection. If a user types http://example.com into their browser for the very first time, and you don’t have a redirect from HTTP to HTTPS configured at the web server level, they will connect via unencrypted HTTP. It’s only on subsequent visits, or if they explicitly type https://example.com, that the HSTS header comes into play. This is where the preload directive becomes incredibly valuable, as it bypasses the need for an initial unencrypted connection to fetch the header.

Next Steps: Certificate Management and Beyond

Once your TLS and HSTS are solid, the next immediate concern is certificate lifecycle management. You’ll need to ensure your TLS certificates are kept up-to-date, using strong certificate authorities, and that you have a robust process for renewal before they expire. The next error you might encounter is related to certificate expiry or revocation.

Want structured learning?

Take the full Http2 course →