Basic HAProxy Configuration on Debian
Table of Contents
Setup #
My setup consists of a Debian 11 server with HAProxy, and 2 Apache web servers running on Alpine linux:
- Debian: 192.168.100.121
- Alpine 1: 192.168.100.120
- Alpine 2: 192.168.100.130
The webservers are hosting the following contents on port 80:
#Alpine 1
Node 1: 192.168.100.120
#Alpine 2
Node 2: 192.168.100.130
Install and Enable HAProxy #
apt install haproxy -y
systemctl enable --now haproxy
HAProxy configuration #
HAProxy is configured with mode http
by default, including timeout settings. My setup:
# frontend
frontend apache_alpine_front
bind *:80
default_backend apache_alpine_backend_servers
option forwardfor
# backend
backend apache_alpine_backend_servers
balance roundrobin
server alpine 192.168.100.120:80
server alpine2 192.168.100.130:80
-
frontend: Where requests will be received. It’s listening on all IPs on port 80.
-
option forwardfor: Adds the
X-Forwarded-For
header in all requests to the backend. -
backend: Servers that will process the requests.
-
balance: Defines how the requests will be distributed.
Restart haproxy
, and verify the configuration by accessing the frontend:
MacBook-Pro:~ kavish$ for i in `seq 1 7`; do curl 192.168.100.121; done
Node 1: 192.168.100.120
Node 2: 192.168.100.130
Node 1: 192.168.100.120
Node 2: 192.168.100.130
Node 1: 192.168.100.120
Node 2: 192.168.100.130
Node 1: 192.168.100.120
Note: make sure your webservers are up and running.
TLS/SSL Termination #
Communication from the client to the proxy will be encrypted, and communication from HAProxy to the backend will be plain HTTP. HAProxy require the private key and certificate to be in the same file:
$ cd /etc/ssl/private
$ mkcert localhost
$ mv localhost.pem
$ cat localhost-key.pem localhost.pem > localhost-haproxy.pem
$ rm -f localhost-cert.pem localhost-key.pem
$ chmod 640 localhost-haproxy.pem
Configure the frontend section:
# Define frontend
frontend apache_alpine_front
bind *:443 ssl crt /etc/ssl/private/localhost-haproxy.pem
http-request redirect scheme https unless { ssl_fc }
default_backend apache_alpine_backend_servers
option forwardfor
Force TLS #
On a local network, users won’t include https://
. To redirect all traffic over port 443, use the http-request redirect scheme
:
# Define frontend
frontend apache_alpine_front
bind *:443 ssl crt /etc/ssl/private/localhost-haproxy.pem
http-request redirect scheme https unless { ssl_fc }
default_backend apache_alpine_backend_servers
option forwardfor
Implement TLS/SSL for backend servers #
If for some reason you want to encrypt the comunication of HAProxy to the backend servers, replace 80 with 443, and the ssl
keyword:
# Define backend
backend apache_alpine_backend_servers
balance roundrobin
server alpine 192.168.100.120:80
server alpine2 192.168.100.130:443 ssl
For Self Signed Certificates #
It’s not neccesarry to verify SSL certificates for local servers. Unless you have the CA certificate, just use verify none
:
# Define backend
backend apache_alpine_backend_servers
balance roundrobin
server alpine 192.168.100.120:80
server alpine2 192.168.100.130:443 ssl verify none
Health checks #
By default, HAProxy will route traffic to webservers on your backend, even if the servers are offline. Only servers that respond with a 200 status code should remain in the backend queue. To perform health checks, you should use option httpchk
, and check
directives in the backend
section:
# Define backend
backend apache_alpine_backend_servers
option httpchk
balance roundrobin
server alpine 192.168.100.120:80 check
server alpine2 192.168.100.130:443 ssl verify none check
Specific Health Checks #
The check can be more specific. For example, perform a GET request on /
for each server every 20 seconds:
# Define backend
backend apache_alpine_backend_servers
option httpchk GET /
default-server inter 20s
balance roundrobin
server alpine 192.168.100.120:80 check
server alpine2 192.168.100.130:443 ssl verify none check
Or perform the check every 20s, except for alpine2, which a check will be perform every 10s:
# Define backend
backend apache_alpine_backend_servers
option httpchk GET /
default-server 20s
balance roundrobin
server alpine 192.168.100.120:80 check
server alpine2 192.168.100.130:443 ssl verify none check inter 10000
More examples can be found here.
Server Stats #
You can enable the global stats page, by appending the following in your configuration file:
listen stats
bind :8000
mode http
stats enable
stats hide-version
stats uri /
stats admin if TRUE
Modify your firewall to allow the specified port, and browse to yoursite:8000
. Stats can be enabled or configured for specific frontend/backend
sections. You can read more about it here.
Be the change that you wish to see in the world.”
― Mahatma Gandhi