Transport Layer Security (TLS) and its predecessor, Secure Sockets Layer (SSL), both frequently referred to as "SSL", are cryptographic protocols that provide communications security over a computer network. Among others, websites use TLS to secure all communications between their servers and web browsers.

The TLS protocol primarily aims to provide privacy and data integrity between two communicating computer applications. When secured by TLS, connections between a client (e.g. a web browser) and a server (e.g. twitter.com) have one or more of the following properties:

  1. The connection is private (or secure) because symmetric cryptography is used to encrypt the data transmitted. The keys for this symmetric encryption are generated uniquely for each connection and based on a shared secret that was negotiated at the start of the session (see TLS handshake protocol). The server and client negotiate the details of which encryption algorithm and cryptographic keys to use before the first byte of data is transmitted. The negotiation of a shared secret is both secure and reliable because:

    • the negotiated secret is unavailable to eavesdroppers and cannot be obtained, even by an attacker that places itself in the middle of the connection.

    • no attacker can modify the communications during the negotiation without being detected.

  2. The identity of the communicating parties can be authenticated using public-key cryptography. This authentication can be made optional, but is generally required for at least one of the parties (typically the server).

TLS supports different methods for exchanging keys, encrypting data, and authenticating message integrity. As a result, secure configuration of TLS involves many parameters.

Understanding TLS Terminology

Before you begin, it is useful to understand the terms often encountered when working with TLS:

certificate

A digital certificate that certifies the ownership of a public key by the named subject of the certificate. This allows third parties to rely upon signatures or on assertions from the private key that corresponds to the certified public key.

certificate authority

An entity that issues digital certificates.

cipher suite

A string describing the protocol used for key exchange, data ciphering, and data integrity negotiated by two peers in a TLS connection.

TLS extension

An extension made to the TLS protocol to add more features.

private key

A key generated and owned by the certificate owner, used to generate certificate requests and to establish a TLS connection.

public key

A key associated to the private key and sent to a client in order to create the TLS connection.

Session ID

A unique ID that identifies the TLS session; it can be used to resume a previous session to avoid a full heavy TLS handshake.

SNI

Server Name Indication, or a string containing the name of the service that the client tries to reach (usually, web browsers use the Host header). It is used by the server to present the right certificate and to host multiple certificates over the same IP address.

SSL

Secured Socket Layer. Early and legacy name of the TLS protocol.

symmetric key

A key generated during the TLS connection handshake phase using the public key (client) and the private key (server). A session ID is associated to this key.

TLS

Transport Layer Security. New name of the SSL protocol.

Configuring TLS Settings

You configure TLS settings in HAProxy Enterprise in the global section, the frontend, and the backend.

Define TLS settings in the Global Section

Directive

Description

ssl-default-bind-ciphers <ciphers>

A string describing the list of cipher suite algorithms that HAProxy supports. It applies to all bind lines where SSL is enabled

Note

Mozilla offers a page of TLS recommended configurations for modern, intermediate, and old backward compatibility ciphers here: You can copy and paste the one to suit your needs.

ssl-default-bind-options [<option>]...

SSL/TLS options to apply to all bind lines where SSL is enabled. <options> are the ones from the frontend bind directive

ssl-default-server-ciphers <ciphers>

A string describing the list of cipher suite algorithms. It applies to all servers where SSL is enabled

Note

Mozilla offers a page of TLS recommended configurations for modern, intermediate, and old backward compatibility ciphers here: You can copy and paste the one to suit your needs.

ssl-default-server-options [<option>]...

SSL/TLS options to apply to all bind lines where SSL is enabled. <options> are the one from the backend server directive

ssl-server-verify [none|required]

Default behavior for TLS connection verification on the server side:

  • When set to none, certificate errors are ignored.

  • The default is required, which means that HAProxy refuses the connection to a server if its certificate is in error (self-signed, outdated, etc...).

tune.ssl.cachesize <number>

Sets the size of the global SSL/TLS session cache. Default number is 20000. When the cache is full and a new entry is required, the least recently used entry is removed.

tune.ssl.lifetime <timeout>

Sets the life time of a SSL/TLS session in the cache. timeout is expressed in seconds, and its default value is 300 (5 minutes). After timeout, the session is purged from the cache and a new one is generated.

tune.ssl.maxrecord <number>

Sets the maximum <number> of bytes passed to the SSL/TLS layer at a time. By default, <number> is 0, which means no limit.

The client cannot start deciphering the stream until it has received a full segment. Reducing this value may improve application response time on the client side.

tune.ssl.default-dh-param <number>

Sets the maximum size of the Diffie-Hellman parameters used to generate the ephemeral/temporary Diffie-Hellman key when using DHE key exchange. Default <number> value is 1024. Higher values increase CPU load and may not be supported by some clients (IE:Java 7).

Define bind directives on the frontend

The following directives are valid only if the bind line also owns the statement ssl:

Directive

Description

alpn <protocols>

Enables the TLS ALPN extension and advertises the <protocol> list (comma separated) supported by HAProxy itself and/or the server behind it.

ca-file <ca-file>

Designates the CA certificate to use in order to validate CA certificates provided by clients.

ca-ignore-err all|<errorid>,...

Sets a list of TLS error IDs to ignore when performing TLS handshakes at depth > 0. The TLS handshake is aborted when an error occurs. By default, no errors are ignored. When all is set, all errors are ignored.

Note

The SSL handshake is ignored when an error occurs.

ciphers

A string describing the list of cipher suite algorithms

Note

Mozilla offers a page of TLS recommended configurations for modern, intermediate, and old backward compatibility ciphers here: You can copy and paste the ones that suit your needs.

crl-file <crlfile>

Designates a PEM file (Privacy Enhanced Mail) from which HAProxy can load a certificate revocation list. The list is used to verify client certificates.

crt <pem-file>

Designates the file containing the certificate and its associated private key. Possibly, intermediaries and root certificates may be included as well. The <pem-file> format is PEM. After multiple crt <pem-file> certificates are loaded, HAProxy uses the SNI from the client to choose the best one. If there is no SNI, then HAProxy loads the default certificate, which is the first on the list.

crt-ignore-err all|<errorid>,...

Sets a list of TLS error IDs to ignore during verification at depth 0. <errors> is a comma separated list. By default, no error is ignored. When all is used, all errors are ignored.

Note

The SSL handshake is ignored when an error occurs.

crt-list <file> [[!]<snifilter ...]

Designates a file containing a list of PEM file certificates and associated optional list of SNI filters. Each line in <file> follows this scheme: <pemfile> [[!]<snifilter> ...] The SNI filter supports wildcards. Negative filters are also supported, but they are only useful when combined with a wildcard filter to exclude a specific SNI.

force-sslv3

Enforces the use of SSL protocol version SSLv3.

Note

Not recommended on Internet because of the poodle vulnerability: https://poodle.io/

force-tlsv10

Enforces the use of TLS protocol version 1.0

force-tlsv11

Enforces the use of TLS protocol version 1.1

force-tlsv12

Enforces the use of TLS protocol version 1.2

no-sslv3

Disables support of SSLv3 protocol

no-tls-tickets

Disables support of TLS tickets, used to resume TLS sessions with compatible clients

no-tlsv10

Disables support of TLS 1.0 protocol

no-tlsv11

Disables support of TLS 1.1 protocol

no-tlsv12

Disables support of TLS 1.2 protocol

ssl

Enables a TLS/SSL endpoint on this listener in order to cipher/decipher the traffic.

strict-sni

The SSL/TLS negotiation is allowed only if the client provides a SNI that matches a certificate loaded by HAProxy. The default certificate is ignored in this case.

verify [none|optional|required]

Sets HAProxy's behavior regarding client side certificate:

  • none (default value) : client certificate is not requested.

  • optional: HAProxy requests a client certificate, and the TLS handshake is successful even if the client doesn't provide one.

  • required: HAProxy requests a client certificate, but the TLS handshake is aborted if the client doesn't provide one.

Define server directive settings on the backend

Directive

Description

ca-file <ca-file>

Designates the CA certificate to use to validate certificates provided by servers

ciphers

A string describing the list of cipher suite algorithms to use to get connected to the servers

Note

Mozilla offers a page of TLS recommended configurations for modern, intermediate, and old backward compatibility ciphers here: You can copy and paste the ones that suit your needs.

crl-file <crlfile>

Designates a PEM file from which HAProxy can load a certificate revocation list. The list is used to verify certificates provided by servers.

crt <pem-file>

Designates the file containing a client certificate and its associated private key. HAProxy will use it if the server asks for a client certificate.

force-sslv3

Enforces the use of SSL protocol version SSLv3.

Note

Not recommended on Internet because of the poodle vulnerability: https://poodle.io/

force-tlsv10

Enforces the use of TLS protocol version 1.0

force-tlsv11

Enforces the use of TLS protocol version 1.1

force-tlsv12

Enforces the use of TLS protocol version 1.2

no-sslv3

Disables support of SSLv3 protocol

no-tls-tickets

Disables support of TLS tickets, used to resume TLS sessions with compatible clients

no-tlsv10

Disables support of TLS 1.0 protocol

no-tlsv11

Disables support of TLS 1.1 protocol

no-tlsv12

Disables support of TLS 1.2 protocol

sni <sample>

Evaluates the sample fecth expression and uses the result as a string for the SNI TLS extension sent to the server.

ssl

Creates a TLS/SSL socket when connecting to this server to cipher/decipher the traffic

verify [none|required]

Sets HAProxy's behavior regarding the certificated presented by the server:

  • none: does not verify the certificate of the server

  • required (default value): the TLS handshake is aborted if the validation of the certificate presented by the server returns an error.

Note

The certificate of the server is validated using the server's ca-file and crl-file directive.

veryfyhost <hostname>

Sets a <hostname> to look for in the Subject and SubjectAlternateNames fields in the certificate from the server. If <hostname> is not found, then the TLS handshake is aborted.

Note

This only applies when verify required is configured.

Example TLS Configurations

Define Global Settings

The following are examples of settings available in the global section.

Disable SSLv3 everywhere:

global
        ssl-default-bind-options no-sslv3

Set a default cipher list to use:

global
ssl-default-bind-ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-
AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-
SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-
ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-
AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK

Disable validation of certificates presented by servers (because of self-signed certificates):

global
ssl-server-verify none

Force validation of certificates presented by servers:

global
ssl-server-verify required

Increase TLS session cache size and lifetime to avoid computing too many symmetric keys:

global
        tune.ssl.cachesize 100000
        tune.ssl.lifetime 600

Set up a TLS record to match a TCP segment size to improve client side rendering of content:

global
        tune.ssl.maxrecord 1460

Define Listener (frontend) Settings

The following are examples of settings available for the listener:

Enable SSL processing on a bind line:

frontend f_myapp
        bind 10.0.0.1:443 ssl crt mycrt

Anounce supported protocols using TLS NPN or ALPN extension:

frontend f_myapp
        bind 10.0.0.1:443 ssl crt mycrt alpn http/1.1,http/1.0

or:

frontend f_myapp
        bind 10.0.0.1:443 ssl crt mycrt npn http/1.1,http/1.0

Enable SSL processing on a bind line and make client certificate mandatory for the connection:

frontend f_myapp
        bind 10.0.0.1:443 ssl crt mycrt ca-file ./ca.crt verify required

Load multiple certificates over a single IP:

frontend f_myapp
        bind 10.0.0.1:443 ssl crt star.mydomain.com crt www.mydomain.net

Note

The first one is used by default when the client does not send any SNI, or the SNI sent does not match any loaded certificate.

Define Server Settings

The following are examples of settings available for the server:

Do not check the validity of a server certificate (can be dangerous):

backend b_myapp
        [...]
        server app1 10.0.0.1:443 ssl verify none

Use a company's internal CA to check a server certificate; also check the ssl-server-verify global option to force validation over all servers by default.

backend b_myapp
        [...]
        server app1 10.0.0.1:443 ssl verify required ca-file /etc/haproxy/myca.pem

Use a client certificate to get connected on a server; also check the ssl-server-verify global option to force validation over all servers by default.

backend b_myapp
        [...]
        server app1 10.0.0.1:443 ssl verify required ca-file /etc/haproxy/myca.pem crt /etc/haproxy/client.pem

Use the host header as SNI when opening a TLS connection on to a server:

backend b_myapp
        mode http
        [...]
        server app1 10.0.0.1:443 ssl sni req.hdr(Host)