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:
-
Verify that your server TLS certificate contains an OCSP URI by using the
openssl x509
command with-ocsp_uri
argument:nixopenssl x509 -in ./mysite.pem -noout -ocsp_urinixopenssl x509 -in ./mysite.pem -noout -ocsp_urioutputtexthttp://ocsp.issuer.comoutputtexthttp://ocsp.issuer.com -
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
.
-
-
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:
-
Set the
ocsp-update.mode
global directive toon
.haproxyglobalocsp-update.mode onhaproxyglobalocsp-update.mode on -
Optional: Set the global configuration parameters
ocsp-update.maxdelay
andocsp-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 forocsp-update.maxdelay
.haproxyglobalocsp-update.mode onocsp-update.mindelay 300ocsp-update.maxdelay 3600haproxyglobalocsp-update.mode onocsp-update.mindelay 300ocsp-update.maxdelay 3600 -
Reload the load balancer configuration.
nixsudo systemctl reload haproxynixsudo systemctl reload haproxynixsudo systemctl reload hapee-3.0-lbnixsudo 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.
-
Using the text editor of your choice, create the
crt-list
file. In this example, we will create a file namedcrt-list.txt
. For this example, we will specify one certificate.In the example
crt-list
file below, ourPEM
file is located in thecerts
directory. We are specifying our ALPN options here as well,alpn h2
, and enabling OCSP withocsp-update on
. Note that theocsp-update on
argument can be included only in acrt-list
. It cannot be added to abind
line.crt-list.txtnix/etc/haproxy/certs/mysite.pem [alpn h2 ocsp-update on]crt-list.txtnix/etc/haproxy/certs/mysite.pem [alpn h2 ocsp-update on]crt-list.txtnix/etc/hapee-3.0/certs/mysite.pem [alpn h2 ocsp-update on]crt-list.txtnix/etc/hapee-3.0/certs/mysite.pem [alpn h2 ocsp-update on] -
Add a
bind
line to yourfrontend
that specifies the path to thecrt-list
. The load balancer will load the certificates according to the options specified in thecrt-list
.haproxyfrontend wwwbind :443 ssl crt-list /etc/haproxy/certs/crt-list.txtdefault_backend webservershaproxyfrontend wwwbind :443 ssl crt-list /etc/haproxy/certs/crt-list.txtdefault_backend webservershaproxyfrontend wwwbind :443 ssl crt-list /etc/hapee-3.0/certs/crt-list.txtdefault_backend webservershaproxyfrontend wwwbind :443 ssl crt-list /etc/hapee-3.0/certs/crt-list.txtdefault_backend webservers -
Optional: Set the global configuration parameters
ocsp-update.maxdelay
andocsp-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 forocsp-update.maxdelay
.Name of directive changed
Prior to HAProxy 3.0, the
ocsp-update
directives were namedtune.ssl.ocsp-update
.haproxyglobalocsp-update.mindelay 300ocsp-update.maxdelay 3600haproxyglobalocsp-update.mindelay 300ocsp-update.maxdelay 3600 -
Reload the load balancer configuration.
nixsudo systemctl reload haproxynixsudo systemctl reload haproxynixsudo systemctl reload hapee-3.0-lbnixsudo 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
:
-
Define a
crt-store
in your configuration section.haproxycrt-store webcrt-base /etc/haproxy/certs/load crt mysite.pem ocsp-update onhaproxycrt-store webcrt-base /etc/haproxy/certs/load crt mysite.pem ocsp-update onhaproxycrt-store webcrt-base /etc/hapee-3.0/certs/load crt mysite.pem ocsp-update onhaproxycrt-store webcrt-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
toon
to enable OCSP stapling for your certificate.
- Specify a location for
-
Reference the certificate files by their name and the name of the
crt-store
, in this case@web/mysite.pem
, in your frontend:haproxyfrontend wwwbind :443 ssl crt "@web/mysite.pem"default_backend webservershaproxyfrontend wwwbind :443 ssl crt "@web/mysite.pem"default_backend webservers -
Optional: Set the global configuration parameters
ocsp-update.maxdelay
andocsp-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 forocsp-update.maxdelay
.Name of directive changed
Prior to HAProxy 3.0, the
ocsp-update
directives were namedtune.ssl.ocsp-update
.haproxyglobalocsp-update.mindelay 300ocsp-update.maxdelay 3600haproxyglobalocsp-update.mindelay 300ocsp-update.maxdelay 3600 -
Reload the load balancer configuration.
nixsudo systemctl reload haproxynixsudo systemctl reload haproxynixsudo systemctl reload hapee-3.0-lbnixsudo 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.
-
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:nixopenssl ocsp \-issuer issuer.pem \-cert mysite.pem \-url http://ocsp.issuer.com \-host ocsp.issuer.com:80 \-respout mysite.ocspnixopenssl ocsp \-issuer issuer.pem \-cert mysite.pem \-url http://ocsp.issuer.com \-host ocsp.issuer.com:80 \-respout mysite.ocsp
-
-
Add an
ocsp
argument to indicate the file to load.-
If using
crt-list
, add anocsp
argument for each certificate:crt-list.txtnix/etc/hapee-3.0/certs/mysite.pem [alpn h2 ocsp-update on ocsp /etc/hapee-3.0/certs/mysite.ocsp]crt-list.txtnix/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 anocsp
argument to theload
directive:haproxycrt-store webcrt-base /etc/hapee-3.0/certs/load crt mysite.pem ocsp-update on ocsp mysite.ocsphaproxycrt-store webcrt-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
globalocsp-update.httpproxy 192.168.0.10:8000
haproxy
globalocsp-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:
-
We rely on the
openssl
command-line utility. To check that it’s installed, run:nixopenssl versionnixopenssl versionoutputtextOpenSSL 3.0.11 19 Sep 2023 (Library: OpenSSL 3.0.11 19 Sep 2023)outputtextOpenSSL 3.0.11 19 Sep 2023 (Library: OpenSSL 3.0.11 19 Sep 2023) -
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:
nixsudo mkdir -p /exampleCA/rootCA/{certs,newcerts,crl,private,csr}echo 1000 | sudo tee /exampleCA/rootCA/serialecho 0100 | sudo tee /exampleCA/rootCA/crlnumbersudo touch /exampleCA/rootCA/index.txtsudo touch /exampleCA/openssl-root.cnfnixsudo mkdir -p /exampleCA/rootCA/{certs,newcerts,crl,private,csr}echo 1000 | sudo tee /exampleCA/rootCA/serialecho 0100 | sudo tee /exampleCA/rootCA/crlnumbersudo touch /exampleCA/rootCA/index.txtsudo touch /exampleCA/openssl-root.cnf -
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.cnftext[ ca ] # The default CA sectiondefault_ca = CA_default # The default CA name[ CA_default ] # Default settings for the CAdir = /exampleCA/rootCA # CA directorycerts = $dir/certs # Certificates directorycrl_dir = $dir/crl # CRL directorynew_certs_dir = $dir/newcerts # New certificates directorydatabase = $dir/index.txt # Certificate index fileserial = $dir/serial # Serial number fileRANDFILE = $dir/private/.rand # Random number fileprivate_key = $dir/private/rootCA.key # Root CA private keycertificate = $dir/certs/rootCA.crt # Root CA certificatecrl = $dir/crl/crl.pem # Root CA CRLcrlnumber = $dir/crlnumber # Root CA CRL numbercrl_extensions = crl_ext # CRL extensionsdefault_crl_days = 30 # Default CRL validity daysdefault_md = sha256 # Default message digestpreserve = no # Preserve existing extensionsemail_in_dn = no # Exclude email from the DNname_opt = ca_default # Formatting options for namescert_opt = ca_default # Certificate output optionspolicy = policy_strict # Certificate policyunique_subject = no # Allow multiple certs with the same DN[ policy_strict ] # Policy for stricter validationcountryName = match # Must match the issuer's countrystateOrProvinceName = match # Must match the issuer's stateorganizationName = match # Must match the issuer's organizationorganizationalUnitName = optional # Organizational unit is optionalcommonName = supplied # Must provide a common nameemailAddress = optional # Email address is optional[ req ] # Request settingsdefault_bits = 2048 # Default key sizedistinguished_name = req_distinguished_name # Default DN templatestring_mask = utf8only # UTF-8 encodingdefault_md = sha256 # Default message digestprompt = no # Non-interactive mode[ req_distinguished_name ] # Template for the DN in the CSRcountryName = 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 extensionssubjectKeyIdentifier = hash # Subject key identifierauthorityKeyIdentifier = keyid:always,issuer # Authority key identifierbasicConstraints = critical, CA:true # Basic constraints for a CAkeyUsage = critical, keyCertSign, cRLSign # Key usage for a CA[ crl_ext ] # CRL extensionsauthorityKeyIdentifier = keyid:always,issuer # Authority key identifier[ v3_intermediate_ca ]subjectKeyIdentifier = hashauthorityKeyIdentifier = keyid:always,issuerbasicConstraints = critical, CA:true, pathlen:0keyUsage = critical, digitalSignature, cRLSign, keyCertSign[ v3_OCSP ]basicConstraints = CA:FALSEkeyUsage = nonRepudiation, digitalSignature, keyEnciphermentextendedKeyUsage = OCSPSigning[ server_cert ]basicConstraints = CA:falsensCertType = serversubjectKeyIdentifier = hashauthorityKeyIdentifier = keyid,issuer:alwayskeyUsage = critical, digitalSignature, keyEnciphermentextendedKeyUsage = serverAuthauthorityInfoAccess = OCSP;URI:http://192.168.56.39:8888openssl-root.cnftext[ ca ] # The default CA sectiondefault_ca = CA_default # The default CA name[ CA_default ] # Default settings for the CAdir = /exampleCA/rootCA # CA directorycerts = $dir/certs # Certificates directorycrl_dir = $dir/crl # CRL directorynew_certs_dir = $dir/newcerts # New certificates directorydatabase = $dir/index.txt # Certificate index fileserial = $dir/serial # Serial number fileRANDFILE = $dir/private/.rand # Random number fileprivate_key = $dir/private/rootCA.key # Root CA private keycertificate = $dir/certs/rootCA.crt # Root CA certificatecrl = $dir/crl/crl.pem # Root CA CRLcrlnumber = $dir/crlnumber # Root CA CRL numbercrl_extensions = crl_ext # CRL extensionsdefault_crl_days = 30 # Default CRL validity daysdefault_md = sha256 # Default message digestpreserve = no # Preserve existing extensionsemail_in_dn = no # Exclude email from the DNname_opt = ca_default # Formatting options for namescert_opt = ca_default # Certificate output optionspolicy = policy_strict # Certificate policyunique_subject = no # Allow multiple certs with the same DN[ policy_strict ] # Policy for stricter validationcountryName = match # Must match the issuer's countrystateOrProvinceName = match # Must match the issuer's stateorganizationName = match # Must match the issuer's organizationorganizationalUnitName = optional # Organizational unit is optionalcommonName = supplied # Must provide a common nameemailAddress = optional # Email address is optional[ req ] # Request settingsdefault_bits = 2048 # Default key sizedistinguished_name = req_distinguished_name # Default DN templatestring_mask = utf8only # UTF-8 encodingdefault_md = sha256 # Default message digestprompt = no # Non-interactive mode[ req_distinguished_name ] # Template for the DN in the CSRcountryName = 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 extensionssubjectKeyIdentifier = hash # Subject key identifierauthorityKeyIdentifier = keyid:always,issuer # Authority key identifierbasicConstraints = critical, CA:true # Basic constraints for a CAkeyUsage = critical, keyCertSign, cRLSign # Key usage for a CA[ crl_ext ] # CRL extensionsauthorityKeyIdentifier = keyid:always,issuer # Authority key identifier[ v3_intermediate_ca ]subjectKeyIdentifier = hashauthorityKeyIdentifier = keyid:always,issuerbasicConstraints = critical, CA:true, pathlen:0keyUsage = critical, digitalSignature, cRLSign, keyCertSign[ v3_OCSP ]basicConstraints = CA:FALSEkeyUsage = nonRepudiation, digitalSignature, keyEnciphermentextendedKeyUsage = OCSPSigning[ server_cert ]basicConstraints = CA:falsensCertType = serversubjectKeyIdentifier = hashauthorityKeyIdentifier = keyid,issuer:alwayskeyUsage = critical, digitalSignature, keyEnciphermentextendedKeyUsage = serverAuthauthorityInfoAccess = OCSP;URI:http://192.168.56.39:8888 -
Generate a root certificate and private key for the CA:
nixsudo openssl genrsa -out /exampleCA/rootCA/private/rootCA.key 4096sudo 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.crtnixsudo openssl genrsa -out /exampleCA/rootCA/private/rootCA.key 4096sudo 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 -
Add this root certificate to the server’s list of CA certificates so that it becomes trusted.
nixsudo mkdir /usr/local/share/ca-certificates/extrasudo cp /exampleCA/rootCA/certs/rootCA.crt /usr/local/share/ca-certificates/extra/sudo update-ca-certificatesnixsudo mkdir /usr/local/share/ca-certificates/extrasudo cp /exampleCA/rootCA/certs/rootCA.crt /usr/local/share/ca-certificates/extra/sudo update-ca-certificatesoutputtextUpdating certificates in /etc/ssl/certs...1 added, 0 removed; done.Running hooks in /etc/ca-certificates/update.d...done.outputtextUpdating certificates in /etc/ssl/certs...1 added, 0 removed; done.Running hooks in /etc/ca-certificates/update.d...done. -
Create a private key and a CSR that you’ll use to sign OCSP responses. This will prompt you to enter a passphrase.
nixsudo 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.csrnixsudo 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 -
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.nixsudo 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.crtnixsudo 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.crtoutputtextSign the certificate? [y/n]:y1 out of 1 certificate requests certified, commit? [y/n]yWrite out database with 1 new entriesDatabase updatedoutputtextSign the certificate? [y/n]:y1 out of 1 certificate requests certified, commit? [y/n]yWrite out database with 1 new entriesDatabase updated -
Start the OCSP server. This will prompt you to enter your passphrase.
nixsudo 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 60nixsudo 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 60outputtextACCEPT 0.0.0.0:8888 PID=3241Enter pass phrase for /exampleCA/rootCA/private/ocsp.example.com.key:ocsp: waiting for OCSP client connections...outputtextACCEPT 0.0.0.0:8888 PID=3241Enter pass phrase for /exampleCA/rootCA/private/ocsp.example.com.key:ocsp: waiting for OCSP client connections... -
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.nixsudo 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.csrsudo 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.crtnixsudo 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.csrsudo 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.crtoutputtextSign the certificate? [y/n]:y1 out of 1 certificate requests certified, commit? [y/n]yWrite out database with 1 new entriesDatabase updatedoutputtextSign the certificate? [y/n]:y1 out of 1 certificate requests certified, commit? [y/n]yWrite out database with 1 new entriesDatabase updated -
At this point, you can query the OCSP Responder server at its listening IP address using this certificate. It should return a good status.
nixopenssl ocsp \-issuer /exampleCA/rootCA/certs/rootCA.crt \-cert /exampleCA/rootCA/certs/www.example.com.crt \-url http://192.168.56.39:8888 \-resp_textnixopenssl ocsp \-issuer /exampleCA/rootCA/certs/rootCA.crt \-cert /exampleCA/rootCA/certs/www.example.com.crt \-url http://192.168.56.39:8888 \-resp_textoutputtextOCSP Response Data:OCSP Response Status: successful (0x0)Response Type: Basic OCSP ResponseVersion: 1 (0x0)Responder Id: C = US, ST = Ohio, O = Example Corp, OU = IT Department, CN = ocsp.example.comProduced At: Dec 17 15:07:20 2024 GMTResponses:Certificate ID:Hash Algorithm: sha1Issuer Name Hash: FB1F13EE9B62FF5CE28500BCCB28584007D61524Issuer Key Hash: 200DF0756FA74CAFB9421A42A6C1C965532FC369Serial Number: 1001Cert Status: goodThis Update: Dec 17 15:07:20 2024 GMTNext Update: Dec 17 15:12:20 2024 GMToutputtextOCSP Response Data:OCSP Response Status: successful (0x0)Response Type: Basic OCSP ResponseVersion: 1 (0x0)Responder Id: C = US, ST = Ohio, O = Example Corp, OU = IT Department, CN = ocsp.example.comProduced At: Dec 17 15:07:20 2024 GMTResponses:Certificate ID:Hash Algorithm: sha1Issuer Name Hash: FB1F13EE9B62FF5CE28500BCCB28584007D61524Issuer Key Hash: 200DF0756FA74CAFB9421A42A6C1C965532FC369Serial Number: 1001Cert Status: goodThis Update: Dec 17 15:07:20 2024 GMTNext Update: Dec 17 15:12:20 2024 GMT -
Copy the contents of the
www.example.com.crt
certificate, thewww.example.com.key
private key, and the CA root certificate into a single PEM file to be used on your QA load balancer.nixsudo cat /exampleCA/rootCA/certs/www.example.com.crt > ~/www.example.com.pemsudo cat /exampleCA/rootCA/private/www.example.com.key >> ~/www.example.com.pemsudo cat /exampleCA/rootCA/certs/rootCA.crt >> ~/www.example.com.pemnixsudo cat /exampleCA/rootCA/certs/www.example.com.crt > ~/www.example.com.pemsudo cat /exampleCA/rootCA/private/www.example.com.key >> ~/www.example.com.pemsudo cat /exampleCA/rootCA/certs/rootCA.crt >> ~/www.example.com.pem -
Copy these files to your home directory on your QA load balancer:
~/www.example.com.pem
/exampleCA/rootCA/certs/rootCA.crt
-
On your QA load balancer, add the root certificate to the server’s list of CA certificates so that it becomes trusted.
nixsudo mkdir /usr/local/share/ca-certificates/extrasudo cp ~/rootCA.crt /usr/local/share/ca-certificates/extra/sudo update-ca-certificatesnixsudo mkdir /usr/local/share/ca-certificates/extrasudo cp ~/rootCA.crt /usr/local/share/ca-certificates/extra/sudo update-ca-certificatesoutputtextUpdating certificates in /etc/ssl/certs...1 added, 0 removed; done.Running hooks in /etc/ca-certificates/update.d...done.outputtextUpdating certificates in /etc/ssl/certs...1 added, 0 removed; done.Running hooks in /etc/ca-certificates/update.d...done. -
Copy the
www.example.com.pem
file to yourcerts
directory. For example:nixsudo mkdir -p /etc/haproxy/certssudo cp ~/www.example.com.pem /etc/haproxy/certs/nixsudo mkdir -p /etc/haproxy/certssudo cp ~/www.example.com.pem /etc/haproxy/certs/nixsudo mkdir -p /etc/hapee-3.0/certssudo cp ~/www.example.com.pem /etc/hapee-3.0/certs/nixsudo mkdir -p /etc/hapee-3.0/certssudo cp ~/www.example.com.pem /etc/hapee-3.0/certs/ -
Update your
crt-list
file to use this certificate and enable OCSP stapling. Save this to thecerts
directory ascrt-list.txt
.crt-list.txttext/etc/haproxy/certs/www.example.com.pem [ocsp-update on]crt-list.txttext/etc/haproxy/certs/www.example.com.pem [ocsp-update on]crt-list.txttext/etc/hapee-3.0/certs/www.example.com.pem [ocsp-update on]crt-list.txttext/etc/hapee-3.0/certs/www.example.com.pem [ocsp-update on] -
Update your frontend to use the
crt-list
.haproxyfrontend wwwbind :443 ssl crt-list /etc/haproxy/certs/crt-list.txtdefault_backend webservershaproxyfrontend wwwbind :443 ssl crt-list /etc/haproxy/certs/crt-list.txtdefault_backend webservershaproxyfrontend wwwbind :443 ssl crt-list /etc/hapee-3.0/certs/crt-list.txtdefault_backend webservershaproxyfrontend wwwbind :443 ssl crt-list /etc/hapee-3.0/certs/crt-list.txtdefault_backend webservers -
Reload the load balancer configuration.
nixsudo systemctl reload haproxynixsudo systemctl reload haproxynixsudo systemctl reload hapee-3.0-lbnixsudo systemctl reload hapee-3.0-lb -
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.logtext<OCSP-UPDATE> /etc/haproxy/certs/www.example.com.pem 1 "Update successful" 0 1haproxy.logtext<OCSP-UPDATE> /etc/haproxy/certs/www.example.com.pem 1 "Update successful" 0 1Check the
lb-access-<DATE>.log
log file under/var/log/hapee-3.0/
for OCSP update messages.lb-access-20250103.logtext<OCSP-UPDATE> /etc/hapee-3.0/certs/www.example.com.pem 1 "Update successful" 0 1lb-access-20250103.logtext<OCSP-UPDATE> /etc/hapee-3.0/certs/www.example.com.pem 1 "Update successful" 0 1 -
To map the domain
www.example.com
to your load balancer’s IP address, edit the server’s/etc/hosts
file:hoststext127.0.0.1 www.example.comhoststext127.0.0.1 www.example.com -
Test that the load balancer is stapling the OCSP response. The output should show
OCSP Response Data
.nixopenssl s_client -connect www.example.com:443 -servername www.example.com -status </dev/nullnixopenssl s_client -connect www.example.com:443 -servername www.example.com -status </dev/nulloutputtextCONNECTED(00000003)depth=1 C = US, ST = Ohio, L = Columbus, O = Example Corp, OU = IT Department, CN = Root CAverify error:num=19:self-signed certificate in certificate chainverify return:1depth=1 C = US, ST = Ohio, L = Columbus, O = Example Corp, OU = IT Department, CN = Root CAverify return:1depth=0 C = US, ST = Ohio, O = Example Corp, OU = IT Department, CN = www.example.comverify return:1OCSP response:======================================OCSP Response Data:OCSP Response Status: successful (0x0)Response Type: Basic OCSP ResponseVersion: 1 (0x0)Responder Id: C = US, ST = Ohio, O = Example Corp, OU = IT Department, CN = ocsp.example.comProduced At: Dec 18 15:37:31 2024 GMTResponses:Certificate ID:Hash Algorithm: sha1Issuer Name Hash: FB1F13EE9B62FF5CE28500BCCB28584007D61524Issuer Key Hash: 200DF0756FA74CAFB9421A42A6C1C965532FC369Serial Number: 1001Cert Status: goodThis Update: Dec 18 15:37:31 2024 GMTNext Update: Dec 18 16:37:31 2024 GMToutputtextCONNECTED(00000003)depth=1 C = US, ST = Ohio, L = Columbus, O = Example Corp, OU = IT Department, CN = Root CAverify error:num=19:self-signed certificate in certificate chainverify return:1depth=1 C = US, ST = Ohio, L = Columbus, O = Example Corp, OU = IT Department, CN = Root CAverify return:1depth=0 C = US, ST = Ohio, O = Example Corp, OU = IT Department, CN = www.example.comverify return:1OCSP response:======================================OCSP Response Data:OCSP Response Status: successful (0x0)Response Type: Basic OCSP ResponseVersion: 1 (0x0)Responder Id: C = US, ST = Ohio, O = Example Corp, OU = IT Department, CN = ocsp.example.comProduced At: Dec 18 15:37:31 2024 GMTResponses:Certificate ID:Hash Algorithm: sha1Issuer Name Hash: FB1F13EE9B62FF5CE28500BCCB28584007D61524Issuer Key Hash: 200DF0756FA74CAFB9421A42A6C1C965532FC369Serial Number: 1001Cert Status: goodThis Update: Dec 18 15:37:31 2024 GMTNext 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?