OCSP Stapling on NGINX and Apache

David Oravsky - 7 min read124 VIEWS
Last Updated - Sep 23, 2021
Summary : This post will review what OCSP stapling is and does. We'll also lay out the steps necessary to configure OCSP Stapling on both NGINX and Apache.

Introduction

When connecting to a server, clients must verify the validity of the server certificate using either a CRL (Certificate Revocation List), or an OCSP (Online Certificate Status Protocol) record.  The problem with CRLs is that the lists have become huge and loading them takes forever.

OCSP is much more lightweight, since only one entry is extracted at a time.  But a side effect is that OCSP requests must be send to a third-party OCSP responder when connecting to the server, which adds a delay and possible failures.  In fact, the OCSP respondents managed by certificate authorities are often so unreliable that the browser silently crashes if no response is received in a timely manner.  This reduces security by allowing someone with malicious intent to perform a DoS (Denial of Service) attack on an OCSP responder to disable the check.

The solution is to allow the server to send its cached OCSP entry during the TLS handshake, therefore, bypassing the OCSP responder.  This mechanism retains the two-way communication between the client and the OCSP responder and is called OCSP Stapling.

The server will send a cached OCSP response only if the client requests it, announcing support for the TLS extension of the status request in its client “Hello” message.

Most servers will cache OCSP responses for up to 48 hours.  At regular intervals, the server will connect to the OCSP CA responder to receive a new OCSP record.  The location of the OCSP responder is taken from the Authority Information Access field of the signed certificate.

What is OCSP Stapling?

OCSP stapling is defined in IETF RFC 6066.  The term "stapling" is a popular term used to describe how a web server receives an OCSP response.  The web server caches the response from the CA that issued the certificate.  When an SSL/TLS handshake is initiated, the web server returns a response to the client by attaching the cached OCSP response to a CertificateStatus message.  To use OCSP stapling, the client must include the status_request extension with its SSL/TSL client "Hello" message.

OCSP stapling has several advantages, including the following:

  • The relying party receives the status of the web server certificate when it is needed (during the SSL/TLS handshake).
  • No additional HTTP connection is required with the issuing CA.
  • OCSP stapling provides additional security by reducing the number of attack vectors.

Check the following links for more information about OCSP and OCSP stapling:

NGINX - Requirements

You need at least NGINX 1.3.7 for this to work.  This is not available in current releases of Ubuntu LTS (12.04), it has 1.1.19 and on CentOS you need EPEL or the official repositories.  However, it is easy to install the latest version of NGINX.

You also need to create a firewall exception to allow your server to make outbound connections to upstream OCSPs. You can view all OCSP URIs from a website using this command:

OLDIFS=$IFS; IFS=':' certificates=$(openssl s_client -connect google.com:443 -showcerts -tlsextdebug -tls1 2>&1 </dev/null 
| sed -n '/-----BEGIN/,/-----END/ {/-----BEGIN/ s/^/:/; p}'); for certificate in ${certificates#:}; do echo $certificate 
| openssl x509 -noout -ocsp_uri; done; IFS=$OLDIFS

It should show the following results for google.com:

http://clients1.google.com/ocsp
http://gtglobal-ocsp.geotrust.com

Now try replacing google.com with your domain.

NGINX - Configuration

Add the below configuration to your https (443) server block:

ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

For the OCSP stapling to work, the certificate of the server certificate provider must be known.  If the ssl_certificate file does not contain intermediate certificates, the certificate of the server certificate provider must be present in the ssl_trusted_certificate file.

The certificate for techievor.com is issued by Let’s Encrypt.  That certificate is cross-signed by IdenTrust DST Root CA x3. In our NGINX ssl_certificate file, all these certificates are present.  If this is not the case for your configuration, create a file with the certificate chain and use it like so:

ssl_trusted_certificate /etc/ssl/certs/domain.chain.stapling.pem;

Prior to version 1.1.7, only one name server could be configured.  Specifying name servers using IPv6 addresses is supported starting with versions 1.3.1 and 1.2.2.  By default, NGINX will look for IPv4 and IPv6 addresses when resolving.  If searching for IPv6 addresses is not desired, you can specify the ipv6=off parameter.  Name resolution to IPv6 addresses has been supported since version 1.5.8.

By default, NGINX caches responses using the TTL response value.  The (optional) valid parameter allows you to override it for 5 minutes.  Prior to version 1.1.9, setting the caching time was not possible, and NGINX always cached response lasting 5 minutes.

Restart NGINX to load the new configuration:

service nginx restart

Apache - Requirements

You need at least Apache 2.3.3 and higher, plus OpenSSL 0.9.8h or higher for this to work.  It is not available in current releases of Ubuntu LTS (12.04), it has 2.2.22 and CentOS 6 has 2.2.15.  Either find personal package archive repositories, unofficial repositories, or compile them yourself.

You also need to create a firewall exception to allow your server to make outbound connections with upstream OCSPs.  You can view all OCSP URIs from a website using this command:

OLDIFS=$IFS; IFS=':' certificates=$(openssl s_client -connect google.com:443 -showcerts -tlsextdebug -tls1 2>&1 </dev/null 
| sed -n '/-----BEGIN/,/-----END/ {/-----BEGIN/ s/^/:/; p}'); for certificate in ${certificates#:}; do echo $certificate 
| openssl x509 -noout -ocsp_uri; done; IFS=$OLDIFS

It should show the following results for google.com:

http://clients1.google.com/ocsp
http://gtglobal-ocsp.geotrust.com

Now try replacing google.com with your domain.  Also note that you need the GNU version of sed and bash. It does not work on OS X or BSD.

Apache - Configuration

Add the below configuration to your virtualhost:

SSLUseStapling on
SSLStaplingCache "shmcb:logs/stapling-cache(150000)"

The SSLStaplingCache parameter configures the cache used to store OCSP responses that are included in the TLS handshake if SSLUseStapling is enabled.  The cache configuration is mandatory for OCSP stapling.  With the exception of none and nonenotnull, the same storage types are supported as in SSLSessionCache.

The shmcb parameter allows the use of a high-performance cyclic buffer (approximately in bytes in size) within the shared memory segment in RAM (set via /path/to/datafile) to synchronize local OpenSSL memory caches of server processes.  This is the recommended session cache. To use this, make sure that mod_socache_shmcb is loaded.

There are a few other optional parameters you can provide.  

For instance, a freshness timeout (how old the OCSP response can be):

SSLStaplingResponseMaxAge 900

This lets the response only be max 15 minutes old (900 seconds).

If your Apache server is behind an HTTP proxy and you need to perform OCSP requests through a proxy, you can use SSLStaplingForceURL.  This overrides the URL provided by the certificate:

SSLStaplingForceURL http://internal-proxy.example.org

Restart your Apache to load the new configuration:

service apache2 restart

Test Configuration

Now that we have configured OCSP stapling, let’s test it out.  Start a terminal and use the following OpenSSL command to connect to your website:

openssl s_client -connect example.org:443 -tls1 -tlsextdebug -status

Replace example.org with your domain name.  In the response, look for the following:

OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
    Version: 1 (0x0)
    Responder Id: 99E4405F6B145E3E05D9DDD36354FC62B8F700AC
    Produced At: Feb  3 04:25:39 2014 GMT
    Responses:
    Certificate ID:
        Hash Algorithm: sha1
        Issuer Name Hash: 0226EE2F5FA2810834DACC3380E680ACE827F604
        Issuer Key Hash: 99E4405F6B145E3E05D9DDD36354FC62B8F700AC
        Serial Number: C1A3D8D00D72FCE483CD84759E9EC0BC
    Cert Status: good
    This Update: Feb  3 04:25:39 2014 GMT
    Next Update: Feb  7 04:25:39 2014 GMT

That means it is working.  If you get a response like below, it is not working:

OCSP response: no response sent

You can also use the SSL Labs test to see if OCSP stapling works.  Look for "OCSP stapling" near the bottom of the report, in the "Protocol Details" section.

Conclusion

OCSP stapling helps protect user information while reducing page load time.  By allowing the browser to retrieve SSL certificate information from the server rather than returning to the CA server for each request, it can achieve both of these results.  Often, the page load time is reduced at the same time, and user security is improved, but the inclusion of OCSP stapling makes it easier.

If you like this article, consider sponsoring us by trying out a Digital Ocean VPS. With this link you'll get $100 credit for 60 days.

Additional Reading