SSL / TLS
Client-side encryption
You can use Transport Layer Security (TLS) for encrypting traffic between the load balancer and clients. TLS is the successor to Secure Sockets Layer (SSL), which is now deprecated.
Enable TLS Jump to heading
The load balancer offers you flexibility in regards to enabling TLS for your frontends. The needs of your application, your configuration, and your certificate storage, that is, where you store your certificates, keys, and other related files on your filesystem, may determine which configuration feature you should use. There are three configuration concepts to consider:
crt
- This keyword indicates that you will use either a single
PEM
file containing both the required certificates and any associated private keys, or you will use multiple files that are co-located in a single directory and share a name, for examplesite1.crt
,site1.key
,site1.ocsp
, and so on. The load balancer will load the file, or the directory containing the files, that you specify as thecrt
. Additional configuration options are available for this keyword and they apply to allcrt
entries on the samebind
line.
- This keyword indicates that you will use either a single
crt-list
- You can specify a
crt-list
file in place of mulitplecrt
declarations if you need to apply different SSL configuration options per certificate. All of the certificate files, key files, and oscp files must be co-located, as is the case withcrt
.
- You can specify a
crt-store
- Available as of version 3.0, the
crt-store
provides additional flexibility regarding the location of related certificate files, key files, and so on. You can use acrt-store
to specify different filesystem locations for certificate and key files, and you can assign aliases to certificates for easier readability when referenced in the load balancer configuration or incrt-list
files.
- Available as of version 3.0, the
See configuration considerations to help you decide which configuration concept is best suited for your application.
Use crt to enable TLS Jump to heading
For HTTPS, you will typically bind to port 443. In this setup, the load balancer handles encrypting and decrypting traffic, and sends traffic in the clear to backend servers. The backend servers can then listen on port 80 (HTTP port).
haproxy
frontend wwwbind :443 ssl crt /certs/site.pemdefault_backend webservers
haproxy
frontend wwwbind :443 ssl crt /certs/site.pemdefault_backend webservers
In this example:
- The
ssl
argument enables TLS encryption. - The
crt
argument indicates the file path to a.pem
file that contains both your server’s PEM-formatted TLS certificate and its private key. You will typically need to concatenate these two things manually into a single file. Simply copy and paste them into the file.
Setting crt to a directory
You can also set the crt
argument to a directory. When set to a directory, the load balancer will use Server Name Indication (SNI) to search the directory for a certificate that has a Common Name (CN) or Subject Alternative Name (SAN) field that matches the requested domain, which the client sends during the TLS handshake.
This allows you to host multiple websites with different domain names at the same IP address and port. Each will use the certificate that matches the domain name being requested. In the example below, we set crt
to a directory that contains TLS certificates:
haproxy
frontend wwwmode httpbind :443 ssl crt /certsdefault_backend webservers
haproxy
frontend wwwmode httpbind :443 ssl crt /certsdefault_backend webservers
Use crt-store to enable TLS Jump to heading
Available since:
- HAProxy 3.0
- HAProxy Enterprise 3.0r1
- HAProxy ALOHA 16.5
You can configure the load balancer’s internal certificate storage mechanism using a crt-store
. The crt-store
separates certificate storage from their use in a frontend, and provides better visibility for certificate information by moving it from external files, such as within crt-list
s, and placing it into the main HAProxy configuration. The crt-store
section allows you to individually specify the locations of each certificate component, for example certificates files, key files, and OCSP response files.
To use a crt-store
:
-
Define a
crt-store
section in your load balancer configuration. Consider the following example:haproxycrt-store webcrt-base /etc/haproxy/ssl/certs/key-base /etc/haproxy/ssl/private/load crt "site1.crt"load crt "site2.crt" key "site2.key"haproxycrt-store webcrt-base /etc/haproxy/ssl/certs/key-base /etc/haproxy/ssl/private/load crt "site1.crt"load crt "site2.crt" key "site2.key"In this example:
- The
crt-store
section namedweb
indicates the TLS certificates that the load balancer will use. - The
crt-base
directive specifies the directory to search for TLS certificate files. In this example, files are located at/etc/haproxy/ssl/certs
. - The
key-base
directive specifies the directory to search for key files. In this example, files are located at/etc/haproxy/ssl/private
. - Each
load
directive indicates a certificate file and options that pertain to it. - The
load
directive’s alias argument allows us to reference this certificate later by that name.
- The
-
Use this
crt-store
definition in a frontend by referencing it by name via abind
directive’scrt
argument. The format for the name is@<crt-store name>/<certificate name or alias>
, or in this case,@web/site2.crt
and@web/site2.crt
:haproxyfrontend mainbind *:443 ssl crt "@web/site1.crt" crt "@web/site2.crt"haproxyfrontend mainbind *:443 ssl crt "@web/site1.crt" crt "@web/site2.crt"
You can also specify the crt-base
and key-base
in your global settings. Note that including crt-base
or key-base
in a crt-store
take precedence over the global settings. The same is true for using absolute paths when specifying your certificates and keys.
See the load reference for options available for the load
keyword.
Info
If you do not give your crt-store
a name, you can reference its certificates using @/<certificate name or alias>
, leaving out of the name of the crt-store
. For example, @/site1.crt
for a certificate named site1.crt
defined in an unnamed crt-store
.
Update certificate files dynamically
You can update certificate files dynamically using Runtime API commands including set ssl cert
. See Update an ssl certificate using the runtime API for more information.
Use aliases to reference certificate components Jump to heading
Aliases provide support for human-friendly names for referencing the certificates more easily on bind lines. To use aliases:
-
Define a
crt-store
in your configuration. In the example below, we name ourcrt-store
web
and we can reference thiscrt-store
by name using@web
.haproxycrt-store webcrt-base /etc/haproxy/ssl/certsload crt "site1.pem" ocsp "site1.ocsp" alias "site1" ocsp-update onhaproxycrt-store webcrt-base /etc/haproxy/ssl/certsload crt "site1.pem" ocsp "site1.ocsp" alias "site1" ocsp-update on -
In your
load
directive in yourcrt-store
, give yourcrt
an alias using thealias
option. In this example, we give the certificate namedsite1.pem
an alias ofsite1
.haproxycrt-store webcrt-base /etc/haproxy/ssl/certsload crt "site1.pem" ocsp "site1.ocsp" alias "site1" ocsp-update onhaproxycrt-store webcrt-base /etc/haproxy/ssl/certsload crt "site1.pem" ocsp "site1.ocsp" alias "site1" ocsp-update onNote that in this example we also specify that the certificate’s corresponding OCSP response file is named
site1.ocsp
. We enable OCSP stapling for this certificate by including the optionocsp-update
and setting it toon
. -
Reference the certificate components defined in the
crt-store
by the aliassite1
in a frontend:haproxyfrontend mainbind *:443 ssl crt "@web/site1"default_backend apphaproxyfrontend mainbind *:443 ssl crt "@web/site1"default_backend appIn this frontend:
- We set the
crt
as@web/site1
. This means that:- we are using the
crt-store
namedweb
. - from the
crt-store
named web, we want the certificate components having the aliassite1
. In this case, as we defined in thecrt-store
, that is the certificatesite1.pem
and OCSP response filesite1.ocsp
.
- we are using the
- We set the
Redirect HTTP to HTTPS Jump to heading
To enable an HTTP to HTTPS redirect, use the http-request redirect scheme
directive:
haproxy
frontend wwwmode httpbind :80bind :443 ssl crt /certs/site.pemhttp-request redirect scheme https unless { ssl_fc }default_backend webservers
haproxy
frontend wwwmode httpbind :80bind :443 ssl crt /certs/site.pemhttp-request redirect scheme https unless { ssl_fc }default_backend webservers
In this example:
- We set
mode
tohttp
. - We enable TLS with the
ssl
andcrt
arguments on the secondbind
line. Notice that this frontend listens on both ports 80 for HTTP and 443 for HTTPS. Traffic that is received at HTTP port 80 is redirected to HTTPS port 443. - Use the
http-request redirect scheme
directive to redirect HTTP traffic to the HTTPS scheme, unless it is already HTTPS as indicated by the ssl_fc fetch method.
Info
Even with the redirect, there is still a chance that a man-in-the-middle attack can occur. To prevent this attack, consider using the http-response set-header Strict-Transport-Security
directive. For details, see HTTP Strict Transport Security.
Set default certificates Jump to heading
Available since
- HAProxy 3.0
- HAProxy Enterprise 3.0r1
- HAProxy ALOHA 16.5
If you specify the crt
as a directory, the load balancer will use Server Name Indication (SNI) to search the directory for a certificate that has a Common Name (CN) or Subject Alternative Name (SAN) field that matches the requested domain, which the client sends during the TLS handshake. If the client does not provide an SNI, or if the SNI hostname does not match any certificate, the load balancer will present a default certificate. You can specify default certificates on your bind
line using the default-crt
option. To set a default certificate:
-
Add the
default-crt
option to thebind
line in your frontend, specifying the names of your default certificates. Note that you can specify multiple default certificates, for example, an ECDSA certificate and an RSA certificate. Specifying multiple certificates in this way will allows you to give precedence to the ECDSA certificate, presenting the RSA certificate otherwise.haproxyfrontend fe_mainbind :80bind :443 ssl default-crt /certs/default.pem.ecdsa /certs/default.pem.rsa crt /certs/# Redirects to HTTPShttp-request redirect scheme https unless { ssl_fc }haproxyfrontend fe_mainbind :80bind :443 ssl default-crt /certs/default.pem.ecdsa /certs/default.pem.rsa crt /certs/# Redirects to HTTPShttp-request redirect scheme https unless { ssl_fc }In this example:
- We specify the default certificates as
/certs/default.pem.ecdsa
and/certs/default.pem.rsa
. The load balancer will try to use the ECDSA certificate first, and if unsupported by the client, use the RSA certificate. - We set the directory for our certificates as
/certs/
. The load balancer will select the appropriate certificate from this directory based on the SNI. If it cannot find a matching certificate, it will use the default certificates.
- We specify the default certificates as
Note that the load balancer will use default certificates only when you are not also using the strict-sni
option.
Other ways to set default certificates
If you do not explicitly define your default certificates using the default-crt
keyword, the load balancer will try to select and load a default certificate in one of the following ways:
-
The load balancer will use the first certificate in the directory. If you intend to load default certificates in this way, ensure that this first certificate file is a multi-cert bundle (PEM format).
-
If you are using a
crt-list
, mark your certificate with an asterisk to indicate that the load balancer should consider it to be the default. For example:crt-list.txtnixdefault.pem.rsa *default.pem.ecdsa *crt-list.txtnixdefault.pem.rsa *default.pem.ecdsa *
HTTP Strict Transport Security Jump to heading
Use HTTP Strict Transport Security (HSTS) to prevent a man-in-the-middle attack.
The HTTP Strict Transport Security (HSTS) policy directs clients to communicate over secure transport. This policy can prevent man-in-the-middle attacks, where the redirected traffic is intercepted by a malicious party.
HSTS works by sending the response header Strict-Transport-Security
to clients. This header directs the client browser to use HTTPS instead of HTTP for this domain and, optionally, its subdomains.
Load balancer applications use the redirect scheme https
directive to direct HTTP traffic to HTTPS, but that directive alone does not prevent a man-in-the-middle attack. Adding the HSTS header, however, prevents the man-in-the-middle attack by requiring the client to direct traffic to the secure site without relying on redirects. The client browser caches your domain’s HSTS policy so that for future HTTP requests, it automatically uses secure transport instead of HTTP.
The Strict-Transport-Security
header fields are:
Field | Description |
---|---|
max-age |
Required. Sets how long the browser should remember the rule, in seconds, after the user has visited the website at least once. The next time the user client accesses your domain, the HSTS policy will be cached again. |
includeSubDomains |
Optional. Tells the browser that it should include all of your subdomains in the rule. |
preload |
Optional. Submit your site to the HSTS preload service, which is a registry of websites that browsers will connect to using HTTPS automatically. The preload option requires includeSubDomains . |
Enable HSTS Jump to heading
To enable HSTS:
-
Configure the redirect to HTTPS in your frontend section.
-
Insert the
Strict-Transport-Security
header into every response using thehttp-response set-header
directive, as shown here:haproxyfrontend www.mywebsite.combind :80bind :443 ssl crt /etc/ssl/certs/mywebsite.com.pemhttp-request redirect scheme https code 301 unless { ssl_fc }# max-age is mandatory. 16000000 seconds is approximately 6 months. Use a low value during testing.http-response set-header Strict-Transport-Security "max-age=16000000; includeSubDomains; preload;"default_backend servershaproxyfrontend www.mywebsite.combind :80bind :443 ssl crt /etc/ssl/certs/mywebsite.com.pemhttp-request redirect scheme https code 301 unless { ssl_fc }# max-age is mandatory. 16000000 seconds is approximately 6 months. Use a low value during testing.http-response set-header Strict-Transport-Security "max-age=16000000; includeSubDomains; preload;"default_backend servers
With this configuration, HAProxy returns the Strict-Transport-Security
header, which instructs the browser to route messages to this website using HTTPS from the start. This rule lasts for 16000000 seconds (approximately six months) after the user has visited your website at least once. From then on, attackers will no longer get a chance to intercept your user’s messages. As a side effect, it also avoids one round trip between the user and server, improving response times.
Info
During testing, use a low max-age
value to minimize the impact on clients accessing any subdomains that do not yet support HTTPS. Once the HSTS policy is cached in the client’s browser, the browser will use only HTTPS to access your domain until the max-age
expires. So until you’re sure all subdomains support HTTPS, use a low max-age
value.
Global settings Jump to heading
Some TLS settings should apply to your entire load balancer, such as whether to allow older versions of TLS or whether to set a list of preferred ciphers. Although it’s possible to set these things at the bind
or server
level, you will often want to apply them across the board. In that case, you can add them to the global
section of your configuration.
Set the minimum TLS version Jump to heading
The following example uses ssl-default-bind-options to allow only version TLS 1.2 or newer on all bind
lines:
haproxy
globalssl-default-bind-options ssl-min-ver TLSv1.2
haproxy
globalssl-default-bind-options ssl-min-ver TLSv1.2
To set this on an individual bind
line, use the ssl-min-ver argument.
Set the TLS ciphers Jump to heading
Use the ssl-default-bind-ciphers directive to set a list of TLS ciphers for bind
lines, in order of preference:
haproxy
globalssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
haproxy
globalssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
To use the client’s preferred cipher instead, specify the prefer-client-ciphers
parameter.
To set this on an individual bind
line, use the ciphers argument.
For TLS versions 1.3 and later, set the preferred encryption ciphers in your global
section using the ssl-default-bind-ciphersuites option. Note that you can override this value on each bind
line (including bind
lines in crt-list
files).
haproxy
globalssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
haproxy
globalssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
To set this on an individual bind
line, use the ciphersuites argument.
Disable validation of certificates Jump to heading
When the load balancer connects to a backend server over HTTPS, the server presents its own certificate. To disable validation of server certificates, such as when using self-signed certificates, set the ssl-server-verify directive to none
:
haproxy
globalssl-server-verify none
haproxy
globalssl-server-verify none
To set this on an individual server
line, use the verify argument.
Performance considerations Jump to heading
Consider these factors when estimating TLS encryption performance:
-
Encryption with an ECC certificate uses about 1/8 of the CPU of an RSA certificate of an equivalent cryptographic strength.
If you have both an ECC and RSA certificate, you can use both at the same time by using the file name extensions. Name the RSA certificate file with an
.rsa
extension, such asexample.pem.rsa
. Name the ECC certificate with an.ecdsa
extension, such asexample.pem.ecdsa
. In your configuration, set thecrt
argument to load the file with only the.pem
extension, omitting the.rsa
or.ecdsa
extension, such ascrt example.pem
. -
How large are your RSA keys? 2048 is typical, 4096 will be substantially slower. The older 1024 is considered insecure and will no longer be signed by public CAs.
-
Are TLS session tickets enabled on the load balancer server? This can increase the speed of the TLS handshake.
The following guidelines can help you decide how many cores you need:
- A 3.7GHz CPU core will take about 1ms to process a 2048 bit key exchange, meaning you can do 1000 key exchanges per second.
- 1 GB of RAM can support 8000 open TLS connections.
If you decide that your use case will likely require more than one core, you can use the cpu-map
options with nbthread
to pin threads to specific cores.
For example:
haproxy
globalnbthread 4cpu-map auto:1/1-4 0-3
haproxy
globalnbthread 4cpu-map auto:1/1-4 0-3
Configuration considerations Jump to heading
In some cases you can use either a crt-list
or a crt-store
depending on your configuration needs. You can also provide some of the same options those features provide when defining a crt
on the bind
line. With multiple options for configuration, which one should you choose? The answer depends on the needs of your application, your configuration, and your certificate storage, that is, where you store your certificates, keys, and other related files on your filesystem.
Here are some common use cases with which feature you should consider using:
-
You want to specify different filesystem locations for certificates and keys.
- You should consider using a
crt-store
, as it allows you to specify independent locations for related certificate files, key files, OCSP response files, and so on. If you use onlycrt
withoutcrt-store
or usecrt-list
, the load balancer assumes all of the files are co-located with the certificate.
- You should consider using a
-
You want to set specific SSL options per certificate.
- You should consider using a
crt-list
, as it allows you to specify different options per certificate. Thecrt-list
also supports several keywords from thecrt-store
load
directive.
- You should consider using a
-
You want to use aliases, but also want to be able to set specific SSL options per certificate.
-
You should consider using
crt-store
in combination with acrt-list
. In this way, you can specify the storage locations for your certificate components and give the certificates aliases. Then using the aliases you defined in thecrt-store
, you can then add additional SSL options to each certificate entry in thecrt-list
, referenced by aliases. For example:haproxycrt-storecrt-base /etc/haproxy/ssl/certs/key-base /etc/haproxy/ssl/private/load crt "site1.crt" key "site1.key" ocsp "site1.ocsp" alias "site1"load crt "site2.crt" key "site2.key" alias "site2"load crt "site3.crt" key "site3.key" alias "site3"haproxycrt-storecrt-base /etc/haproxy/ssl/certs/key-base /etc/haproxy/ssl/private/load crt "site1.crt" key "site1.key" ocsp "site1.ocsp" alias "site1"load crt "site2.crt" key "site2.key" alias "site2"load crt "site3.crt" key "site3.key" alias "site3"crt-list.txthaproxy@/site1 [ciphers ECDHE-ECDSA-AES256-GCM-SHA384 ssl-min-ver TLSv1.2]@/site2 [ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256 ssl-min-ver TLSv1.3]@/site3 [ciphers ECDHE-RSA-AES128-GCM-SHA256]crt-list.txthaproxy@/site1 [ciphers ECDHE-ECDSA-AES256-GCM-SHA384 ssl-min-ver TLSv1.2]@/site2 [ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256 ssl-min-ver TLSv1.3]@/site3 [ciphers ECDHE-RSA-AES128-GCM-SHA256]haproxyfrontend wwwbind :443 ssl crt-list /etc/haproxy/certs/crt-list.txtdefault_backend webserversHere each certificate is referenced by alias in the `crt-list`. The `frontend` configuration references the `crt-list` rather than each certificate individually.haproxyfrontend wwwbind :443 ssl crt-list /etc/haproxy/certs/crt-list.txtdefault_backend webserversHere each certificate is referenced by alias in the `crt-list`. The `frontend` configuration references the `crt-list` rather than each certificate individually. -
You have multiple certificates, but you do not want to define your certificates in an external file, as would be the case with a
crt-list
, and you do not need to use the SSL options supported bycrt-list
.- You should consider using a
crt-store
. It enables you to put all of your certificate definitions into your main load balancer configuration file rather than list them in an externalcrt-list
file.
- You should consider using a
-
You have a single certificate per frontend, do not require OCSP stapling, and your related certificate and key files are co-located and share a name,
site1.crt
andsite1.key
, for example.- You should consider using
crt
on yourbind
line. It may be unnecessary for you to use acrt-store
orcrt-list
if you do not require additional options regarding storage or SSL configuration options.
- You should consider using
-
See also Jump to heading
Do you have any suggestions on how we can improve the content of this page?