Load Balancer Guide

    HAProxy Load Balancer

    Deploy HAProxy, the reliable high-performance TCP/HTTP load balancer, on RamNode VPS. Distribute traffic, ensure high availability, and scale your applications.

    Ubuntu/Debian
    HAProxy 2.8 LTS
    ⏱️ 25-35 minutes

    Prerequisites & VPS Selection

    Small Setup

    • • 512MB RAM
    • • 1 vCPU
    • • 2-3 backends

    Recommended

    • • 2GB RAM
    • • 2 vCPU
    • • 5-10 backends

    High Traffic

    • • 4GB+ RAM
    • • 4 vCPU
    • • 10+ backends

    💡 Tip: HAProxy is extremely efficient. A single core can handle 20,000+ concurrent connections. Scale up for SSL termination or many backends.

    2

    Install HAProxy

    Install HAProxy from the official repository for the latest stable version:

    Install HAProxy on Ubuntu/Debian
    # Update system packages
    sudo apt update && sudo apt upgrade -y
    
    # Add HAProxy official repository (for latest version)
    sudo apt install -y software-properties-common
    sudo add-apt-repository ppa:vbernat/haproxy-2.8 -y
    sudo apt update
    
    # Install HAProxy
    sudo apt install haproxy -y
    
    # Verify installation
    haproxy -v
    
    # Check service status
    sudo systemctl status haproxy

    For RHEL/AlmaLinux/Rocky Linux:

    Install HAProxy on RHEL-based systems
    # Install HAProxy
    sudo dnf install haproxy -y
    
    # Start and enable
    sudo systemctl start haproxy
    sudo systemctl enable haproxy
    3

    Basic Configuration

    HAProxy configuration is in /etc/haproxy/haproxy.cfg. Let's understand the structure:

    Backup and edit config
    # Backup original config
    sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.backup
    
    # Edit configuration
    sudo nano /etc/haproxy/haproxy.cfg
    /etc/haproxy/haproxy.cfg - Basic structure
    #---------------------------------------------------------------------
    # Global settings
    #---------------------------------------------------------------------
    global
        log /dev/log local0
        log /dev/log local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin
        stats timeout 30s
        user haproxy
        group haproxy
        daemon
    
        # SSL settings
        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
    
    #---------------------------------------------------------------------
    # Default settings
    #---------------------------------------------------------------------
    defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http
    4

    Load Balancing Configuration

    Configure frontend (incoming) and backend (servers) for load balancing:

    HTTP Load Balancing
    #---------------------------------------------------------------------
    # Frontend: Accept incoming connections
    #---------------------------------------------------------------------
    frontend http_front
        bind *:80
        
        # Default backend
        default_backend http_back
        
        # Route based on domain (optional)
        acl is_api hdr(host) -i api.example.com
        acl is_app hdr(host) -i app.example.com
        
        use_backend api_servers if is_api
        use_backend app_servers if is_app
    
    #---------------------------------------------------------------------
    # Backend: Web servers pool
    #---------------------------------------------------------------------
    backend http_back
        balance roundrobin
        option httpchk GET /health
        http-check expect status 200
        
        # Backend servers
        server web1 192.168.1.10:80 check
        server web2 192.168.1.11:80 check
        server web3 192.168.1.12:80 check backup
    
    backend api_servers
        balance leastconn
        option httpchk GET /api/health
        
        server api1 192.168.1.20:3000 check
        server api2 192.168.1.21:3000 check
    
    backend app_servers
        balance roundrobin
        
        server app1 192.168.1.30:8080 check
        server app2 192.168.1.31:8080 check

    Load Balancing Algorithms

    roundrobin

    Distributes requests evenly across servers in order. Best for similar server capacities.

    leastconn

    Sends to server with fewest connections. Best for long-running connections.

    source

    Hashes client IP for consistent routing. Simple sticky sessions.

    uri

    Hashes URI for consistent routing. Good for caching layers.

    5

    Health Checks

    Configure health checks to automatically remove unhealthy servers:

    Advanced health check configuration
    backend web_servers
        balance roundrobin
        
        # HTTP health check
        option httpchk GET /health HTTP/1.1\r\nHost:\ localhost
        http-check expect status 200
        
        # Health check intervals
        default-server inter 3s fall 3 rise 2
        
        # Server definitions with health check options
        server web1 192.168.1.10:80 check inter 2s fall 3 rise 2 weight 100
        server web2 192.168.1.11:80 check inter 2s fall 3 rise 2 weight 100
        server web3 192.168.1.12:80 check inter 2s fall 3 rise 2 weight 50
    
    # TCP health check (for non-HTTP services)
    backend mysql_servers
        mode tcp
        balance roundrobin
        option mysql-check user haproxy
        
        server mysql1 192.168.1.50:3306 check
        server mysql2 192.168.1.51:3306 check backup
    Health Check Parameters:
    • inter: Interval between checks (default 2s)
    • fall: Failed checks before marking down (default 3)
    • rise: Successful checks before marking up (default 2)
    • weight: Server weight for load distribution (1-256)
    6

    SSL Termination

    Configure HAProxy to handle SSL certificates:

    Obtain SSL certificate
    # Install Certbot
    sudo apt install certbot -y
    
    # Get certificate (standalone mode)
    sudo certbot certonly --standalone -d example.com -d www.example.com
    
    # Create combined PEM file for HAProxy
    sudo cat /etc/letsencrypt/live/example.com/fullchain.pem \
        /etc/letsencrypt/live/example.com/privkey.pem \
        | sudo tee /etc/haproxy/certs/example.com.pem
    
    # Set permissions
    sudo chmod 600 /etc/haproxy/certs/example.com.pem
    SSL frontend configuration
    #---------------------------------------------------------------------
    # HTTPS Frontend with SSL termination
    #---------------------------------------------------------------------
    frontend https_front
        bind *:443 ssl crt /etc/haproxy/certs/example.com.pem alpn h2,http/1.1
        
        # Security headers
        http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains"
        http-response set-header X-Frame-Options "SAMEORIGIN"
        http-response set-header X-Content-Type-Options "nosniff"
        
        default_backend http_back
    
    # Redirect HTTP to HTTPS
    frontend http_front
        bind *:80
        
        # ACME challenge for Let's Encrypt renewal
        acl is_acme path_beg /.well-known/acme-challenge/
        use_backend acme_backend if is_acme
        
        # Redirect all other traffic to HTTPS
        redirect scheme https code 301 if !is_acme
    
    backend acme_backend
        server acme 127.0.0.1:8888

    Auto-Renew SSL with HAProxy

    Create renewal script
    sudo nano /etc/letsencrypt/renewal-hooks/post/haproxy.sh
    /etc/letsencrypt/renewal-hooks/post/haproxy.sh
    #!/bin/bash
    DOMAIN="example.com"
    cat /etc/letsencrypt/live/$DOMAIN/fullchain.pem \
        /etc/letsencrypt/live/$DOMAIN/privkey.pem \
        > /etc/haproxy/certs/$DOMAIN.pem
    systemctl reload haproxy
    Make executable
    sudo chmod +x /etc/letsencrypt/renewal-hooks/post/haproxy.sh
    7

    Sticky Sessions

    Ensure users stay on the same backend server:

    Cookie-based sticky sessions
    backend app_servers
        balance roundrobin
        
        # Cookie-based persistence
        cookie SERVERID insert indirect nocache
        
        server app1 192.168.1.30:8080 check cookie app1
        server app2 192.168.1.31:8080 check cookie app2
        server app3 192.168.1.32:8080 check cookie app3
    IP-based sticky sessions
    backend app_servers
        # Use source IP for persistence
        balance source
        hash-type consistent
        
        server app1 192.168.1.30:8080 check
        server app2 192.168.1.31:8080 check
    Stick table persistence
    backend app_servers
        balance roundrobin
        
        # Stick table for session persistence
        stick-table type ip size 200k expire 30m
        stick on src
        
        server app1 192.168.1.30:8080 check
        server app2 192.168.1.31:8080 check
    8

    Rate Limiting

    Protect your servers from abuse with rate limiting:

    Rate limiting configuration
    frontend http_front
        bind *:80
        
        # Stick table for rate limiting
        stick-table type ip size 100k expire 30s store http_req_rate(10s)
        
        # Track requests per IP
        http-request track-sc0 src
        
        # Deny if more than 100 requests in 10 seconds
        http-request deny deny_status 429 if { sc_http_req_rate(0) gt 100 }
        
        # Add rate limit headers
        http-response set-header X-RateLimit-Limit 100
        http-response set-header X-RateLimit-Remaining %[sc_http_req_rate(0),sub(100)]
        
        default_backend http_back
    
    # Connection rate limiting
    frontend http_front_connlimit
        bind *:80
        
        # Limit concurrent connections per IP
        stick-table type ip size 100k expire 30s store conn_cur
        http-request track-sc0 src
        http-request deny deny_status 429 if { sc_conn_cur(0) gt 50 }
    9

    Stats Dashboard

    Enable the built-in statistics dashboard:

    Stats configuration
    #---------------------------------------------------------------------
    # Statistics Dashboard
    #---------------------------------------------------------------------
    frontend stats
        bind *:8404
        mode http
        stats enable
        stats uri /stats
        stats refresh 10s
        stats admin if LOCALHOST
        
        # Authentication (strongly recommended)
        stats auth admin:your_secure_password
        
        # Hide HAProxy version
        stats hide-version
    Restart HAProxy
    # Validate configuration
    sudo haproxy -c -f /etc/haproxy/haproxy.cfg
    
    # Restart service
    sudo systemctl restart haproxy

    ✅ Success! Access stats at http://YOUR_IP:8404/stats

    ⚠️ Security: Restrict stats access to trusted IPs or use a firewall. Never expose stats publicly without authentication.

    10

    Logging Configuration

    Configure rsyslog for HAProxy
    sudo nano /etc/rsyslog.d/49-haproxy.conf
    /etc/rsyslog.d/49-haproxy.conf
    # Create an additional socket in haproxy's chroot
    $AddUnixListenSocket /var/lib/haproxy/dev/log
    
    # Send HAProxy messages to a dedicated logfile
    if $programname startswith 'haproxy' then /var/log/haproxy.log
    &stop
    Restart rsyslog and create log directory
    # Create log socket directory
    sudo mkdir -p /var/lib/haproxy/dev
    
    # Restart rsyslog
    sudo systemctl restart rsyslog
    
    # View logs
    sudo tail -f /var/log/haproxy.log

    Custom Log Format

    Custom logging in haproxy.cfg
    defaults
        # Custom log format with timing info
        log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r"
        
        # Separate log for errors
        option log-separate-errors
    11

    High Availability Setup

    Set up HAProxy with Keepalived for automatic failover:

    Install Keepalived
    sudo apt install keepalived -y
    Master node - /etc/keepalived/keepalived.conf
    vrrp_script chk_haproxy {
        script "killall -0 haproxy"
        interval 2
        weight 2
    }
    
    vrrp_instance VI_1 {
        state MASTER
        interface eth0
        virtual_router_id 51
        priority 101
        advert_int 1
        
        authentication {
            auth_type PASS
            auth_pass your_secret_password
        }
        
        virtual_ipaddress {
            192.168.1.100/24
        }
        
        track_script {
            chk_haproxy
        }
    }
    Backup node - /etc/keepalived/keepalived.conf
    vrrp_script chk_haproxy {
        script "killall -0 haproxy"
        interval 2
        weight 2
    }
    
    vrrp_instance VI_1 {
        state BACKUP
        interface eth0
        virtual_router_id 51
        priority 100
        advert_int 1
        
        authentication {
            auth_type PASS
            auth_pass your_secret_password
        }
        
        virtual_ipaddress {
            192.168.1.100/24
        }
        
        track_script {
            chk_haproxy
        }
    }
    Start Keepalived
    sudo systemctl start keepalived
    sudo systemctl enable keepalived
    
    # Check virtual IP
    ip addr show eth0
    12

    Troubleshooting

    Validate Configuration

    Test configuration
    # Check syntax
    sudo haproxy -c -f /etc/haproxy/haproxy.cfg
    
    # Check with verbose output
    sudo haproxy -c -V -f /etc/haproxy/haproxy.cfg

    Debug Mode

    Run HAProxy in debug mode
    # Stop service first
    sudo systemctl stop haproxy
    
    # Run in foreground with debug
    sudo haproxy -d -f /etc/haproxy/haproxy.cfg

    Common Issues

    Check listening ports
    # Check if HAProxy is listening
    sudo ss -tlnp | grep haproxy
    
    # Check for port conflicts
    sudo lsof -i :80
    sudo lsof -i :443
    Check backend connectivity
    # Test backend directly
    curl -v http://192.168.1.10:80/health
    
    # Check HAProxy logs
    sudo tail -100 /var/log/haproxy.log | grep -i error

    Runtime Commands

    HAProxy runtime management
    # Show server status
    echo "show stat" | sudo socat stdio /run/haproxy/admin.sock
    
    # Disable a server
    echo "disable server http_back/web1" | sudo socat stdio /run/haproxy/admin.sock
    
    # Enable a server
    echo "enable server http_back/web1" | sudo socat stdio /run/haproxy/admin.sock
    
    # Show current sessions
    echo "show sess" | sudo socat stdio /run/haproxy/admin.sock
    
    # Graceful reload
    sudo systemctl reload haproxy

    Congratulations!

    You've successfully deployed HAProxy load balancer on your RamNode VPS. Your traffic is now being distributed across backend servers.

    Security Best Practices

    • Use strong SSL ciphers - Configure TLS 1.2+ with modern cipher suites
    • Protect stats page - Use authentication and IP restrictions
    • Enable rate limiting - Protect against DDoS and abuse
    • Keep HAProxy updated - Apply security patches promptly
    • Use firewall rules - Only allow necessary ports
    • Monitor logs - Watch for suspicious patterns