SSL / TLS

OCSP stapling

Available since

  • HAProxy 2.8
  • HAProxy Enterprise 2.8r1
  • Not available in HAProxy ALOHA

The Online Certificate Status Protocol (OCSP) allows a client (browser) to see the revocation status of an SSL/TLS certificate in real time. A client contacts an OCSP Responder server to get the OCSP response, which contains the certificate’s revocation status. The Responder server is often managed by the certificate issuer. Because the browser must make a separate call to the OCSP Responder server to fetch the certificate’s revocation status, OCSP adds a small delay to a user’s request.

OCSP stapling is a mechanism that allows you to fetch the revocation status ahead of time and attach it to the certificate, saving the client from needing to make that request to the OCSP Responder server. The OCSP response contains a revocation status for the certificate of either good, revoked, or unknown.

As of HAProxy version 2.8, when OCSP stapling is enabled, the load balancer will automatically update the OCSP response for its configured certificates by contacting the OCSP Responder server at the URI contained within the certificate.

For earlier versions of HAProxy, you can must retrieve the OCSP response manually and load it into HAProxy’s memory using the Runtime API’s set ssl ocsp-response command.

Enable OCSP stapling Jump to heading

When OCSP stapling is enabled, the load balancer will automatically retrieve and update the OCSP response for each of its configured certificates.

To enable OCSP stapling:

  1. Verify that your server TLS certificate contains an OCSP URI by using the openssl x509 command with -ocsp_uri argument:

    nix
    openssl x509 -in ./mysite.pem -noout -ocsp_uri
    nix
    openssl x509 -in ./mysite.pem -noout -ocsp_uri
    output
    text
    http://ocsp.issuer.com
    output
    text
    http://ocsp.issuer.com
  2. Ensure that the issuer’s intermediate certificate is present on your load balancer server in one of two ways:

    • Append it within your server TLS certificate .pem file. Your server certificate .pem file should contain the following, in any order:

      • public certificate
      • private key
      • any intermediate certificates
    • Save it to its own file in the same directory as the server certificate, sharing the same name as the server certificate but with the suffix .issuer.

  3. Enable OCSP stapling either:

Enable for all certificates Jump to heading

Available since

  • HAProxy 3.0
  • HAProxy Enterprise 3.0

To Enable OCSP stapling at the global level for all certificates in the configuration:

  1. Set the ocsp-update.mode global directive to on.

    haproxy
    global
    ocsp-update.mode on
    haproxy
    global
    ocsp-update.mode on
  2. Optional: Set the global configuration parameters ocsp-update.maxdelay and ocsp-update.mindelay to specify the minimum and maximum intervals between automatic updates of the same OCSP response. Their defaults are 3600 seconds (1 hour) and 300 seconds (5 minutes), respectively. ocsp-update.mindelay must be set to a value lower than that specified for ocsp-update.maxdelay.

    haproxy
    global
    ocsp-update.mode on
    ocsp-update.mindelay 300
    ocsp-update.maxdelay 3600
    haproxy
    global
    ocsp-update.mode on
    ocsp-update.mindelay 300
    ocsp-update.maxdelay 3600
  3. Reload the load balancer configuration.

    nix
    sudo systemctl reload haproxy
    nix
    sudo systemctl reload haproxy
    nix
    sudo systemctl reload hapee-3.0-lb
    nix
    sudo systemctl reload hapee-3.0-lb

Enable for specific certificates Jump to heading

To Enable OCSP stapling for one or more specific certificates, use either a crt-list or a crt-store to specify your OCSP stapling settings.

Use crt-store

Starting in HAProxy version 3.0 and HAProxy Enterprise version 3.0r1 you can use a crt-store section in place of a crt-list to enable OCSP stapling. Prior to these versions, you must declare your OCSP settings in a crt-list. OCSP stapling is not available in HAProxy ALOHA.

For more information on crt-store, see Use crt-store to enable TLS.

Choose one of:

Use a crt-list to enable OCSP stapling

A crt-list file enumerates the certificates bound to a listener and describes metadata about each certificate, such as ALPN, minimum TLS version, and OCSP. You can create a crt-list file, for example crt-list.txt, that has one line for each of the certificates you want to bind to. For example, if you host multiple websites at the same IP address, then you will add a line for each TLS certificate. Each line includes the path to the certificate. Your corresponding issuer certificates should reside at this path as well.

  1. Using the text editor of your choice, create the crt-list file. In this example, we will create a file named crt-list.txt. For this example, we will specify one certificate.

    In the example crt-list file below, our PEM file is located in the certs directory. We are specifying our ALPN options here as well, alpn h2, and enabling OCSP with ocsp-update on. Note that the ocsp-update on argument can be included only in a crt-list. It cannot be added to a bind line.

    crt-list.txt
    nix
    /etc/haproxy/certs/mysite.pem [alpn h2 ocsp-update on]
    crt-list.txt
    nix
    /etc/haproxy/certs/mysite.pem [alpn h2 ocsp-update on]
    crt-list.txt
    nix
    /etc/hapee-3.0/certs/mysite.pem [alpn h2 ocsp-update on]
    crt-list.txt
    nix
    /etc/hapee-3.0/certs/mysite.pem [alpn h2 ocsp-update on]
  2. Add a bind line to your frontend that specifies the path to the crt-list. The load balancer will load the certificates according to the options specified in the crt-list.

    haproxy
    frontend www
    bind :443 ssl crt-list /etc/haproxy/certs/crt-list.txt
    default_backend webservers
    haproxy
    frontend www
    bind :443 ssl crt-list /etc/haproxy/certs/crt-list.txt
    default_backend webservers
    haproxy
    frontend www
    bind :443 ssl crt-list /etc/hapee-3.0/certs/crt-list.txt
    default_backend webservers
    haproxy
    frontend www
    bind :443 ssl crt-list /etc/hapee-3.0/certs/crt-list.txt
    default_backend webservers
  3. Optional: Set the global configuration parameters ocsp-update.maxdelay and ocsp-update.mindelay to specify the minimum and maximum intervals between automatic updates of the same OCSP response. Their defaults are 3600 seconds (1 hour) and 300 seconds (5 minutes), respectively. ocsp-update.mindelay must be set to a value lower than that specified for ocsp-update.maxdelay.

    Name of directive changed

    Prior to HAProxy 3.0, the ocsp-update directives were named tune.ssl.ocsp-update.

    haproxy
    global
    ocsp-update.mindelay 300
    ocsp-update.maxdelay 3600
    haproxy
    global
    ocsp-update.mindelay 300
    ocsp-update.maxdelay 3600
  4. Reload the load balancer configuration.

    nix
    sudo systemctl reload haproxy
    nix
    sudo systemctl reload haproxy
    nix
    sudo systemctl reload hapee-3.0-lb
    nix
    sudo systemctl reload hapee-3.0-lb
Use a crt-store to enable OCSP stapling

Instead of placing certificate definitions in files separate from the load balancer configuration, as would be the case when using a crt-list, we will place them within the configuration file itself using a crt-store section. To use a crt-store:

  1. Define a crt-store in your configuration section.

    haproxy
    crt-store web
    crt-base /etc/haproxy/certs/
    load crt mysite.pem ocsp-update on
    haproxy
    crt-store web
    crt-base /etc/haproxy/certs/
    load crt mysite.pem ocsp-update on
    haproxy
    crt-store web
    crt-base /etc/hapee-3.0/certs/
    load crt mysite.pem ocsp-update on
    haproxy
    crt-store web
    crt-base /etc/hapee-3.0/certs/
    load crt mysite.pem ocsp-update on
    • Specify a location for crt-base. The load balancer will look for the files at this location.
    • Set ocsp-update to on to enable OCSP stapling for your certificate.
  2. Reference the certificate files by their name and the name of the crt-store, in this case @web/mysite.pem, in your frontend:

    haproxy
    frontend www
    bind :443 ssl crt "@web/mysite.pem"
    default_backend webservers
    haproxy
    frontend www
    bind :443 ssl crt "@web/mysite.pem"
    default_backend webservers
  3. Optional: Set the global configuration parameters ocsp-update.maxdelay and ocsp-update.mindelay to specify the minimum and maximum intervals between automatic updates of the same OCSP response. Their defaults are 3600 seconds (1 hour) and 300 seconds (5 minutes), respectively. ocsp-update.mindelay must be set to a value lower than that specified for ocsp-update.maxdelay.

    Name of directive changed

    Prior to HAProxy 3.0, the ocsp-update directives were named tune.ssl.ocsp-update.

    haproxy
    global
    ocsp-update.mindelay 300
    ocsp-update.maxdelay 3600
    haproxy
    global
    ocsp-update.mindelay 300
    ocsp-update.maxdelay 3600
  4. Reload the load balancer configuration.

    nix
    sudo systemctl reload haproxy
    nix
    sudo systemctl reload haproxy
    nix
    sudo systemctl reload hapee-3.0-lb
    nix
    sudo systemctl reload hapee-3.0-lb

Save the OCSP response to a file Jump to heading

As an optional step, you can save the OCSP response to a file so that HAProxy loads it during startup. That will improve startup time. Otherwise, HAProxy keeps the response in memory only and will fetch the data again after a restart. Name the file the same as your TLS server certificate, but with a .ocsp file extension, for example mysite.ocsp. Save it to the same directory as your TLS server certificate.

  1. To save the response data to a file, do one of the following:

    • Call the Runtime API’s show ssl ocsp-response command to get the data already stored in memory and then save the result to a file.

    • Call the openssl ocsp command, replacing the values with your own:

      nix
      openssl ocsp \
      -issuer issuer.pem \
      -cert mysite.pem \
      -url http://ocsp.issuer.com \
      -host ocsp.issuer.com:80 \
      -respout mysite.ocsp
      nix
      openssl ocsp \
      -issuer issuer.pem \
      -cert mysite.pem \
      -url http://ocsp.issuer.com \
      -host ocsp.issuer.com:80 \
      -respout mysite.ocsp
  2. Add an ocsp argument to indicate the file to load.

    • If using crt-list, add an ocsp argument for each certificate:

      crt-list.txt
      nix
      /etc/hapee-3.0/certs/mysite.pem [alpn h2 ocsp-update on ocsp /etc/hapee-3.0/certs/mysite.ocsp]
      crt-list.txt
      nix
      /etc/hapee-3.0/certs/mysite.pem [alpn h2 ocsp-update on ocsp /etc/hapee-3.0/certs/mysite.ocsp]
    • If using crt-store, add an ocsp argument to the load directive:

      haproxy
      crt-store web
      crt-base /etc/hapee-3.0/certs/
      load crt mysite.pem ocsp-update on ocsp mysite.ocsp
      haproxy
      crt-store web
      crt-base /etc/hapee-3.0/certs/
      load crt mysite.pem ocsp-update on ocsp mysite.ocsp

Add an HTTP proxy for OCSP Jump to heading

Available since

  • HAProxy 3.0
  • HAProxy Enterprise 3.0r1

When you enable OCSP stapling, the load balancer periodically connects to an OCSP Responder server to fetch the revocation status of your SSL/TLS certificates. If your load balancer is in an air-gapped environment without direct Internet access, then you’ll need a way to connect to the OCSP Responder server. You can indicate an HTTP proxy to route OCSP update requests through by setting the global directive ocsp-update.httpproxy.

Below we set the IP address and port of our HTTP proxy:

haproxy
global
ocsp-update.httpproxy 192.168.0.10:8000
haproxy
global
ocsp-update.httpproxy 192.168.0.10:8000

Run a test OCSP Responder server Jump to heading

To validate your OCSP stapling setup, you can use openssl commands to run a test OCSP Responder server in your QA environment. The OCSP Responder server simulates returning OCSP responses. It also functions as a Certificate Authority (CA), issuing TLS certificates that you would install onto your QA load balancer and later revoke to see OCSP stapling in action. Deploy a Linux server in the same network as your QA load balancer.

Tutorial operating system

This tutorial uses Debian 12 (Bookworm) as the operating system for the OCSP Responder server.

After creating the server, perform these tasks on it:

  1. We rely on the openssl command-line utility. To check that it’s installed, run:

    nix
    openssl version
    nix
    openssl version
    output
    text
    OpenSSL 3.0.11 19 Sep 2023 (Library: OpenSSL 3.0.11 19 Sep 2023)
    output
    text
    OpenSSL 3.0.11 19 Sep 2023 (Library: OpenSSL 3.0.11 19 Sep 2023)
  2. This server will function as a CA that generates TLS certificates, private keys, CRLs, and CSRs for testing. Create the directory structure for storing these different types of files:

    nix
    sudo mkdir -p /exampleCA/rootCA/{certs,newcerts,crl,private,csr}
    echo 1000 | sudo tee /exampleCA/rootCA/serial
    echo 0100 | sudo tee /exampleCA/rootCA/crlnumber
    sudo touch /exampleCA/rootCA/index.txt
    sudo touch /exampleCA/openssl-root.cnf
    nix
    sudo mkdir -p /exampleCA/rootCA/{certs,newcerts,crl,private,csr}
    echo 1000 | sudo tee /exampleCA/rootCA/serial
    echo 0100 | sudo tee /exampleCA/rootCA/crlnumber
    sudo touch /exampleCA/rootCA/index.txt
    sudo touch /exampleCA/openssl-root.cnf
  3. As root, edit the file /exampleCA/openssl-root.cnf and add the following content, which defines the OpenSSL settings we need.

    Change the line authorityInfoAccess = OCSP;URI:http://192.168.56.39:8888 to use your OCSP Responder server’s IP address. This will be embedded into every TLS server certificate as a call address for making OCSP queries.

    openssl-root.cnf
    text
    [ ca ] # The default CA section
    default_ca = CA_default # The default CA name
    [ CA_default ] # Default settings for the CA
    dir = /exampleCA/rootCA # CA directory
    certs = $dir/certs # Certificates directory
    crl_dir = $dir/crl # CRL directory
    new_certs_dir = $dir/newcerts # New certificates directory
    database = $dir/index.txt # Certificate index file
    serial = $dir/serial # Serial number file
    RANDFILE = $dir/private/.rand # Random number file
    private_key = $dir/private/rootCA.key # Root CA private key
    certificate = $dir/certs/rootCA.crt # Root CA certificate
    crl = $dir/crl/crl.pem # Root CA CRL
    crlnumber = $dir/crlnumber # Root CA CRL number
    crl_extensions = crl_ext # CRL extensions
    default_crl_days = 30 # Default CRL validity days
    default_md = sha256 # Default message digest
    preserve = no # Preserve existing extensions
    email_in_dn = no # Exclude email from the DN
    name_opt = ca_default # Formatting options for names
    cert_opt = ca_default # Certificate output options
    policy = policy_strict # Certificate policy
    unique_subject = no # Allow multiple certs with the same DN
    [ policy_strict ] # Policy for stricter validation
    countryName = match # Must match the issuer's country
    stateOrProvinceName = match # Must match the issuer's state
    organizationName = match # Must match the issuer's organization
    organizationalUnitName = optional # Organizational unit is optional
    commonName = supplied # Must provide a common name
    emailAddress = optional # Email address is optional
    [ req ] # Request settings
    default_bits = 2048 # Default key size
    distinguished_name = req_distinguished_name # Default DN template
    string_mask = utf8only # UTF-8 encoding
    default_md = sha256 # Default message digest
    prompt = no # Non-interactive mode
    [ req_distinguished_name ] # Template for the DN in the CSR
    countryName = Country Name (2 letter code)
    stateOrProvinceName = State or Province Name (full name)
    localityName = Locality Name (city)
    0.organizationName = Organization Name (company)
    organizationalUnitName = Organizational Unit Name (section)
    commonName = Common Name (your domain)
    emailAddress = Email Address
    [ v3_ca ] # Root CA certificate extensions
    subjectKeyIdentifier = hash # Subject key identifier
    authorityKeyIdentifier = keyid:always,issuer # Authority key identifier
    basicConstraints = critical, CA:true # Basic constraints for a CA
    keyUsage = critical, keyCertSign, cRLSign # Key usage for a CA
    [ crl_ext ] # CRL extensions
    authorityKeyIdentifier = keyid:always,issuer # Authority key identifier
    [ v3_intermediate_ca ]
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid:always,issuer
    basicConstraints = critical, CA:true, pathlen:0
    keyUsage = critical, digitalSignature, cRLSign, keyCertSign
    [ v3_OCSP ]
    basicConstraints = CA:FALSE
    keyUsage = nonRepudiation, digitalSignature, keyEncipherment
    extendedKeyUsage = OCSPSigning
    [ server_cert ]
    basicConstraints = CA:false
    nsCertType = server
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid,issuer:always
    keyUsage = critical, digitalSignature, keyEncipherment
    extendedKeyUsage = serverAuth
    authorityInfoAccess = OCSP;URI:http://192.168.56.39:8888
    openssl-root.cnf
    text
    [ ca ] # The default CA section
    default_ca = CA_default # The default CA name
    [ CA_default ] # Default settings for the CA
    dir = /exampleCA/rootCA # CA directory
    certs = $dir/certs # Certificates directory
    crl_dir = $dir/crl # CRL directory
    new_certs_dir = $dir/newcerts # New certificates directory
    database = $dir/index.txt # Certificate index file
    serial = $dir/serial # Serial number file
    RANDFILE = $dir/private/.rand # Random number file
    private_key = $dir/private/rootCA.key # Root CA private key
    certificate = $dir/certs/rootCA.crt # Root CA certificate
    crl = $dir/crl/crl.pem # Root CA CRL
    crlnumber = $dir/crlnumber # Root CA CRL number
    crl_extensions = crl_ext # CRL extensions
    default_crl_days = 30 # Default CRL validity days
    default_md = sha256 # Default message digest
    preserve = no # Preserve existing extensions
    email_in_dn = no # Exclude email from the DN
    name_opt = ca_default # Formatting options for names
    cert_opt = ca_default # Certificate output options
    policy = policy_strict # Certificate policy
    unique_subject = no # Allow multiple certs with the same DN
    [ policy_strict ] # Policy for stricter validation
    countryName = match # Must match the issuer's country
    stateOrProvinceName = match # Must match the issuer's state
    organizationName = match # Must match the issuer's organization
    organizationalUnitName = optional # Organizational unit is optional
    commonName = supplied # Must provide a common name
    emailAddress = optional # Email address is optional
    [ req ] # Request settings
    default_bits = 2048 # Default key size
    distinguished_name = req_distinguished_name # Default DN template
    string_mask = utf8only # UTF-8 encoding
    default_md = sha256 # Default message digest
    prompt = no # Non-interactive mode
    [ req_distinguished_name ] # Template for the DN in the CSR
    countryName = Country Name (2 letter code)
    stateOrProvinceName = State or Province Name (full name)
    localityName = Locality Name (city)
    0.organizationName = Organization Name (company)
    organizationalUnitName = Organizational Unit Name (section)
    commonName = Common Name (your domain)
    emailAddress = Email Address
    [ v3_ca ] # Root CA certificate extensions
    subjectKeyIdentifier = hash # Subject key identifier
    authorityKeyIdentifier = keyid:always,issuer # Authority key identifier
    basicConstraints = critical, CA:true # Basic constraints for a CA
    keyUsage = critical, keyCertSign, cRLSign # Key usage for a CA
    [ crl_ext ] # CRL extensions
    authorityKeyIdentifier = keyid:always,issuer # Authority key identifier
    [ v3_intermediate_ca ]
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid:always,issuer
    basicConstraints = critical, CA:true, pathlen:0
    keyUsage = critical, digitalSignature, cRLSign, keyCertSign
    [ v3_OCSP ]
    basicConstraints = CA:FALSE
    keyUsage = nonRepudiation, digitalSignature, keyEncipherment
    extendedKeyUsage = OCSPSigning
    [ server_cert ]
    basicConstraints = CA:false
    nsCertType = server
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid,issuer:always
    keyUsage = critical, digitalSignature, keyEncipherment
    extendedKeyUsage = serverAuth
    authorityInfoAccess = OCSP;URI:http://192.168.56.39:8888
  4. Generate a root certificate and private key for the CA:

    nix
    sudo openssl genrsa -out /exampleCA/rootCA/private/rootCA.key 4096
    sudo openssl req \
    -config /exampleCA/openssl-root.cnf \
    -extensions v3_ca \
    -new \
    -x509 \
    -days 7300 \
    -sha256 \
    -subj "/C=US/ST=Ohio/L=Columbus/O=Example Corp/OU=IT Department/CN=Root CA" \
    -key /exampleCA/rootCA/private/rootCA.key \
    -out /exampleCA/rootCA/certs/rootCA.crt
    nix
    sudo openssl genrsa -out /exampleCA/rootCA/private/rootCA.key 4096
    sudo openssl req \
    -config /exampleCA/openssl-root.cnf \
    -extensions v3_ca \
    -new \
    -x509 \
    -days 7300 \
    -sha256 \
    -subj "/C=US/ST=Ohio/L=Columbus/O=Example Corp/OU=IT Department/CN=Root CA" \
    -key /exampleCA/rootCA/private/rootCA.key \
    -out /exampleCA/rootCA/certs/rootCA.crt
  5. Add this root certificate to the server’s list of CA certificates so that it becomes trusted.

    nix
    sudo mkdir /usr/local/share/ca-certificates/extra
    sudo cp /exampleCA/rootCA/certs/rootCA.crt /usr/local/share/ca-certificates/extra/
    sudo update-ca-certificates
    nix
    sudo mkdir /usr/local/share/ca-certificates/extra
    sudo cp /exampleCA/rootCA/certs/rootCA.crt /usr/local/share/ca-certificates/extra/
    sudo update-ca-certificates
    output
    text
    Updating certificates in /etc/ssl/certs...
    1 added, 0 removed; done.
    Running hooks in /etc/ca-certificates/update.d...
    done.
    output
    text
    Updating certificates in /etc/ssl/certs...
    1 added, 0 removed; done.
    Running hooks in /etc/ca-certificates/update.d...
    done.
  6. Create a private key and a CSR that you’ll use to sign OCSP responses. This will prompt you to enter a passphrase.

    nix
    sudo openssl req \
    -config /exampleCA/openssl-root.cnf \
    -new \
    -sha256 \
    -subj "/C=US/ST=Ohio/L=Columbus/O=Example Corp/OU=IT Department/CN=ocsp.example.com" \
    -keyout /exampleCA/rootCA/private/ocsp.example.com.key \
    -out /exampleCA/rootCA/csr/ocsp.example.com.csr
    nix
    sudo openssl req \
    -config /exampleCA/openssl-root.cnf \
    -new \
    -sha256 \
    -subj "/C=US/ST=Ohio/L=Columbus/O=Example Corp/OU=IT Department/CN=ocsp.example.com" \
    -keyout /exampleCA/rootCA/private/ocsp.example.com.key \
    -out /exampleCA/rootCA/csr/ocsp.example.com.csr
  7. Generate a certificate named ocsp.example.com.crt from the CSR. This will prompt you to sign the certificate and commit it to the certificates database.

    nix
    sudo openssl ca \
    -config /exampleCA/openssl-root.cnf \
    -extensions v3_OCSP \
    -days 375 \
    -notext \
    -md sha256 \
    -in /exampleCA/rootCA/csr/ocsp.example.com.csr \
    -out /exampleCA/rootCA/certs/ocsp.example.com.crt
    nix
    sudo openssl ca \
    -config /exampleCA/openssl-root.cnf \
    -extensions v3_OCSP \
    -days 375 \
    -notext \
    -md sha256 \
    -in /exampleCA/rootCA/csr/ocsp.example.com.csr \
    -out /exampleCA/rootCA/certs/ocsp.example.com.crt
    output
    text
    Sign the certificate? [y/n]:y
    1 out of 1 certificate requests certified, commit? [y/n]y
    Write out database with 1 new entries
    Database updated
    output
    text
    Sign the certificate? [y/n]:y
    1 out of 1 certificate requests certified, commit? [y/n]y
    Write out database with 1 new entries
    Database updated
  8. Start the OCSP server. This will prompt you to enter your passphrase.

    nix
    sudo openssl ocsp \
    -port 8888 \
    -index /exampleCA/rootCA/index.txt \
    -rsigner /exampleCA/rootCA/certs/ocsp.example.com.crt \
    -rkey /exampleCA/rootCA/private/ocsp.example.com.key \
    -CA /exampleCA/rootCA/certs/rootCA.crt \
    -text \
    -nmin 60
    nix
    sudo openssl ocsp \
    -port 8888 \
    -index /exampleCA/rootCA/index.txt \
    -rsigner /exampleCA/rootCA/certs/ocsp.example.com.crt \
    -rkey /exampleCA/rootCA/private/ocsp.example.com.key \
    -CA /exampleCA/rootCA/certs/rootCA.crt \
    -text \
    -nmin 60
    output
    text
    ACCEPT 0.0.0.0:8888 PID=3241
    Enter pass phrase for /exampleCA/rootCA/private/ocsp.example.com.key:
    ocsp: waiting for OCSP client connections...
    output
    text
    ACCEPT 0.0.0.0:8888 PID=3241
    Enter pass phrase for /exampleCA/rootCA/private/ocsp.example.com.key:
    ocsp: waiting for OCSP client connections...
  9. In another terminal window, create a TLS certificate named www.example.com.crt for your load balancer. This will prompt you to sign the certificate and commit it to the certificates database.

    nix
    sudo openssl req \
    -config /exampleCA/openssl-root.cnf \
    -newkey rsa:2048 \
    -nodes \
    -subj "/C=US/ST=Ohio/L=Columbus/O=Example Corp/OU=IT Department/CN=www.example.com" \
    -keyout /exampleCA/rootCA/private/www.example.com.key \
    -out /exampleCA/rootCA/csr/www.example.com.csr
    sudo openssl ca \
    -config /exampleCA/openssl-root.cnf \
    -extensions server_cert \
    -days 3650 \
    -notext \
    -md sha256 \
    -in /exampleCA/rootCA/csr/www.example.com.csr \
    -out /exampleCA/rootCA/certs/www.example.com.crt
    nix
    sudo openssl req \
    -config /exampleCA/openssl-root.cnf \
    -newkey rsa:2048 \
    -nodes \
    -subj "/C=US/ST=Ohio/L=Columbus/O=Example Corp/OU=IT Department/CN=www.example.com" \
    -keyout /exampleCA/rootCA/private/www.example.com.key \
    -out /exampleCA/rootCA/csr/www.example.com.csr
    sudo openssl ca \
    -config /exampleCA/openssl-root.cnf \
    -extensions server_cert \
    -days 3650 \
    -notext \
    -md sha256 \
    -in /exampleCA/rootCA/csr/www.example.com.csr \
    -out /exampleCA/rootCA/certs/www.example.com.crt
    output
    text
    Sign the certificate? [y/n]:y
    1 out of 1 certificate requests certified, commit? [y/n]y
    Write out database with 1 new entries
    Database updated
    output
    text
    Sign the certificate? [y/n]:y
    1 out of 1 certificate requests certified, commit? [y/n]y
    Write out database with 1 new entries
    Database updated
  10. At this point, you can query the OCSP Responder server at its listening IP address using this certificate. It should return a good status.

    nix
    openssl ocsp \
    -issuer /exampleCA/rootCA/certs/rootCA.crt \
    -cert /exampleCA/rootCA/certs/www.example.com.crt \
    -url http://192.168.56.39:8888 \
    -resp_text
    nix
    openssl ocsp \
    -issuer /exampleCA/rootCA/certs/rootCA.crt \
    -cert /exampleCA/rootCA/certs/www.example.com.crt \
    -url http://192.168.56.39:8888 \
    -resp_text
    output
    text
    OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
    Version: 1 (0x0)
    Responder Id: C = US, ST = Ohio, O = Example Corp, OU = IT Department, CN = ocsp.example.com
    Produced At: Dec 17 15:07:20 2024 GMT
    Responses:
    Certificate ID:
    Hash Algorithm: sha1
    Issuer Name Hash: FB1F13EE9B62FF5CE28500BCCB28584007D61524
    Issuer Key Hash: 200DF0756FA74CAFB9421A42A6C1C965532FC369
    Serial Number: 1001
    Cert Status: good
    This Update: Dec 17 15:07:20 2024 GMT
    Next Update: Dec 17 15:12:20 2024 GMT
    output
    text
    OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
    Version: 1 (0x0)
    Responder Id: C = US, ST = Ohio, O = Example Corp, OU = IT Department, CN = ocsp.example.com
    Produced At: Dec 17 15:07:20 2024 GMT
    Responses:
    Certificate ID:
    Hash Algorithm: sha1
    Issuer Name Hash: FB1F13EE9B62FF5CE28500BCCB28584007D61524
    Issuer Key Hash: 200DF0756FA74CAFB9421A42A6C1C965532FC369
    Serial Number: 1001
    Cert Status: good
    This Update: Dec 17 15:07:20 2024 GMT
    Next Update: Dec 17 15:12:20 2024 GMT
  11. Copy the contents of the www.example.com.crt certificate, the www.example.com.key private key, and the CA root certificate into a single PEM file to be used on your QA load balancer.

    nix
    sudo cat /exampleCA/rootCA/certs/www.example.com.crt > ~/www.example.com.pem
    sudo cat /exampleCA/rootCA/private/www.example.com.key >> ~/www.example.com.pem
    sudo cat /exampleCA/rootCA/certs/rootCA.crt >> ~/www.example.com.pem
    nix
    sudo cat /exampleCA/rootCA/certs/www.example.com.crt > ~/www.example.com.pem
    sudo cat /exampleCA/rootCA/private/www.example.com.key >> ~/www.example.com.pem
    sudo cat /exampleCA/rootCA/certs/rootCA.crt >> ~/www.example.com.pem
  12. Copy these files to your home directory on your QA load balancer:

    • ~/www.example.com.pem
    • /exampleCA/rootCA/certs/rootCA.crt
  13. On your QA load balancer, add the root certificate to the server’s list of CA certificates so that it becomes trusted.

    nix
    sudo mkdir /usr/local/share/ca-certificates/extra
    sudo cp ~/rootCA.crt /usr/local/share/ca-certificates/extra/
    sudo update-ca-certificates
    nix
    sudo mkdir /usr/local/share/ca-certificates/extra
    sudo cp ~/rootCA.crt /usr/local/share/ca-certificates/extra/
    sudo update-ca-certificates
    output
    text
    Updating certificates in /etc/ssl/certs...
    1 added, 0 removed; done.
    Running hooks in /etc/ca-certificates/update.d...
    done.
    output
    text
    Updating certificates in /etc/ssl/certs...
    1 added, 0 removed; done.
    Running hooks in /etc/ca-certificates/update.d...
    done.
  14. Copy the www.example.com.pem file to your certs directory. For example:

    nix
    sudo mkdir -p /etc/haproxy/certs
    sudo cp ~/www.example.com.pem /etc/haproxy/certs/
    nix
    sudo mkdir -p /etc/haproxy/certs
    sudo cp ~/www.example.com.pem /etc/haproxy/certs/
    nix
    sudo mkdir -p /etc/hapee-3.0/certs
    sudo cp ~/www.example.com.pem /etc/hapee-3.0/certs/
    nix
    sudo mkdir -p /etc/hapee-3.0/certs
    sudo cp ~/www.example.com.pem /etc/hapee-3.0/certs/
  15. Update your crt-list file to use this certificate and enable OCSP stapling. Save this to the certs directory as crt-list.txt.

    crt-list.txt
    text
    /etc/haproxy/certs/www.example.com.pem [ocsp-update on]
    crt-list.txt
    text
    /etc/haproxy/certs/www.example.com.pem [ocsp-update on]
    crt-list.txt
    text
    /etc/hapee-3.0/certs/www.example.com.pem [ocsp-update on]
    crt-list.txt
    text
    /etc/hapee-3.0/certs/www.example.com.pem [ocsp-update on]
  16. Update your frontend to use the crt-list.

    haproxy
    frontend www
    bind :443 ssl crt-list /etc/haproxy/certs/crt-list.txt
    default_backend webservers
    haproxy
    frontend www
    bind :443 ssl crt-list /etc/haproxy/certs/crt-list.txt
    default_backend webservers
    haproxy
    frontend www
    bind :443 ssl crt-list /etc/hapee-3.0/certs/crt-list.txt
    default_backend webservers
    haproxy
    frontend www
    bind :443 ssl crt-list /etc/hapee-3.0/certs/crt-list.txt
    default_backend webservers
  17. Reload the load balancer configuration.

    nix
    sudo systemctl reload haproxy
    nix
    sudo systemctl reload haproxy
    nix
    sudo systemctl reload hapee-3.0-lb
    nix
    sudo systemctl reload hapee-3.0-lb
  18. At this point, your load balancer logs should show that the OCSP updates are completing successfully.

    Check the log file /var/log/haproxy.log for OCSP update messages.

    haproxy.log
    text
    <OCSP-UPDATE> /etc/haproxy/certs/www.example.com.pem 1 "Update successful" 0 1
    haproxy.log
    text
    <OCSP-UPDATE> /etc/haproxy/certs/www.example.com.pem 1 "Update successful" 0 1

    Check the lb-access-<DATE>.log log file under /var/log/hapee-3.0/ for OCSP update messages.

    lb-access-20250103.log
    text
    <OCSP-UPDATE> /etc/hapee-3.0/certs/www.example.com.pem 1 "Update successful" 0 1
    lb-access-20250103.log
    text
    <OCSP-UPDATE> /etc/hapee-3.0/certs/www.example.com.pem 1 "Update successful" 0 1
  19. To map the domain www.example.com to your load balancer’s IP address, edit the server’s /etc/hosts file:

    hosts
    text
    127.0.0.1 www.example.com
    hosts
    text
    127.0.0.1 www.example.com
  20. Test that the load balancer is stapling the OCSP response. The output should show OCSP Response Data.

    nix
    openssl s_client -connect www.example.com:443 -servername www.example.com -status </dev/null
    nix
    openssl s_client -connect www.example.com:443 -servername www.example.com -status </dev/null
    output
    text
    CONNECTED(00000003)
    depth=1 C = US, ST = Ohio, L = Columbus, O = Example Corp, OU = IT Department, CN = Root CA
    verify error:num=19:self-signed certificate in certificate chain
    verify return:1
    depth=1 C = US, ST = Ohio, L = Columbus, O = Example Corp, OU = IT Department, CN = Root CA
    verify return:1
    depth=0 C = US, ST = Ohio, O = Example Corp, OU = IT Department, CN = www.example.com
    verify return:1
    OCSP response:
    ======================================
    OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
    Version: 1 (0x0)
    Responder Id: C = US, ST = Ohio, O = Example Corp, OU = IT Department, CN = ocsp.example.com
    Produced At: Dec 18 15:37:31 2024 GMT
    Responses:
    Certificate ID:
    Hash Algorithm: sha1
    Issuer Name Hash: FB1F13EE9B62FF5CE28500BCCB28584007D61524
    Issuer Key Hash: 200DF0756FA74CAFB9421A42A6C1C965532FC369
    Serial Number: 1001
    Cert Status: good
    This Update: Dec 18 15:37:31 2024 GMT
    Next Update: Dec 18 16:37:31 2024 GMT
    output
    text
    CONNECTED(00000003)
    depth=1 C = US, ST = Ohio, L = Columbus, O = Example Corp, OU = IT Department, CN = Root CA
    verify error:num=19:self-signed certificate in certificate chain
    verify return:1
    depth=1 C = US, ST = Ohio, L = Columbus, O = Example Corp, OU = IT Department, CN = Root CA
    verify return:1
    depth=0 C = US, ST = Ohio, O = Example Corp, OU = IT Department, CN = www.example.com
    verify return:1
    OCSP response:
    ======================================
    OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
    Version: 1 (0x0)
    Responder Id: C = US, ST = Ohio, O = Example Corp, OU = IT Department, CN = ocsp.example.com
    Produced At: Dec 18 15:37:31 2024 GMT
    Responses:
    Certificate ID:
    Hash Algorithm: sha1
    Issuer Name Hash: FB1F13EE9B62FF5CE28500BCCB28584007D61524
    Issuer Key Hash: 200DF0756FA74CAFB9421A42A6C1C965532FC369
    Serial Number: 1001
    Cert Status: good
    This Update: Dec 18 15:37:31 2024 GMT
    Next Update: Dec 18 16:37:31 2024 GMT

See also Jump to heading

Do you have any suggestions on how we can improve the content of this page?