How to Enable OCSP Stapling in Nginx

How to Enable OCSP Stapling in Nginx

How to Enable OCSP Stapling in Nginx

Every time a browser connects to your HTTPS site, it needs to check whether your SSL certificate has been revoked. Traditionally that meant the browser itself contacted the certificate authority’s OCSP (Online Certificate Status Protocol) server directly — which adds latency, leaks a bit of the visitor’s browsing behavior to the CA, and occasionally fails outright if the CA’s responder is slow or down. OCSP stapling flips this: your server checks the revocation status ahead of time and “staples” that signed response onto the TLS handshake, so the browser never has to make a separate call at all.

It’s a small change with a real payoff — faster handshakes, better privacy for visitors, and one less point of failure in your TLS chain. This guide covers what OCSP stapling actually does, how to enable it properly in Nginx, and how to verify it’s really working (a step a lot of guides skip, leaving people with a config that looks right but silently isn’t stapling anything).

How OCSP and OCSP Stapling Work

When a certificate is issued, it includes a URL for an OCSP responder — a service run by the certificate authority that can answer “is this certificate still valid?” Without stapling, here’s what happens on every connection:

  1. Browser receives your certificate.
  2. Browser contacts the CA’s OCSP responder directly to check revocation status.
  3. CA responds “good,” “revoked,” or “unknown.”
  4. Browser completes the handshake.

That second step is the problem — it’s a synchronous network round trip the visitor’s browser has to make, often to a server they’ve never talked to before, adding real latency and creating a privacy leak (the CA now knows every site that visitor connects to).

With OCSP stapling:

  1. Your Nginx server periodically fetches the OCSP response from the CA itself (not the visitor — your server does this in the background).
  2. Nginx caches that signed response.
  3. When a visitor connects, Nginx “staples” the cached, signed OCSP response directly onto the TLS handshake.
  4. The browser verifies the stapled response’s signature and trusts it — no separate network call needed.

The response is cryptographically signed by the CA, so the browser can trust it without contacting the CA itself. It’s a genuinely elegant solution to a real performance and privacy problem.

Requirements

Step 1: Confirm Your Certificate Chain Is Complete

OCSP stapling requires Nginx to send the issuer (intermediate) certificate along with your own, because the stapled response needs to be verified against the chain. If you’re using Let’s Encrypt via Certbot, fullchain.pem already includes this — that’s exactly why it’s used instead of cert.pem alone.

Check your chain:

openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -noout -issuer -subject

If you’re managing certificates manually from a commercial CA, make sure you concatenate your certificate with the CA’s intermediate bundle:

cat your_domain.crt intermediate.crt > fullchain.crt

Step 2: Configure Nginx for OCSP Stapling

Edit your server block (or a shared SSL config file included across virtual hosts):

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

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;

    # The trusted certificate used to verify the OCSP response signature.
    # This should be the CA's chain, NOT including your own leaf cert.
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;

    # DNS resolver Nginx uses to reach the OCSP responder
    resolver 8.8.8.8 1.1.1.1 valid=300s;
    resolver_timeout 5s;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
}

Key directives explained:

Step 3: Test the Configuration and Reload

sudo nginx -t
sudo systemctl reload nginx

Step 4: Verify Stapling Is Actually Working

This is the step most tutorials skip, and it matters — a broken stapling config doesn’t throw errors, it just silently doesn’t staple anything, and your site keeps working exactly as before (minus the benefit).

Using OpenSSL directly:

echo | openssl s_client -connect example.com:443 -status 2>/dev/null | grep -A 17 "OCSP response"

Look for OCSP Response Status: successful (0x0) and Cert Status: good. If instead you see OCSP response: no response sent, stapling isn’t working.

Using SSL Labs:

Run your domain through SSL Labs’ SSL Server Test — the results page includes an explicit “OCSP Stapling” field that reports Yes/No.

Checking Nginx error logs for stapling issues:

sudo tail -f /var/log/nginx/error.log

If Nginx can’t reach the OCSP responder or the resolver isn’t configured, you’ll see warnings like:

[warn] ssl_stapling ignored, issuer certificate not found

That specific warning almost always means your ssl_trusted_certificate is pointing at the wrong file, or is missing entirely.

Troubleshooting Common Issues

“issuer certificate not found” warning. Your ssl_trusted_certificate isn’t set, or points to a file that doesn’t contain the actual intermediate CA cert. Double-check you’re using the chain file, not the full combined bundle.

OCSP response shows but is stale/old. Nginx caches the OCSP response according to the nextUpdate field the CA provides — this is normal and by design, not a bug. Responses are typically valid for several days.

Stapling works on curl/OpenSSL tests but SSL Labs reports “No.” Check that you’re testing the exact hostname SSL Labs uses, and that any CDN/load balancer in front of your server isn’t terminating TLS itself (in which case stapling needs to be configured there, not on your origin Nginx).

“no route to host” or timeouts in error log. Your resolver can’t reach the internet, or a firewall is blocking outbound port 80/443 to the OCSP responder. Verify with curl -I http://ocsp.your-ca.com from the server itself.

Works after reload but breaks after a while. This can happen if resolver cache validity (valid=300s) is too short combined with a flaky upstream DNS resolver — try a more reliable resolver pair, or extend valid=3600s.

Security Considerations

Performance Tips

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1h;
ssl_session_tickets off;

Real-World Use Cases

Best Practices

Wrapping Up

OCSP stapling is one of those TLS hardening steps that costs almost nothing to implement but quietly makes every visitor’s connection to your site a little faster and a little more private. The configuration itself is short — five or six directives — but getting the chain file right and actually verifying it’s working is where most setups go wrong. Take the extra two minutes to check with OpenSSL or SSL Labs after enabling it; a config that “looks correct” but isn’t actually stapling responses is a very easy mistake to ship unnoticed.

Exit mobile version