HAProxy can handle TLS termination, meaning it decrypts incoming HTTPS traffic before forwarding it to your backend servers. This offloads the computationally expensive SSL/TLS handshake and encryption/decryption process from your application servers, allowing them to focus on serving content.
Let’s see HAProxy in action terminating TLS. Imagine you have an Nginx server running on 192.168.1.100:80 that serves your website. You want to expose this via HTTPS on port 443 using HAProxy, with a certificate for example.com.
Here’s a simplified HAProxy configuration snippet:
frontend http_in
bind *:443 ssl crt /etc/haproxy/certs/example.com.pem
mode http
default_backend webservers
backend webservers
mode http
server web1 192.168.1.100:80 check
In this setup:
frontend http_in: This section defines how HAProxy listens for incoming connections.bind *:443 ssl crt /etc/haproxy/certs/example.com.pem: This is the core of TLS termination. HAProxy binds to all interfaces (*) on port443. Thessldirective enables TLS, andcrt /etc/haproxy/certs/example.com.pempoints to the PEM-encoded file containing both the private key and the certificate chain forexample.com. HAProxy will use this to perform the TLS handshake with clients.mode http: Specifies that this frontend will handle HTTP traffic.default_backend webservers: Any traffic hitting this frontend will be directed to thewebserversbackend.backend webservers: This section defines the pool of servers that will handle the actual application logic.server web1 192.168.1.100:80 check: This declares a backend server namedweb1listening on192.168.1.100on port80. Thecheckdirective tells HAProxy to monitor the health of this server.
When a client connects to https://example.com on port 443, HAProxy intercepts the request. It performs the TLS handshake using the specified certificate and private key. Once the TLS connection is established and the HTTP request is decrypted, HAProxy forwards the plain HTTP request to the webservers backend. The backend server (Nginx in this case) receives an unencrypted HTTP request on port 80 and responds accordingly. HAProxy then takes the HTTP response, re-encrypts it using TLS, and sends it back to the client.
The primary problem HAProxy TLS termination solves is the resource overhead on application servers. SSL/TLS operations are CPU-intensive. By offloading this to HAProxy, your application servers can dedicate their CPU cycles to application logic and content delivery, leading to better performance and scalability. It also simplifies certificate management; you only need to manage certificates on HAProxy, not on every single backend server. Furthermore, it allows you to use older or less capable backend servers that might not efficiently handle TLS themselves.
One common misconception is that once HAProxy terminates TLS, the traffic to the backend is inherently insecure. This is only true if you do not take steps to secure the internal network. HAProxy can be configured to re-encrypt traffic to the backend using SSL/TLS itself, creating an end-to-end encrypted tunnel. This is achieved by specifying ssl on the server line within the backend configuration and providing a client certificate if required by the backend. For instance, to re-encrypt to 192.168.1.100:443 with a CA certificate for verification:
backend webservers
mode http
server web1 192.168.1.100:443 ssl verify required ca-file /etc/haproxy/certs/internal-ca.pem check
This ensures that even if the network between HAProxy and the backend is compromised, the traffic remains encrypted.
The next logical step after mastering TLS termination is understanding how HAProxy can perform HTTP header manipulation and load balancing algorithms to optimize traffic distribution to your backend services.