TL;DR — Resumen Rápido
Guía completa de HAProxy para balanceo de carga TCP y HTTP con alta disponibilidad. ACLs, health checks, SSL, stick tables y failover con keepalived VRRP.
HAProxy es la implementación de referencia para balanceo de carga de código abierto. Mientras Nginx sirve también como servidor web y Caddy prioriza la facilidad de uso, HAProxy está diseñado específicamente para proxy y balanceo de carga, y eso se nota en cada benchmark. Esta guía cubre el stack completo de HAProxy: arquitectura, instalación en Ubuntu y RHEL, ajuste de global y defaults, configuración de frontend/backend con ACLs, todos los algoritmos de balanceo, health checks TCP y HTTP, terminación SSL/TLS, la página de estadísticas, stick tables, rate limiting, integración con rsyslog y una configuración completa de keepalived VRRP para alta disponibilidad en dos nodos.
Requisitos Previos
Antes de comenzar, asegúrate de tener:
- Ubuntu 22.04/24.04 o RHEL 9/AlmaLinux 9 con acceso sudo
- Al menos dos servidores de aplicación backend
- Dos nodos HAProxy (para la sección de alta disponibilidad con keepalived)
- Conocimientos básicos de TCP/IP y HTTP
- HAProxy 2.6 o posterior (se recomienda la versión LTS)
Arquitectura de HAProxy
HAProxy se ejecuta como un proceso único basado en eventos (o un número configurable de procesos/hilos). Toda la E/S es no bloqueante y multiplexada, lo que permite a HAProxy gestionar decenas de miles de conexiones concurrentes con RAM mínima.
Un archivo de configuración tiene cuatro tipos de sección principales:
- global — configuración global del proceso (maxconn, log, chroot, user/group, nbthread)
- defaults — valores predeterminados heredados por todos los frontends y backends
- frontend — escucha conexiones entrantes; aplica ACLs y enruta tráfico a backends
- backend — define el grupo de servidores, algoritmo de balanceo y parámetros de health check
- listen — combinación de frontend+backend, útil para la página de estadísticas o proxies TCP simples
El flujo del tráfico es: cliente → frontend → evaluación de ACLs → regla use_backend → backend → servidor.
Instalación
Ubuntu / Debian
sudo apt update
sudo apt install haproxy -y
haproxy -v
Para una versión LTS más reciente, añade el PPA oficial:
sudo add-apt-repository ppa:vbernat/haproxy-2.8 -y
sudo apt install haproxy=2.8.\* -y
RHEL / AlmaLinux / Rocky Linux
sudo dnf install haproxy -y
haproxy -v
sudo systemctl enable --now haproxy
Configuración Global y Defaults
Abre /etc/haproxy/haproxy.cfg y reemplaza el contenido estándar con una base lista para producción:
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon
maxconn 50000
nbthread 4
tune.ssl.default-dh-param 2048
ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:!aNULL:!MD5:!DSS
ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11
defaults
log global
mode http
option httplog
option dontlognull
option forwardfor
option http-server-close
retries 3
timeout connect 5s
timeout client 30s
timeout server 30s
timeout http-keep-alive 10s
timeout check 5s
maxconn 3000
Parámetros clave explicados:
maxconn 50000— límite global de conexiones; ajusta según la RAM disponible (~1 MB por 1000 conexiones)nbthread 4— ejecuta cuatro hilos en un sistema de cuatro núcleos; HAProxy 2.x es multihilooption dontlognull— suprime logs de health checks sin payloadoption forwardfor— inyecta la cabeceraX-Forwarded-Foren las peticiones proxyretries 3— reintentos de conexión fallida antes de marcar un servidor como caídotimeout connect 5s— tiempo máximo para establecer una conexión TCP con un backend
Configuración de Frontend
Un frontend define en qué escucha HAProxy y a dónde enruta el tráfico:
frontend http_front
bind *:80
bind *:443 ssl crt /etc/haproxy/certs/example.com.pem
http-request redirect scheme https unless { ssl_fc }
http-request set-header X-Forwarded-Proto https if { ssl_fc }
# Definición de ACLs
acl is_api path_beg /api/
acl is_static path_beg /static/ /assets/ /images/
acl host_admin hdr(host) -i admin.example.com
# Reglas de enrutamiento
use_backend api_backend if is_api
use_backend static_backend if is_static
use_backend admin_backend if host_admin
default_backend app_backend
Coincidencias de ACL más utilizadas:
| Coincidencia | Ejemplo | Qué comprueba |
|---|---|---|
path_beg | path_beg /api/ | URI comienza con /api/ |
path_end | path_end .php | URI termina en .php |
hdr(host) | hdr(host) -i api.example.com | Cabecera Host (sin distinción de mayúsculas) |
src | src 10.0.0.0/8 | Rango de IP del cliente |
method | method POST | Método HTTP |
Configuración de Backend
Un backend define el grupo de servidores y cómo se distribuye el tráfico:
backend app_backend
balance roundrobin
option httpchk GET /health HTTP/1.1\r\nHost:\ app.example.com
server app1 10.0.0.10:8080 weight 3 maxconn 500 check inter 2s fall 3 rise 2
server app2 10.0.0.11:8080 weight 3 maxconn 500 check inter 2s fall 3 rise 2
server app3 10.0.0.12:8080 weight 1 maxconn 200 check inter 2s fall 3 rise 2
server app_backup 10.0.0.20:8080 backup check inter 5s fall 2 rise 1
Algoritmos de Balanceo
| Algoritmo | Directiva | Mejor para |
|---|---|---|
| Round-robin | balance roundrobin | Peticiones cortas y uniformes |
| RR ponderado | balance roundrobin + weight N | Servidores de capacidad mixta |
| Menos conexiones | balance leastconn | Tiempos de respuesta variables |
| Hash de IP origen | balance source | Afinidad de sesión por IP del cliente |
| Hash de URI | balance uri | Servidores de caché |
| Hash de cabecera | balance hdr(User-Agent) | Enrutamiento por cabecera HTTP |
Health Checks
Health Check TCP (predeterminado)
HAProxy abre una conexión TCP para verificar que el puerto está escuchando:
backend tcp_backend
balance leastconn
server db1 10.0.0.30:5432 check inter 3s fall 2 rise 1
server db2 10.0.0.31:5432 check inter 3s fall 2 rise 1
Health Check HTTP
Para backends HTTP, verifica que la aplicación devuelve un código de estado saludable:
backend app_backend
option httpchk GET /health HTTP/1.1\r\nHost:\ app.example.com
http-check expect status 200
server app1 10.0.0.10:8080 check inter 2s fall 3 rise 2
server app2 10.0.0.11:8080 check inter 2s fall 3 rise 2
Terminación SSL/TLS
HAProxy termina SSL en el frontend y reenvía TCP o HTTP sin cifrar a los backends. Combina certificado y clave privada en un PEM:
cat fullchain.pem privkey.pem > /etc/haproxy/certs/example.com.pem
chmod 600 /etc/haproxy/certs/example.com.pem
SNI multi-certificado (un directorio, HAProxy elige el certificado correcto automáticamente):
frontend https_front
bind *:443 ssl crt /etc/haproxy/certs/
http-request set-header X-Forwarded-Proto https
http-response set-header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
default_backend app_backend
Página de Estadísticas
La página de estadísticas integrada de HAProxy proporciona métricas de conexión en tiempo real:
listen stats
bind *:8404
stats enable
stats uri /stats
stats refresh 10s
stats auth admin:changeme
stats show-legends
stats show-node
stats hide-version
Accede en http://tu-servidor:8404/stats. Protege este puerto con una regla de firewall:
sudo ufw allow from 10.0.0.0/8 to any port 8404
sudo ufw deny 8404
Stick Tables para Persistencia de Sesión
Las stick tables rastrean asignaciones cliente→servidor en memoria compartida:
backend app_backend
balance roundrobin
stick-table type ip size 100k expire 30m
stick on src
server app1 10.0.0.10:8080 check
server app2 10.0.0.11:8080 check
Para persistencia basada en cookies:
backend app_backend
balance roundrobin
cookie SERVERID insert indirect nocache
server app1 10.0.0.10:8080 cookie app1 check
server app2 10.0.0.11:8080 cookie app2 check
Rate Limiting con Stick Tables
Las stick tables de HAProxy también gestionan el rate limiting sin dependencias externas:
frontend http_front
bind *:80
bind *:443 ssl crt /etc/haproxy/certs/
stick-table type ip size 200k expire 10s store http_req_rate(10s)
http-request track-sc0 src
http-request deny deny_status 429 if { sc_http_req_rate(0) gt 100 }
default_backend app_backend
Para límites más estrictos en rutas específicas (por ejemplo, el endpoint de login):
frontend http_front
stick-table type ip size 50k expire 60s store http_req_rate(60s)
http-request track-sc0 src if { path_beg /api/auth/ }
http-request deny deny_status 429 if { path_beg /api/auth/ } { sc_http_req_rate(0) gt 10 }
Logging con rsyslog
HAProxy registra en un socket syslog. Configura rsyslog para escribir los logs de HAProxy en un archivo dedicado.
Crea /etc/rsyslog.d/49-haproxy.conf:
$AddUnixListenSocket /dev/log
:programname, startswith, "haproxy" {
/var/log/haproxy.log
stop
}
Reinicia rsyslog y HAProxy:
sudo systemctl restart rsyslog
sudo systemctl restart haproxy
HAProxy con Keepalived para Failover VRRP
keepalived ejecuta VRRP para asignar una IP virtual compartida entre dos nodos HAProxy. Si el nodo primario falla, el nodo de respaldo toma la IP virtual en uno o dos segundos.
Instalar keepalived
sudo apt install keepalived -y # Ubuntu
sudo dnf install keepalived -y # RHEL
Nodo primario — /etc/keepalived/keepalived.conf
vrrp_script chk_haproxy {
script "killall -0 haproxy"
interval 2
weight -20
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 110
advert_int 1
authentication {
auth_type PASS
auth_pass s3cur3p4ss
}
virtual_ipaddress {
192.168.1.100/24
}
track_script {
chk_haproxy
}
}
Nodo de respaldo — /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass s3cur3p4ss
}
virtual_ipaddress {
192.168.1.100/24
}
}
sudo systemctl enable --now keepalived
ip addr show eth0 | grep 192.168.1.100
Tabla Comparativa de Balanceadores
| Característica | HAProxy | Nginx | Traefik | Envoy | AWS ALB |
|---|---|---|---|---|---|
| Balanceo TCP | Sí (nativo) | Sí | Sí | Sí | Sí |
| Health checks activos | Sí (integrado) | Solo Plus | Sí | Sí | Sí |
| IU de estadísticas | Integrada | stub_status | Dashboard | Admin API | CloudWatch |
| Rate limiting | Stick tables | limit_req | Middleware | Filters | WAF |
| Terminación SSL | Sí | Sí | Sí | Sí | Sí |
| HA/VRRP | Via keepalived | Via keepalived | No integrado | No integrado | Gestionado |
| Huella de recursos | Muy baja | Baja | Media | Alta | Gestionado |
| Mejor para | TCP+HTTP HA | Web + caché | Contenedores | Service mesh | AWS nativo |
Resumen
HAProxy es el estándar de referencia para balanceo de carga TCP y HTTP en entornos Linux. Puntos clave:
- Ajusta
maxconn,nbthready los timeouts en las seccionesglobalydefaultsantes que nada - Construye ACLs en el frontend con
path_beg,hdr()ysrc; enruta a backends conuse_backend - Elige
leastconnpara APIs HTTP,roundrobinpara tráfico uniforme, ysourceo stick tables para persistencia de sesión - Añade siempre
check inter 2s fall 3 rise 2a cada línea de servidor yoption httpchka los backends HTTP - Termina SSL en el frontend con un archivo PEM combinado; varios certs en un directorio para SNI automático
- Usa stick tables para persistencia de sesión y rate limiting sin dependencias externas
- Combina HAProxy con keepalived VRRP para failover en menos de un segundo entre dos nodos