HAProxy es un software que permite balancear carga entre varios servidores. Se suele usar para balancear servicios web, pero puede balancear cualquier servicio que funcione bajo protocolo TCP. En este artículo verás varias configuraciones de HAProxy incluso que tenga en cuenta las cookies, parece una tontería, pero puede provocar que fallen nuestra web. Imagínate que tienes 2 servidores web -en adelante frontales- cuando el usuario llega por primera vez a tu web lo hace en el frontal-01. Cuando el usuario se registra crea una cookie, el usuario siguen navegando y de repente HAProxy envía el tráfico al frontal-2, en ese servidor no existe la cookie y por tanto le cerrará la sesión , configurando adecuadamente HAProxy esto no sucederá.
La configuración mínima para poder balancear carga es de 3 servidores: HAProxy + 2 frontales webs. La ventaja de usar HAProxy es que en cualquier momento puedes añadir más frontales.
Otra de las ventajas de usar HAProxy es que puedes restringir el acceso a los frontales por la IP Pública, con lo cual no estarán accesibles directamente.
De todas formas hay diversos servicios para balancear un servidor, como puede ser el mismo nginx.
Instalación HAProxy
Con los siguientes comandos ya tendrás instalado HAproxy:
# apt update && apt upgrade
# apt install haproxy
# mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.org
Configuración base
Ahora ya podrás crear el primer fichero de configuración ejecuta:
nano /etc/haproxy/haproxy.cfg
Y copia la configuración adjunta, tendrás que modificar las IP de los servidores por los que estés usando:
global daemon maxconn 256 user haproxy group haproxy log 127.0.0.1 local0 log 127.0.0.1 local1 notice defaults log global mode http option tcplog option dontlognull maxconn 8000 timeout connect 5s timeout client 300s timeout server 300s retries 3 timeout check 10s timeout queue 1m 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
frontend Haproxy
bind *:80
option forwardfor
default_backend servidores
backend servidores
balance roundrobin
server server1 10.20.10.8:80 check
server server2 10.20.10.9:80 check
Ahora que ya tenemos la configuración hecha, tenemos que reiniciar el servicio de HAProxy, esto lo haremos cada vez que cambiemos la configuración.
# systemctl restart haproxy
Ver estadísticas
Para ver estadísticas vía web, añade la siguiente configuración nano /etc/haproxy/haproxy.cfg:
listen stats
bind *:8083
mode http
stats enable
stats uri /stats
stats realm HAProxy\ Statistics
stats auth haproxy:TestKB
Ahora ve al navegador y abre la web http://IP_Publica_HAProxy:8083/stats, te pedirá usuario y contraseña, introduce haproxy y TestKB.
Si quieres que la página de estadísticas se actualice sola cada 10 minutos, añade la directiva:
stats refresh 10s
Comprobar estado y controlar cookies
Puedes controlar que un usuario siempre acceda al mismo frontal, en nuestro ejemplo nos basaremos en una variable de PHP, pero puedes utilizar cualquier variable.
backend servidores
balance roundrobin
cookie PHPSESSID prefix indirect nocache
server server1 10.20.10.8:80 check maxconn 4000 fall 3 cookie L1
server server2 10.20.10.9:80 check maxconn 4000 fall 3 cookie L2
Añadir certificado SSL de Let's Encrypt para HAProxy
En este punto en que tienes HAProxy funcionando, es el momento adecuado para realizar unas modificaciones para que el sitio web balanceado esté protegido con un certificado, en nuestro caso lo haremos con Let's Encrypt. Algunos aspectos que hay que tener en cuenta son:
- HAProxy y Let's Encrypt no pueden utilizar los mismos puertos 80 y 443. Modificaremos Let's Encrypt y la auto-renovación para que utilice un puerto distinto.
- HAProxy no es capaz de leer el certificado SSL en diversos ficheros como se generan de forma automática. Modificarás el certificado SSL para que lo pueda leer HAProxy.
- Tendrás que crear una regla de filtrado en HAProxy para que las renovaciones de Let's Encrypt funcionen y el resto de peticiones se envíen al backend.
- Tendrás que crear un script para la auto-renovación del certificado sea posible adaptándolo al uso junto a HAProxy.
- Ten en cuenta que tendrás que tener los DNS configurados, puedes ver como hacerlo en el siguiente artículo: Configuración de las zonas DNS para nuestro servidor
Primero de todo instala Let's Encrypt con los siguientes comandos:
# apt install -y certbot
Ahora edita el siguiente fichero:
# nano /etc/haproxy/haproxy.cfg
Y déjalo como a continuación:
global
daemon
maxconn 256
user haproxy
group haproxy
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
defaults
log global
mode http
option tcplog
option dontlognull
maxconn 8000
timeout connect 5s
timeout client 300s
timeout server 300s
retries 3
timeout check 10s
timeout queue 1m
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
frontend Haproxy
bind *:80
option forwardfor
default_backend servidores
#bind *:443 ssl crt /etc/ssl/de9dcd77-65a7-439a-8fa2-29eda02025a3.clouding.host/de9dcd77-65a7-439a-8fa2-29eda02025a3.clouding.host.pem
# Forzamos a HAProxy para que redireccione a HTTPS
#redirect scheme https code 301 if !{ ssl_fc }
# Indicamos que las peticiones de Lets Encrypt vayan al bloque banckend letsencrypt
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
use_backend letsencrypt if letsencrypt-acl
#lets encrypt backend
backend letsencrypt
server letsencrypt 127.0.0.1:8888
backend servidores
balance roundrobin
cookie PHPSESSID prefix indirect nocache
server server1 10.20.10.8:80 check maxconn 4000 fall 3 cookie L1
server server2 10.20.10.9:80 check maxconn 4000 fall 3 cookie L2
listen stats
bind *:8083
mode http
stats enable
stats uri /stats
stats realm HAProxy\ Statistics
stats auth haproxy:TestKB
En este código el identificador "edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host" se tiene que sustituir por el nombre de dominio que se esté usando para la web y las IP de los servidores hay que modificarlas por las que tengas configuradas en el servidor.
Reinicia el HAproxy:
# systemctl restart haproxy
El siguiente paso que tendrás que realizar es generar el certificado SSL de Let's Encrypt para el dominio y que posteriormente configurar en HAProxy. El comando a ejecutar es:
# certbot certonly --standalone -d de9dcd77-65a7-439a-8fa2-29eda02025a3.clouding.host --non-interactive --agree-tos --email soporte@clouding.io --http-01-port=8888
Cómo puedes ver, tienes que utilizar el puerto 8888 para que no entre en conflicto con HAProxy.
Ahora tienes que crear el directorio y el fichero dónde vas a guardar el certificado SSL adaptado para que HAProxy lo pueda leer. Para ello ejecuta:
# mkdir -p /etc/ssl/edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host
# cat /etc/letsencrypt/live/de9dcd77-65a7-439a-8fa2-29eda02025a3.clouding.host/fullchain.pem /etc/letsencrypt/live/de9dcd77-65a7-439a-8fa2-29eda02025a3.clouding.host/privkey.pem | tee /etc/ssl/de9dcd77-65a7-439a-8fa2-29eda02025a3.clouding.host/de9dcd77-65a7-439a-8fa2-29eda02025a3.clouding.host.pem
Con esto ya tendrás el certificado adaptado y que en la configuración de HAProxy anterior lo utiliza en la línea:
bind *:443 ssl crt /etc/ssl/edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host/edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host.pem
Ahora ya puedes descomentar las líneas anteriores:
bind *:443 ssl crt /etc/ssl/de9dcd77-65a7-439a-8fa2-29eda02025a3.clouding.host/de9dcd77-65a7-439a-8fa2-29eda02025a3.clouding.host.pem
redirect scheme https code 301 if !{ ssl_fc }
Para que el certificado de Let's Encrypt se renueve automáticamente tendrás que crear un pequeño script y añadirlo al crontab para que se ejecute una vez al mes:
# crontab -e
Y añade la siguiente línea:
0 0 1 * * root bash /opt/renovar-certificados.sh
Ahora crea el script:
# nano /opt/renovar-certificados.sh
y añade el siguiente contenido:
#!/usr/bin/env bash
# Renovar certificado
certbot renew --force-renewal --tls-sni-01-port=8888
# Adaptamos el certificado para haproxy
bash -c "cat /etc/letsencrypt/live/de9dcd77-65a7-439a-8fa2-29eda02025a3.clouding.host/fullchain.pem /etc/letsencrypt/live/de9dcd77-65a7-439a-8fa2-29eda02025a3.clouding.host/privkey.pem | tee /etc/ssl/de9dcd77-65a7-439a-8fa2-29eda02025a3.clouding.host/de9dcd77-65a7-439a-8fa2-29eda02025a3.clouding.host.pem"
# Recargamos haproxy
service haproxy reload
Finalmente, deberías comprobar que Let's Encrypt será capaz de renovar el certificado ejecutando:
# certbot renew --tls-sni-01-port=8888
Recuerda, si tienes consultas sobre esta u otra cuestión relacionada con tus servidores en Clouding, no dudes en escribir a soporte@clouding.io ¡Estamos a tu lado para lo que necesites, consúltanos!