Install and configure HAProxy for high availability load balancing

Intermediate 45 min Mar 31, 2026 23 views
Ubuntu 24.04 Ubuntu 22.04 Debian 12 AlmaLinux 9 Rocky Linux 9 Fedora 41

Set up HAProxy with SSL termination, keepalived for high availability, and comprehensive health checks to distribute traffic across multiple backend servers with automatic failover.

Prerequisites

  • Root or sudo access
  • Multiple backend servers for load balancing
  • Domain name for SSL certificate
  • Basic understanding of networking concepts

What this solves

HAProxy provides enterprise-grade load balancing and high availability for web applications by distributing incoming requests across multiple backend servers. This tutorial covers setting up HAProxy with SSL termination, health checks, and keepalived for automatic failover, ensuring your services remain available even when individual servers fail.

Step-by-step installation

Update system packages

Start by updating your package manager to ensure you get the latest HAProxy version with security patches.

sudo apt update && sudo apt upgrade -y
sudo dnf update -y

Install HAProxy and keepalived

Install HAProxy for load balancing and keepalived for high availability clustering. These packages work together to provide automatic failover.

sudo apt install -y haproxy keepalived certbot
sudo dnf install -y haproxy keepalived certbot

Create HAProxy directories and backup original config

Set up the directory structure for SSL certificates and create a backup of the default configuration file.

sudo mkdir -p /etc/haproxy/certs /var/lib/haproxy/stats
sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.backup
sudo chown -R haproxy:haproxy /var/lib/haproxy

Configure HAProxy main configuration

Create the main HAProxy configuration with global settings, SSL termination, and backend server definitions.

global
    log         127.0.0.1:514 local0
    chroot      /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user        haproxy
    group       haproxy
    daemon
    
    # SSL Configuration
    ca-base /etc/ssl/certs
    crt-base /etc/ssl/private
    
    # SSL Security
    ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
    ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384
    ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets

defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option                  http-server-close
    option                  forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

Statistics interface

frontend stats bind *:8404 stats enable stats uri /stats stats refresh 30s stats admin if TRUE

HTTP Frontend (redirect to HTTPS)

frontend http_frontend bind *:80 redirect scheme https code 301 if !{ ssl_fc }

HTTPS Frontend

frontend https_frontend bind *:443 ssl crt /etc/haproxy/certs/example.com.pem # Security headers http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" http-response set-header X-Frame-Options "DENY" http-response set-header X-Content-Type-Options "nosniff" # Default backend default_backend web_servers

Backend server pool

backend web_servers balance roundrobin option httpchk GET /health # Backend servers with health checks server web1 203.0.113.10:80 check inter 5000 fall 3 rise 2 server web2 203.0.113.11:80 check inter 5000 fall 3 rise 2 server web3 203.0.113.12:80 check inter 5000 fall 3 rise 2

Generate SSL certificate with Let's Encrypt

Create an SSL certificate for your domain and prepare it for HAProxy's SSL termination.

sudo certbot certonly --standalone -d example.com -d www.example.com
sudo cat /etc/letsencrypt/live/example.com/fullchain.pem /etc/letsencrypt/live/example.com/privkey.pem > /tmp/example.com.pem
sudo mv /tmp/example.com.pem /etc/haproxy/certs/
sudo chmod 600 /etc/haproxy/certs/example.com.pem
sudo chown haproxy:haproxy /etc/haproxy/certs/example.com.pem

Configure keepalived for high availability

Set up keepalived on the primary load balancer node to manage virtual IP failover.

vrrp_script chk_haproxy {
    script "/bin/kill -0 cat /var/run/haproxy.pid"
    interval 2
    weight 2
    fall 3
    rise 2
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 101
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass changeme123
    }
    virtual_ipaddress {
        203.0.113.100/24
    }
    track_script {
        chk_haproxy
    }
}

Configure rsyslog for HAProxy logging

Enable UDP logging in rsyslog to capture HAProxy access logs and errors.

$ModLoad imudp
$UDPServerRun 514
$UDPServerAddress 127.0.0.1

HAProxy log files

local0.* /var/log/haproxy.log & stop

Enable and start services

Start HAProxy and keepalived services and enable them to start automatically on boot.

sudo systemctl restart rsyslog
sudo systemctl enable --now haproxy
sudo systemctl enable --now keepalived
sudo systemctl status haproxy keepalived

Configure firewall rules

Open the necessary ports for HTTP, HTTPS, and HAProxy statistics interface.

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 8404/tcp
sudo ufw allow 112/tcp
sudo ufw reload
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --permanent --add-port=8404/tcp
sudo firewall-cmd --permanent --add-port=112/tcp
sudo firewall-cmd --reload

Advanced configuration

Configure different load balancing algorithms

HAProxy supports multiple load balancing methods. Here's how to configure different algorithms for specific use cases.

# Least connections for long-running requests
backend api_servers
    balance leastconn
    option httpchk GET /api/health
    server api1 203.0.113.20:8080 check
    server api2 203.0.113.21:8080 check

Source IP hash for session persistence

backend app_servers balance source option httpchk GET /status server app1 203.0.113.30:3000 check server app2 203.0.113.31:3000 check

URI hash for cache optimization

backend cache_servers balance uri option httpchk GET /ping server cache1 203.0.113.40:6379 check server cache2 203.0.113.41:6379 check

Setup SSL certificate auto-renewal

Create a script to automatically renew Let's Encrypt certificates and reload HAProxy.

#!/bin/bash
DOMAIN="example.com"
cat /etc/letsencrypt/live/$DOMAIN/fullchain.pem /etc/letsencrypt/live/$DOMAIN/privkey.pem > /etc/haproxy/certs/$DOMAIN.pem
chmod 600 /etc/haproxy/certs/$DOMAIN.pem
chown haproxy:haproxy /etc/haproxy/certs/$DOMAIN.pem
systemctl reload haproxy
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/haproxy-reload.sh

Configure health check monitoring

Set up comprehensive health checks with custom endpoints and failure thresholds.

backend web_servers_enhanced
    balance roundrobin
    
    # Custom health check with headers
    option httpchk GET /health HTTP/1.1\r\nHost:\ example.com
    http-check expect status 200
    
    # Advanced server configuration
    server web1 203.0.113.10:80 check inter 3000 fall 2 rise 3 maxconn 100 weight 100
    server web2 203.0.113.11:80 check inter 3000 fall 2 rise 3 maxconn 100 weight 100
    server web3 203.0.113.12:80 check inter 3000 fall 2 rise 3 maxconn 50 weight 50 backup

Performance tuning and security

Optimize HAProxy performance

Configure system-level optimizations for high-traffic environments.

haproxy soft nofile 65536
haproxy hard nofile 65536
net.core.somaxconn = 65536
net.ipv4.tcp_max_syn_backlog = 65536
net.core.netdev_max_backlog = 5000
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 120
sudo sysctl -p /etc/sysctl.d/99-haproxy.conf

Configure rate limiting and DDoS protection

Add rate limiting to protect backend servers from abuse and DDoS attacks.

# Add to frontend https_frontend section
frontend https_frontend
    bind *:443 ssl crt /etc/haproxy/certs/example.com.pem
    
    # Rate limiting - 20 requests per 10 seconds per IP
    stick-table type ip size 100k expire 30s store http_req_rate(10s)
    http-request track-sc0 src
    http-request deny if { sc_http_req_rate(0) gt 20 }
    
    # Block malicious patterns
    http-request deny if { path_beg -i /admin } && !{ src 203.0.113.0/24 }
    http-request deny if { hdr_sub(user-agent) -i bot scanner }
    
    default_backend web_servers

Configure secondary HAProxy node

Setup backup load balancer

Configure a second HAProxy node for true high availability with automatic failover.

# Configuration for secondary node
vrrp_script chk_haproxy {
    script "/bin/kill -0 cat /var/run/haproxy.pid"
    interval 2
    weight 2
    fall 3
    rise 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass changeme123
    }
    virtual_ipaddress {
        203.0.113.100/24
    }
    track_script {
        chk_haproxy
    }
}

Verify your setup

sudo systemctl status haproxy keepalived
haproxy -f /etc/haproxy/haproxy.cfg -c
sudo ss -tlnp | grep :443
curl -I https://example.com
ip addr show | grep 203.0.113.100

Access the HAProxy statistics page at http://your-server-ip:8404/stats to monitor backend server health and traffic distribution. You can also integrate this with Grafana and Prometheus for comprehensive monitoring.

Common issues

SymptomCauseFix
503 Service UnavailableAll backend servers are downCheck backend server health: curl -I http://backend-ip/health
SSL certificate errorsWrong certificate formatEnsure PEM file contains both cert and key: openssl x509 -in cert.pem -text -noout
Keepalived not failing overVRRP traffic blockedAllow VRRP protocol: sudo ufw allow 112/tcp
High memory usageToo many concurrent connectionsTune maxconn in global and backend sections
Backend servers marked DOWNHealth check endpoint missingCreate /health endpoint on backend servers
Statistics page not accessibleFirewall blocking port 8404Allow stats port: sudo ufw allow 8404/tcp

Next steps

Automated install script

Run this to automate the entire setup

#haproxy #load-balancer #high-availability #ssl-termination #keepalived

Need help?

Don't want to manage this yourself?

We handle infrastructure for businesses that depend on uptime. From initial setup to ongoing operations.

Talk to an engineer