By design, HAProxy is a proxy, which means that it maintains two types of connections:

  • Client <==> HAProxy (front end)

  • HAProxy (back end) <==> Server

  • With this design, HAProxy can use different protocols on each type of connection.

From a SSL/TLS point of view, this allows the following design:

SSL/TLS pass-through

In this mode, HAProxy does not decipher the traffic. It simply opens a TCP tunnel between the client and the server to let them negotiate and handle the TLS traffic.

The diagram below illustrates this layout:

HAProxy SSL/TLS pass-through

Figure: HAProxy SSL/TLS pass-through

Here, HAProxy simply runs in mode tcp. The sample fetch methods that apply to this mode are those whose names starts with req.ssl_.

Simple HTTPs service load-balancing:

frontend ft_myapp
  bind 10.0.0.1:443
  mode tcp
  [...]
  default_backend bk_myapp

backend bk_myapp
  mode tcp
  [...]
  server app1 10.0.0.11:443 check
  server app2 10.0.0.12:443 check

Deny connection if the client forces using SSLv3:

frontend ft_myapp
  bind 10.0.0.1:443
  mode tcp
  acl sslv3 req.ssl_ver 3
  tcp-request inspect-delay 2s
  tcp-request content reject if sslv3
  [...]

Choose a farm based on the information found in the TLS SNI extension. If there is no SNI sent, then deny the connection. Resend the SNI information on the server side:

frontend ft_global
  bind 10.0.0.1:443
  mode tcp
  [...]
  acl webmail  req.ssl_sni -i webmail.domain.com
  acl extranet req.ssl_sni -i extranet.domain.com
  tcp-request inspect-delay 2s
  tcp-request content reject if !webmail !extranet
  use_backend bk_webmail if webmail
  use_backend bk_extranet if extranet
backend bk_webmail
  mode tcp
  [...]
  server mail1 10.0.0.11:443 check sni req.ssl_sni
  server mail2 10.0.0.12:443 check sni req.ssl_sni

backend bk_extranet
  mode tcp
  [...]
  server extranet1 10.0.0.13:443 check sni req.ssl_sni
  server extranet2 10.0.0.14:443 check sni req.ssl_sni

SSL/TLS bridging or re-encryption

In this mode, HAProxy deciphers the traffic on the client side and re-encrypts it on the server side. It can access the content of the request and the response and perform advanced processing over the traffic.

The diagram below illustrates this layout:

HAProxy SSL/TLS bridging or re-encryption

Figure: HAProxy SSL/TLS bridging or re-encryption

In this mode, HAProxy can run either in mode tcp or mode http and the keywords ssl and crt must be set up on the front end's bind line and at least ssl on the back end's server line (crt is available, but optional).

The sample fetch methods which that apply to this mode are those whose names start with ssl_c, ssl_f ssl_fc and ssl_bc.

Simple TLS bridging for an HTTPs application to perform cookie persistence; use host header as SNI information:

frontend ft_myapp
  bind 10.0.0.1:443 ssl crt myapp
  mode http
  [...]
  default_backend bk_myapp

backend bk_myapp
  mode http
  [...]
  cookie MYAPP insert indirect nocache
  server app1 10.0.0.11:443 ssl check cookie app1 sni req.hdr(Host)
  server app2 10.0.0.12:443 ssl check cookie app2 sni req.hdr(Host)

Use HAProxy to export a weak SSLv3 service on internet over a strong TLS1.2 protocol:

frontend ft_public
  bind 10.0.0.1:443 ssl crt myapp force-tlsv12
  mode tcp
  [...]
  default_backend bk_internal
backend bk_internal
  mode tcp
  [...]
  server sslv3server 10.0.0.11:443 check

SSL/TLS offloading

In this mode, HAProxy deciphers the traffic on the client side and gets connected in clear to the server.

The diagram below illustrates this layout:

HAProxy SSL/TLS offloading

Figure: HAProxy SSL/TLS offloading

In this mode, HAProxy can run either in mode tcp or mode http and the keywords ssl and crt must be set up on the front end's bind line.

The sample fetch methods that apply to this mode are those whose name start with ssl_c, ssl_f ssl_fc and ssl_bc.

Handle both HTTP and HTTPs on the client side, offloading TLS. Create a HTTP header X-Forwarded-Protocol containing the name of the protocol used on the client side:

frontend ft_myapp
  bind 10.0.0.1:80 name http
  bind 10.0.0.1:443 name https ssl crt myapp
  mode http
  acl http  ssl_fc,not
  acl https ssl_fc
  http-request set-header X-Forwarded-Protocol http if http
  http-request set-header X-Forwarded-Protocol https if https
  [...]
  default_backend bk_myapp

backend bk_myapp
  mode http
  [...]
  server app1 10.0.0.11:80 check
  server app2 10.0.0.12:80 check

SSL/TLS encryption

In this mode, HAProxy gets the traffic in clear on the client side and uses TLS to get connected to the server.

The diagram below illustrates this layout:

HAProxy SSL/TLS encryption

Figure: HAProxy SSL/TLS encryption

In this mode, HAProxy can run either in mode tcp or mode http and the keyword ssl must be set up on the back end's server line.

The sample fetch methods that apply to this mode are those whose names start with ssl_b.

Force TLS when reaching backup servers hosted in a third party data center and reachable only through internet:

frontend ft_internal
  bind 10.0.0.1:80 name http
  mode http
  [...]
  acl internal_ko nbsrv(bk_internal) eq 0
  use_backend bk_failover if internal_ko
  default_backend bk_internal

backend bk_internal
  mode http
  [...]
  server app1 10.0.0.11:80 check
  server app2 10.0.0.12:80 check

backend bk_failover
  mode http
  [...]
  server app1 90.a.b.c:443 check ssl
  server app2 90.a.b.d:443 check ssl