Easily Remove Existing HAProxy Connections Made via Client Authentication

Most load balancers only check a client certificate when the client first connects. However, this can be problematic if a client stays connected for an extended period of time. Staying connected would allow clients to continually send and receive data.

Imagine you have an employee whose certificate and key were stolen by an adversary. If you are using TLS client authentication, that adversary can connect to your infrastructure and maintain illegal access. And even after you revoke that certificate, that adversary will remain connected until they themselves close that connection. 

For many vendors, the only fix for this is to clear all existing connections and force everyone to re-connect. This is extremely disruptive and can lead to lost revenue since it also kills legitimate connections. 

Luckily, HAProxy Enterprise lets you immediately drop connections and remove the client if their certificate is revoked. Meanwhile, other customers and users aren't affected. Any subsequent attempt to reconnect using that revoked certificate will fail.

Introduction to client authentication

You can use a certificate authority (CA) to generate a client certificate and key. That certificate and key function is like a virtual ID badge—serving as authentication for that client while enabling the server to verify that the client is authorized to access a given resource. 

Since TLS exists at OSI Layer 6, you can use TLS client authentication to secure and authenticate for a variety of applications. One of the most common use cases is securing HTTP traffic. However, you can use TLS authentication to add a layer of security to other protocols, such as SSH. 

The mTLS authentication configuration for either of these protocols can be identical from an HAProxy perspective, which is why we've used a generic example below using a random port. You can use this same configuration with HTTP—just remember to keep the frontend and backend in mode tcp for that configuration, too:

global
log 127.0.0.1 local0
stats socket /var/run/hapee-lb.sock level admin mode 660
module-path /opt/hapee-2.9/modules/
module-load sslcrl.so
defaults
mode tcp
timeout connect 2s
timeout client 10s
timeout server 10s
sslcrl sslcrl-prod-1-config
log global
log-format "%ci:%cp [%t] %ft %bi:%bp"
option hard-errors
check-interval 10s
frontend fe_ssh_crl_example
mode tcp
bind :76 ssl crt /etc/hapee-2.9/certs/www.example.com.crt ca-file /etc/hapee-2.9/certs/chain_file.crt verify required crl-file /etc/hapee-2.9/certs/live_crl.pem
filter sslcrl id my-ssl-crl config sslcrl-prod-1-config
default_backend be_ssh_crl_example
backend be_ssh_crl_example
mode tcp
server server1 172.16.1.32:76

There are three important things to note about this configuration:

  1. This module currently only works with mode tcp and not http mode.

  2. If you're sending more than one certificate authority (CA) you MUST have a CRL list for each.

  3. If you update the file using the CLI, the global option tune.bufsize needs to be larger than the size of that file (the default is 16Kb).

Understanding the configuration

For those new to the HAProxy Enterprise configuration file, the code sample above might seem complex. Let's break down each section and its key components to highlight their importance.

global

Generally appearing at the top of the configuration file, the global section defines process-level directives such as the maximum number of concurrent connections, where to store logs, and which user and group the process should run under. Here's why each line from our sample matters: 

  • The log line helps if you need to troubleshoot.

  • stats socket is where you'll post your changes, also called the Runtime API.

  • module-path is the path where all the modules reside by default.

  • module-load references the module we need.

defaults

The defaults section contains common settings which will be inherited by frontend,backend and listen sections after it. It helps shorten longer configurations by reducing duplicated lines. Our sample configuration contains some generic values that are helpful to define. 

For example, client, server, and connection timeout values default to infinite if not set explicitly. Choosing a value for each helps avoid keeping open connections that were silently closed or discarded by one endpoint.

frontend

The frontend section defines which IP addresses and ports clients can connect to. This helps expose applications or websites to the internet. Our sample configuration contains many important lines that impact SSL/TLS enablement and certificate management. 

First, you must be in mode tcp since mode http won't work effectively at the time of this writing but should exist in the future. 

Second, we've set up a bind on the randomly chosen port 76. Make sure you modify this to be the port that your application uses. This particular line also contains some important pieces that influence SSL and certificate-related behaviors:  

  • Together, the ssl and crt portions enable SSL in HAProxy Enterprise while specifying what certificate to present to the client in the server hello. 

  • ca-file specifies which certificate authority to present. This file can contain more than one CA if needed, but requires a CRL for each in this instance. 

  • verify required states that the client's certificate must be valid or the connection will be rejected.

  • crl-file refers to your certificate revocation list.

  • Lastly, filter sslcrl enables the ssl-crl module.

backend

The backend section defines a server pool to which HAProxy Enterprise will route requests. You can normally add as many backend sections as you need to your configuration, but our example contains a generic configuration for the purposes of this walkthrough. 

With this overall configuration, you can now configure your client software to send a certificate. HAProxy Enterprise will validate this certificate and accept it if it's valid. If you'd like to set up your own test certificates, this blog post from Didier Stevens (unaffiliated with HAProxy Technologies) outlines some great how-to steps. The creation of these files is outside the scope of this blog, however.

Using the CLI to view and revoke

using-the-cli-to-view-and-revoke-1725371412

Once the configuration is up and running it's quite simple to revoke a certificate with the command line interface (CLI). Here's a brief overview.

First, we recommend viewing your current CRL file. This is also helpful to run before and after your updates if you want to validate the changes. Run the following command:

echo "show ssl crl-file /etc/hapee-2.9/certs/live_crl.pem" | sudo socat - UNIX-CONNECT:/var/run/hapee-lb.sock

The second step comes after you revoke a certificate and get an updated CRL. You'll then update the CRL file in memory with that updated CRL—which adds another certificate to revoke (this appends the existing list in memory)—using the following command:

echo "set ssl crl-file "/etc/hapee-2.9/certs/live_crl.pem" \<\<\\n$(cat "/etc/hapee-2.9/certs/live_crl.pem")\\n" | sudo socat - UNIX-CONNECT:/var/run/hapee-lb.sock
Important Note

Appending this file in memory doesn't write it to disk. Please update your CRL on disk first.

Finally, commit that change after updating your CRL file:

echo "commit ssl crl-file /etc/hapee-2.9/certs/live_crl.pem" | sudo socat - UNIX-CONNECT:/var/run/hapee-lb.sock

Once you issue this commit command, HAProxy Enterprise will update the CRL file in memory. HAProxy Enterprise will then promptly update its list of revoked client certificates and close any client connection(s) using that now-revoked certificate.

Here's a sample output from our earlier configuration:

$ echo "show ssl crl-file /etc/hapee-2.9/certs/live_crl.pem" | sudo socat - UNIX-CONNECT:/var/run/hapee-lb.sock
Filename: /etc/hapee-2.9/certs/live_crl.pem
Status: Used
Certificate Revocation List #1:
Version 1
Signature Algorithm: sha256WithRSAEncryption
Issuer: /CN=Interm.
Last Update: Dec 26 18:46:32 2023 GMT
Next Update: Dec 25 18:46:32 2025 GMT
No Revoked Certificates.
Certificate Revocation List #2:
Version 1
Signature Algorithm: sha256WithRSAEncryption
Issuer: /CN=Root-ca
Last Update: Dec 26 18:18:39 2023 GMT
Next Update: Dec 25 18:18:39 2025 GMT
No Revoked Certificates.

Basic troubleshooting

To verify that the certificate is valid and usable with your certificate authority, you can use OpenSSL to check the client certificate:

openssl verify -CAfile /etc/hapee-2.9/certs/chain_file.crt client_certificate.crt

If that returns "OK" then the certificate and CA are valid for use together.

Lastly, you can then use openssl to open a connection to your frontend and use the client certificate. Also confirm that www.host.com resolves properly to the IP address that your frontend is listening on:

openssl s_client -cert client_certificate.crt -key client_certificate.key -tls1_2 -cipher 'AES128-GCM-SHA256' -connect www.host.com:443 -no_ticket

Conclusion

Intelligent certificate management is essential in cases where certificates and keys are lost, stolen, or intentionally abused to launch cyber attacks. HAProxy Enterprise makes this complex process even easier and more flexible—letting you enable SSL, define certificate-related behaviors, and leverage certificate revocation lists to bolster infrastructure security. 

HAProxy Enterprise removes the burden, frustration, and revenue loss that can result from dropping all existing client connections to counteract suspicious behavior. Harness real-time revocation to keep your systems safe and your customers happy. To learn more, check out our HAProxy Enterprise SSL-CRL documentation or our HAProxy and Let's Encrypt: Improved Support in acme.sh blog post.

Subscribe to our blog. Get the latest release updates, tutorials, and deep-dives from HAProxy experts.