How to configure HAProxy load balancer on Linux

How to Configure HAProxy Load Balancer on Linux HAProxy (High Availability Proxy) is one of the most popular open-source load balancers and proxy servers available today. It provides high availability, load balancing, and proxying for TCP and HTTP-based applications. This comprehensive guide will walk you through the complete process of installing, configuring, and optimizing HAProxy on Linux systems, from basic setup to advanced configurations. Table of Contents 1. [Introduction to HAProxy](#introduction-to-haproxy) 2. [Prerequisites and System Requirements](#prerequisites-and-system-requirements) 3. [Installing HAProxy on Linux](#installing-haproxy-on-linux) 4. [Understanding HAProxy Configuration](#understanding-haproxy-configuration) 5. [Basic Load Balancer Configuration](#basic-load-balancer-configuration) 6. [Advanced Configuration Options](#advanced-configuration-options) 7. [SSL/TLS Configuration](#ssltls-configuration) 8. [Health Checks and Monitoring](#health-checks-and-monitoring) 9. [Testing Your Configuration](#testing-your-configuration) 10. [Troubleshooting Common Issues](#troubleshooting-common-issues) 11. [Best Practices and Security](#best-practices-and-security) 12. [Performance Optimization](#performance-optimization) 13. [Conclusion](#conclusion) Introduction to HAProxy HAProxy stands for High Availability Proxy and serves as a reliable, high-performance TCP/HTTP load balancer. It distributes incoming requests across multiple backend servers, ensuring optimal resource utilization and preventing any single server from becoming overwhelmed. HAProxy is widely used by major companies and organizations worldwide due to its stability, performance, and extensive feature set. Key features of HAProxy include: - Load balancing algorithms: Round-robin, least connections, source IP hashing, and more - Health checking: Automatic detection and removal of failed servers - SSL termination: Handle SSL/TLS encryption and decryption - Session persistence: Maintain user sessions with specific backend servers - Advanced routing: Route requests based on various criteria - Real-time statistics: Built-in web interface for monitoring - High availability: Support for failover and redundancy Prerequisites and System Requirements Before installing and configuring HAProxy, ensure your system meets the following requirements: System Requirements - Operating System: Linux distribution (Ubuntu 18.04+, CentOS 7+, RHEL 7+, Debian 9+) - RAM: Minimum 1GB, recommended 2GB or more - CPU: Modern multi-core processor - Disk Space: At least 500MB free space - Network: Stable network connectivity Required Privileges - Root or sudo access to the system - Ability to modify system configuration files - Permission to install packages and manage services Backend Servers - At least two backend servers to load balance - Backend servers should be accessible from the HAProxy server - Applications running on backend servers (web servers, application servers, etc.) Installing HAProxy on Linux Installing on Ubuntu/Debian Update your package repository and install HAProxy: ```bash Update package list sudo apt update Install HAProxy sudo apt install haproxy -y Verify installation haproxy -v ``` Installing on CentOS/RHEL For CentOS/RHEL systems: ```bash Install EPEL repository (if not already installed) sudo yum install epel-release -y Install HAProxy sudo yum install haproxy -y For CentOS 8/RHEL 8, use dnf sudo dnf install haproxy -y Verify installation haproxy -v ``` Installing from Source (Advanced) For the latest features or custom compilation: ```bash Install development tools sudo apt install build-essential libssl-dev libpcre3-dev zlib1g-dev Download HAProxy source wget http://www.haproxy.org/download/2.8/src/haproxy-2.8.0.tar.gz tar -xzf haproxy-2.8.0.tar.gz cd haproxy-2.8.0 Compile with SSL support make TARGET=linux-glibc USE_OPENSSL=1 USE_ZLIB=1 USE_PCRE=1 Install sudo make install ``` Understanding HAProxy Configuration HAProxy configuration is stored in `/etc/haproxy/haproxy.cfg`. The configuration file consists of several sections: Configuration Sections 1. Global: Global settings affecting the entire HAProxy process 2. Defaults: Default settings for all proxies 3. Frontend: Defines listening sockets accepting client connections 4. Backend: Defines servers that will handle the requests 5. Listen: Combines frontend and backend in a single section Basic Configuration Structure ```haproxy global # Global settings defaults # Default settings for all sections frontend # Frontend configuration backend # Backend server configuration listen # Combined frontend/backend configuration ``` Basic Load Balancer Configuration Let's create a basic load balancer configuration for web servers: Step 1: Backup Original Configuration ```bash sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.backup ``` Step 2: Create Basic Configuration Edit the HAProxy configuration file: ```bash sudo nano /etc/haproxy/haproxy.cfg ``` Replace the contents with this basic configuration: ```haproxy global log stdout local0 chroot /var/lib/haproxy stats socket /run/haproxy/admin.sock mode 660 level admin stats timeout 30s user haproxy group haproxy daemon 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 frontend web_frontend bind *:80 default_backend web_servers backend web_servers balance roundrobin option httpchk GET / server web1 192.168.1.10:80 check server web2 192.168.1.11:80 check server web3 192.168.1.12:80 check listen stats bind *:8404 stats enable stats uri /stats stats refresh 30s stats admin if TRUE ``` Step 3: Configure Logging Create rsyslog configuration for HAProxy: ```bash sudo nano /etc/rsyslog.d/49-haproxy.conf ``` Add the following content: ``` $ModLoad imudp $UDPServerRun 514 $UDPServerAddress 127.0.0.1 local0.* /var/log/haproxy.log & stop ``` Restart rsyslog: ```bash sudo systemctl restart rsyslog ``` Step 4: Test Configuration Validate the configuration syntax: ```bash sudo haproxy -f /etc/haproxy/haproxy.cfg -c ``` If the configuration is valid, you'll see: ``` Configuration file is valid ``` Step 5: Start HAProxy Service Enable and start HAProxy: ```bash sudo systemctl enable haproxy sudo systemctl start haproxy sudo systemctl status haproxy ``` Advanced Configuration Options Load Balancing Algorithms HAProxy supports various load balancing algorithms: ```haproxy backend web_servers # Round-robin (default) balance roundrobin # Least connections balance leastconn # Source IP hashing balance source # URI hashing balance uri # Header hashing balance hdr(host) # Random balance random ``` Session Persistence Maintain user sessions with specific servers: ```haproxy backend web_servers balance roundrobin # Cookie-based persistence cookie SERVERID insert indirect nocache server web1 192.168.1.10:80 check cookie web1 server web2 192.168.1.11:80 check cookie web2 # Or use source IP persistence # balance source ``` Advanced Routing with ACLs Route requests based on various criteria: ```haproxy frontend web_frontend bind *:80 # Define ACLs acl is_api path_beg /api/ acl is_static path_beg /static/ acl is_admin hdr_sub(host) admin # Route based on ACLs use_backend api_servers if is_api use_backend static_servers if is_static use_backend admin_servers if is_admin default_backend web_servers backend api_servers balance leastconn server api1 192.168.1.20:8080 check server api2 192.168.1.21:8080 check backend static_servers balance roundrobin server static1 192.168.1.30:80 check server static2 192.168.1.31:80 check ``` SSL/TLS Configuration SSL Termination Configure HAProxy to handle SSL termination: ```haproxy frontend https_frontend bind *:443 ssl crt /etc/ssl/certs/example.com.pem redirect scheme https if !{ ssl_fc } default_backend web_servers frontend http_frontend bind *:80 redirect scheme https code 301 if !{ ssl_fc } ``` Creating SSL Certificate Bundle Combine certificate files: ```bash Combine certificate, private key, and intermediate certificates sudo cat /path/to/certificate.crt /path/to/private.key /path/to/intermediate.crt > /etc/ssl/certs/example.com.pem Set proper permissions sudo chmod 600 /etc/ssl/certs/example.com.pem sudo chown haproxy:haproxy /etc/ssl/certs/example.com.pem ``` SSL Configuration Options ```haproxy global # SSL/TLS configuration ssl-default-bind-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384 ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets frontend https_frontend bind *:443 ssl crt /etc/ssl/certs/example.com.pem # Force HTTPS http-request redirect scheme https unless { ssl_fc } # Security headers http-response set-header Strict-Transport-Security max-age=31536000 http-response set-header X-Frame-Options DENY http-response set-header X-Content-Type-Options nosniff default_backend web_servers ``` Health Checks and Monitoring HTTP Health Checks Configure detailed health checks: ```haproxy backend web_servers balance roundrobin option httpchk GET /health HTTP/1.1\r\nHost:\ example.com http-check expect status 200 server web1 192.168.1.10:80 check inter 5s rise 2 fall 3 server web2 192.168.1.11:80 check inter 5s rise 2 fall 3 ``` TCP Health Checks For non-HTTP services: ```haproxy backend database_servers mode tcp balance leastconn option tcp-check tcp-check connect server db1 192.168.1.40:3306 check inter 10s server db2 192.168.1.41:3306 check inter 10s backup ``` Statistics Interface Enhanced statistics configuration: ```haproxy listen stats bind *:8404 stats enable stats uri /haproxy?stats stats refresh 30s stats realm HAProxy\ Statistics stats auth admin:secure_password stats admin if { src 192.168.1.0/24 } ``` Testing Your Configuration Syntax Validation Always validate configuration before applying: ```bash Check syntax sudo haproxy -f /etc/haproxy/haproxy.cfg -c Test with specific backend sudo haproxy -f /etc/haproxy/haproxy.cfg -c -V ``` Testing Load Balancing Use curl to test load balancing: ```bash Test multiple requests for i in {1..10}; do curl -H "Host: example.com" http://your-haproxy-ip/ echo "Request $i completed" done Test with different headers curl -H "X-Forwarded-For: 192.168.1.100" http://your-haproxy-ip/ ``` Monitoring Tools ```bash Check HAProxy stats via command line echo "show stat" | socat stdio /run/haproxy/admin.sock Show server information echo "show servers state" | socat stdio /run/haproxy/admin.sock Enable/disable servers echo "disable server web_servers/web1" | socat stdio /run/haproxy/admin.sock echo "enable server web_servers/web1" | socat stdio /run/haproxy/admin.sock ``` Troubleshooting Common Issues Configuration Errors Error: Configuration file is not valid ```bash Check detailed error messages sudo haproxy -f /etc/haproxy/haproxy.cfg -c -V Common issues: - Missing semicolons or incorrect syntax - Invalid server addresses - Conflicting bind addresses ``` Connection Issues Backend servers not responding: ```bash Check server connectivity telnet backend-server-ip 80 Verify health check URLs curl -I http://backend-server-ip/health Check HAProxy logs sudo tail -f /var/log/haproxy.log ``` SSL Certificate Issues SSL certificate problems: ```bash Verify certificate bundle openssl x509 -in /etc/ssl/certs/example.com.pem -text -noout Check certificate chain openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/example.com.pem Test SSL configuration openssl s_client -connect your-domain:443 -servername your-domain ``` Performance Issues High CPU usage or slow responses: ```bash Monitor HAProxy process top -p $(pgrep haproxy) Check connection limits ss -tuln | grep :80 ss -tuln | grep :443 Review timeout settings in configuration ``` Log Analysis Common log entries and their meanings: ```bash Successful request Oct 10 10:30:15 haproxy[1234]: 192.168.1.100:45678 [10/Oct/2023:10:30:15.123] web_frontend web_servers/web1 0/0/1/2/3 200 1234 - - ---- 1/1/1/1/0 0/0 "GET / HTTP/1.1" Backend server down Oct 10 10:30:15 haproxy[1234]: Server web_servers/web1 is DOWN, reason: Layer4 connection problem, info: "Connection refused" SSL handshake error Oct 10 10:30:15 haproxy[1234]: 192.168.1.100:45678 [10/Oct/2023:10:30:15.123] web_frontend~ web_frontend/ -1/-1/-1/-1/0 400 0 - - CR-- 1/1/0/0/0 0/0 "" ``` Best Practices and Security Security Hardening ```haproxy global # Security settings chroot /var/lib/haproxy user haproxy group haproxy # Disable dangerous options stats socket /run/haproxy/admin.sock mode 660 level admin frontend web_frontend # Rate limiting 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 } # Security headers http-response set-header X-Frame-Options SAMEORIGIN http-response set-header X-Content-Type-Options nosniff http-response set-header X-XSS-Protection "1; mode=block" # Hide server information http-response del-header Server http-response del-header X-Powered-By ``` Backup and Recovery ```bash Create configuration backup script #!/bin/bash BACKUP_DIR="/etc/haproxy/backups" DATE=$(date +%Y%m%d_%H%M%S) mkdir -p $BACKUP_DIR cp /etc/haproxy/haproxy.cfg $BACKUP_DIR/haproxy.cfg.$DATE Keep only last 10 backups ls -t $BACKUP_DIR/haproxy.cfg.* | tail -n +11 | xargs rm -f ``` Configuration Management Use version control for configuration: ```bash Initialize git repository cd /etc/haproxy sudo git init sudo git add haproxy.cfg sudo git commit -m "Initial HAProxy configuration" Track changes sudo git diff haproxy.cfg sudo git add haproxy.cfg sudo git commit -m "Updated backend servers" ``` Performance Optimization Tuning Parameters ```haproxy global # Performance tuning maxconn 4096 nbproc 1 nbthread 4 cpu-map auto:1/1-4 0-3 # Buffer sizes tune.bufsize 32768 tune.maxrewrite 8192 defaults # Connection limits maxconn 2000 # Optimized timeouts timeout connect 5s timeout client 50s timeout server 50s backend web_servers # Backend optimization option prefer-last-server option splice-auto option tcp-smart-accept ``` System-Level Optimization ```bash Increase file descriptor limits echo "haproxy soft nofile 65536" >> /etc/security/limits.conf echo "haproxy hard nofile 65536" >> /etc/security/limits.conf Kernel parameters echo "net.core.somaxconn = 65535" >> /etc/sysctl.conf echo "net.ipv4.tcp_max_syn_backlog = 65535" >> /etc/sysctl.conf echo "net.core.netdev_max_backlog = 5000" >> /etc/sysctl.conf Apply changes sudo sysctl -p ``` Monitoring Performance ```bash HAProxy statistics curl -s "http://localhost:8404/stats;csv" | column -t -s ',' System monitoring iostat -x 1 vmstat 1 netstat -i ``` Conclusion Configuring HAProxy as a load balancer on Linux provides a robust, scalable solution for distributing traffic across multiple backend servers. This comprehensive guide has covered everything from basic installation to advanced configuration options, SSL termination, health checking, and performance optimization. Key takeaways from this guide: 1. Proper Planning: Always plan your load balancing strategy before implementation 2. Configuration Validation: Always test configurations before applying them to production 3. Monitoring: Implement comprehensive monitoring and logging from the start 4. Security: Apply security best practices and keep HAProxy updated 5. Performance: Regularly monitor and optimize performance based on your specific workload 6. Documentation: Maintain clear documentation of your configuration and changes Next Steps After successfully configuring HAProxy, consider these additional steps: - High Availability: Set up HAProxy in a high-availability configuration using keepalived - Automation: Implement configuration management using tools like Ansible or Puppet - Advanced Features: Explore advanced features like Lua scripting and custom health checks - Integration: Integrate with monitoring solutions like Prometheus and Grafana - Load Testing: Perform comprehensive load testing to validate your configuration HAProxy's flexibility and robust feature set make it an excellent choice for load balancing in production environments. With proper configuration and monitoring, it can handle high traffic loads while providing excellent reliability and performance. Remember to regularly update HAProxy to benefit from security patches and new features, and always test configuration changes in a development environment before applying them to production systems.