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.