Client Certificate Authentication
Client certificate authentication means that the client sends a certificate when they connect over TLS. The load balancer verifies the client's identity based on the certificate. Typically, client certificates are digitally signed with your organization's CA certificate. When a client presents one, you can verify whether it was indeed signed by your CA. If not, deny the request. You would give a unique certificate to each client to which you want to grant access.
Create a client certificate
In certain scenarios, servers may need to authenticate clients before allowing them access to sensitive resources or services. A client certificate is a type of digital certificate used by web servers to verify the identity of a user or device trying to access these resources.
-
Create the certificate signing request with the following command:
$ openssl req \ -newkey rsa:2048 \ -nodes \ -days 3650 \ -subj "/CN=commonName/O=Organization" \ -keyout clientKey.pem \ -out client.csr
-
Now use the following command to sign the certificate signing request; this uses our previously generated CSR
client.csr
, CA certificatecacert.crt
, and keyprivateCA.pem
to create a client certificate,client.crt
.$ openssl x509 \ -req \ -in client.csr \ -out client.crt \ -CA cacert.crt \ -CAkey privateCA.pem \ -CAcreateserial \ -days 3650
Successful confirmation output will look something like this, with an 'OK' statement above your Common Name and Organization:
Certificate request self-signature ok subject=CN = <YourCommonName>, O = <YourOrganization>
Your client certificate is now ready to be used.
Enable client certificate verification
Enable verification of client certificates by setting verify
to required on a bind
line. The ca-file
parameter specifies the CA file to use to verify:
frontend www
bind *:443 ssl crt /etc/hapee-2.0/certs/site.pem verify required ca-file /etc/hapee-2.0/certs/cacert.crt
Send a client certificate to servers
HAProxy Enterprise can also send its own client certificate to backend servers. The servers would then be responsible for verifying it. The crt
parameter points to your client certificate file:
backend webservers
server web1 10.0.0.5:443 ssl verify required ca-file /etc/hapee-2.0/certs/cacert.crt crt /etc/hapee-2.0/certs/client.crt
Generate Certificate Revocation List (CRL)
A Certificate Revocation List (CRL) contains a list of the certificates that have been revoked.
-
Create the directory structure and necessary files. You can choose different directory paths however ensure all created files are in the proper locations:
$ mkdir ./databaseCA $ cd ./databaseCA $ mkdir certs private crl $ touch index.txt serial crlnumber $ echo 01 > serial $ echo 1000 > crlnumber
-
Next, you'll need a configuration file for OpenSSL. This file is often named
openssl.cnf
and can be found in the directories/usr/lib/ssl/
or/etc/ssl/
. Below is a example snippet from the file:# OpenSSL example configuration file. # See doc/man5/config.pod for more info. #################################################################### [ ca ] default_ca = CA_default # The default ca section #################################################################### [ CA_default ] dir = ./databaseCA # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crl # Where the issued crl are kept database = $dir/index.txt # database index file. #unique_subject = no # Set to 'no' to allow creation of # several certs with same subject. new_certs_dir = $dir/newcerts # default place for new certs. certificate = $dir/cacert.crt # The CA certificate serial = $dir/serial # The current serial number crlnumber = $dir/crlnumber # the current crl number # must be commented out to leave a V1 CRL crl = $dir/crl.pem # The current CRL private_key = $dir/privateCA.pem # The private key x509_extensions = usr_cert # The extensions to add to the cert # crlnumber must also be commented out to leave a V1 CRL. crl_extensions = crl_ext default_days = 3650 # how long to certify for default_crl_days= 30 # how long before next CRL default_md = sha256 # use SHA-256 by default preserve = no # keep passed DN ordering
In this configuration,
./databaseCA
is the directory where OpenSSL will store its database of certificates,./privateCA.pem
is the CA's private key, and./cacert.crt
is the CA's certificate. Ensure the directory and file paths match your environment, which we created in step one. Consult OpenSSL.org's documentation for a complete list of configuration options. -
Set up the CRL file. This OpenSSL command generates the file
ca.crl
, which contains the updated list of certificates that have been revoked based on the existing configurations:$ sudo openssl ca -config openssl.cnf -gencrl -out /etc/hapee-2.7/ca.crl
Revoking certificates
By using Certificate Revocation Lists (CRLs), you can effectively revoke client certificates in your HAProxy Enterprise environment. Revoked certificates will be denied access based on your configured CRL file.
Here is an example snippet in which we add the crl-file
argument to deny access to clients who have revoked certificates:
frontend www mode http bind 192.168.10.1:443 ssl crt
/etc/hapee-2.0/server.crtverify required ca-file/etc/hapee-2.0/certs/cacert.crtcrl-file/etc/hapee-2.0/ca.crl
The option crl-file ./ca.crl
is used to check if the client has been revoked in the Certificate Revocation List provided in the argument.
-
If you need to revoke a particular certificate, you can run this command:
$ openssl ca -config openssl.cnf -revoke client.crt
This will immediately revoke the cert
client.crt
as confirmed by the output:Using configuration from openssl.cnf Revoking Certificate 01. Data Base Updated
Now the cert
client.crt
has been invalidated. -
Once this is done, you can either decide to create a new CRL or update the existing one. In our example, we will update the existing CRL:
$ sudo openssl ca -config openssl.cnf -gencrl -out /etc/hapee-2.7/ca.crl
-
Reload HAProxy Enterprise when you're done making changes.
$ sudo systemctl reload hapee-2.0-lb
Additional revocation options
Including
crt-ignore-err all
instructs HAProxy Enterprise to disregard any errors related to client certificates.-
The option
crl-file ./ca.crl
verifies whether the client's certificate has been revoked.frontend www mode http bind 192.168.10.1:443 ssl crt
/etc/hapee-2.0/server.pemca-file/etc/hapee-2.0/cacert.crtverify required crt-ignore-err all crl-file/etc/hapee2.0/ca.crl
Please verify your environment paths for the keys, certificates, and CRL.
Make authentication optional
In the following configuration, both users with and without a certificate are allowed to establish a connection.
The keywords verify optional
enables this behavior.
frontend www mode http bind 192.168.10.1:443 ssl crt
/etc/hapee-2.0/server.pemca-file/etc/hapee-2.0/cacert.crtverify optional crl-file/etc/hapee-2.0/ca.crl
Reload HAProxy Enterprise when you're done making changes.
$ sudo systemctl reload hapee-2.0-lb
Show error pages for certificate errors
By utilizing the configuration options below, we can direct users to different backends based on the presence or absence of a certificate.
-
Configure HTML pages on your webserver. For example,
certexpired.html
andcertrevoked.html
pages.The file
/certexpired.html
could present a dedicated page to users whose certificate has expired, providing guidance on how to renew or request a new certificate.Those with revoked certificates could be directed to the dedicated page
/certrevoked.html
.
-
Edit your load balancer configuration to include
redirect location
directives:backend servers mode http option http-server-close redirect location
/certexpired.htmlif { ssl_c_verify 10 } ! { path/certexpired.html} redirect location/certrevoked.htmlif { ssl_c_verify 23 } ! { path/certrevoked.html} -
Reload HAProxy Enterprise when you're done making changes.
$ sudo systemctl reload hapee-2.0-lb
Redirect HTTP to HTTPS
It is possible to redirect HTTP requests to HTTPS by including an http-request redirect scheme
line:
frontend www mode http bind *:443 ssl crt
/etc/hapee-2.0/certs/site.pemverify required ca-file/etc/hapee-2.0/certs/cacert.crthttp-request redirect scheme https unless { ssl_fc } default_backend serversThe line
http-request redirect scheme https unless { ssl_fc }
is the redirect command. If a connection comes in over HTTP through the frontendwww
, then it is redirected to use HTTPS instead.
This configuration ensures that all incoming connections are served over HTTPS (port 443).
For more information see redirects under Traffic Routing.
Reload HAProxy Enterprise when you're done making changes.
$ sudo systemctl reload hapee-2.0-lb
Next up
JSON Web Token-Based Authorization