The HAProxy load balancer provides high-performance SSL termination, allowing you to encrypt and decrypt traffic.
You can quickly and easily enable SSL/TLS encryption for your applications by using HAProxy SSL termination. HAProxy is compiled with OpenSSL, which allows it to encrypt and decrypt traffic as it passes. In this blog post, you will learn how to set this up and why delegating this function to HAProxy simplifies your infrastructure.
The Benefits of SSL Termination
When you operate a farm of servers, it can be a tedious task maintaining SSL certificates. Even using a Let’s Encrypt Certbot to automatically update certificates has its challenges because, unless you have the ability to dynamically update DNS records as part of the certificate renewal process, it may necessitate making your web servers directly accessible from the Internet so that Let’s Encrypt servers can verify that you own your domain.
Enabling SSL on your web servers also costs more CPU usage, since those servers must become involved in encrypting and decrypting messages. That CPU time could otherwise have been used to do other meaningful work. Web servers can process requests more quickly if they’re not also crunching through encryption algorithms simultaneously.
The term SSL termination means that you are performing all encryption and decryption at the edge of your network, such as at the load balancer. The load balancer strips away the encryption and passes the messages in the clear to your servers. You might also hear this called SSL offloading.
SSL termination has many benefits. These include the following:
- You can maintain certificates in fewer places, making your job easier.
- You don’t need to expose your servers to the Internet for certificate renewal purposes.
- Servers are unburdened from the task of processing encrypted messages, freeing up CPU time.
Enabling SSL with HAProxy
HAProxy version 1.5, which was released in 2016, introduced the ability to handle SSL encryption and decryption without any extra tools like Stunnel or Pound. Enable it by editing your HAProxy configuration file, adding the
crt parameters to a
bind line in a
frontend section. Here’s an example:
ssl parameter enables SSL termination for this listener. The
crt parameter identifies the location of the PEM-formatted SSL certificate. This certificate should contain both the public certificate and private key. That’s it for turning on this feature. Once traffic is decrypted it can be inspected and modified by HAProxy, such as to alter HTTP headers, route based on the URL path or Host, and read cookies. The messages are also passed to backend servers with the encryption stripped away.
Although you lose some of the benefits of SSL termination by doing so, if you prefer to re-encrypt the data before relaying it, then you’d simply add an
ssl parameter to your
server lines in the
backend section. Here’s an example:
When HAProxy negotiates the connection with the server, it will verify whether it trusts that server’s SSL certificate. If the server is using a certificate that was signed by a private certificate authority, you can either ignore the verification by adding
verify none to the
server line or you can store the CA certificate on the load balancer and reference it with the
ca-file parameter. Here’s an example that references the CA PEM file:
If the certificate is self-signed, in which case it acts as its own CA, then you can reference it directly.
Redirecting from HTTP to HTTPS
When a person types your domain name into their address bar, more likely than not, they won’t include https://. So, they’ll be sent to the http:// version of your site. When you use HAProxy for SSL termination, you also get the ability to redirect any traffic that is received at HTTP port 80 to HTTPS port 443.
http-request redirect scheme line to route traffic from HTTP to HTTPS, like this:
This line uses the
unless keyword to check the
ssl_fc fetch method, which returns true unless the connection used SSL/TLS. If it wasn’t used, the request is redirected to the https scheme. Now, all traffic will end up using HTTPS.
This paves the way to adding an HSTS header, which tells a person’s browser to use HTTPS from the start the next time they visit your site. You can add an HSTS header by following the steps described in our blog post, HAProxy and HTTP Strict Transport Security (HSTS) Header in HTTP Redirects.
Limiting Supported Versions of SSL
As vulnerabilities are discovered in older versions of SSL and TLS, those versions are marked deprecated and should no longer be used. With HAProxy, you can allow only certain versions of SSL to be negotiated. Add an
ssl-min-ver directive to a
frontend, specifying the oldest version you want to support.
In the following example, only TLS version 1.2 and newer is allowed:
Today, possible values for this parameter are:
You can set this for all proxies by adding it to your
global section in the form of an
ssl-default-bind-options directive, as shown:
Limiting Supported Ciphers
In addition to setting the allowed versions of SSL and TLS, you can also set the encryption ciphers that you’ll use by adding a
ciphers parameter to the
bind line. These are set in preferred order, with fallback algorithms bringing up the end of the list. HAProxy will select the first cipher that the client also supports, unless the
prefer-client-ciphers parameter is present, in which case the client’s preferred cipher is selected.
It looks like this:
Consider using the Mozilla SSL Configuration Generator when deciding which ciphers to include.
You can also set a default value by adding an
ssl-default-bind-ciphers directive to your
global section, as shown:
Choosing the Certificate with SNI
Server Name Indication (SNI) is a TLS extension that allows the browser to include the hostname of the site it is trying to reach in the TLS handshake information. You can use this to dynamically choose which certificate to serve.
Instead of setting the
crt parameter to the path to a single certificate file, specify a directory that contains multiple PEM files. HAProxy will find the correct one by checking for a matching common name or subject alternative name.
Here’s an example:
If the client does not send SNI information, HAProxy uses the first file listed in the directory, sorted alphabetically. Therefore, it’s a good idea to name the PEM files so that the default certificate is listed first.
You can restrict who can access your application by giving trusted clients a certificate that they must present when connecting. HAProxy will check for this if you add a
verify required parameter to the bind line, as shown:
In addition to
verify required, you can use
ca-file to set a path to a CA file in order to verify that the client’s certificate is signed and trusted. You can also include a
crl-file parameter to indicate a certificate revocation list.
In this blog post, you learned how to enable SSL termination with HAProxy. Allowing HAProxy to manage encryption and decryption has several benefits, including reducing work done on your backend servers, making certificate maintenance easier, and avoiding exposing your servers directly to the Internet for certificate renewal purposes.