
✨ Aborda el tema de HAProxy y Keepalived como balanceador de carga y clúster, además de seguridad (prevención de la vulnerabilidad de uso débil de SSL/Cripto (LOGJAM) (CVE-2015-4000)) y contra altas cargas.

HAProxy es un software de código abierto que proporciona servicio de servidor proxy para aplicaciones basadas en TCP y HTTP con balanceo de carga de alta disponibilidad.
Keepalived es un software de código abierto capaz de proporcionar capacidad de IP failover (conmutación por error) para más de dos servidores. Keepalived utiliza la técnica de comunicación Multicast entre sí.
En nuestra estructura, usaremos HAProxy como balanceador de carga y Keepalived para transferir la IP, es decir, para convertir nuestra estructura HAProxy en un Clúster.
En nuestro escenario hay 3 servidores. Instalaremos HAProxy en estos 3 servidores para convertirlos en balanceadores de carga. Luego, instalaremos el servicio Keepalived para que, cuando uno de los servidores se caiga, se realice un IP failover y se pase a otro servidor sin interrupción, manteniendo nuestro servicio de balanceador de carga en funcionamiento.
Para ello utilizaremos 4 IPs (las IPs son completamente inventadas)
Ahora instalemos el servicio HAProxy y Keepalived en los 3 servidores de la siguiente manera.
sudo add-apt-repository ppa:vbernat/haproxy-2.7 -y
sudo apt update
sudo apt install haproxy keepalived -y
sudo openssl dhparam -out /etc/haproxy/dhparams.pem 2048
Nota1: En los servidores debe estar presente "net.ipv4.ip_nonlocal_bind=1". De lo contrario, la configuración utilizada para HAProxy no podrá albergar la misma IP simultáneamente y dará un error de bind, y el servicio no funcionará. Para ello, debe seguir la siguiente ruta.
Primero edite el archivo "vi /etc/sysctl.conf" y pegue el siguiente parámetro, guarde y salga.
net.ipv4.ip_nonlocal_bind=1
Luego ejecute el siguiente comando.
sysctl -p
Nota2: Si va a usar 443 SSL, debe tener en el directorio "/etc/ssl/private/" el archivo "haproxy.pem" que contiene la versión Bundle de sus SSLs (***.crt, .ca, .key).
Ahora veamos un ejemplo de configuración de HAProxy a continuación. Usará la misma configuración para cada HAProxy en su estructura.
Para ello editará el archivo "/etc/haproxy/haproxy.cfg". La siguiente configuración soporta mínimamente HA v2.
vi /etc/haproxy/haproxy.cfg
A continuación se muestran los valores por defecto.
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 100000 #replaceable
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# Default ciphers to use on SSL-enabled listening sockets.
# For more information, see ciphers(1SSL). This list is from:
# https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
# An alternative list with additional directives can be obtained from
# https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy
ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
#ssl-default-bind-options no-sslv3
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
ssl-dh-param-file /etc/haproxy/dhparams.pem
#tune.ssl.default-dh-param 2048
# nbproc 1
# nbthread 8
tune.maxrewrite 16384
tune.bufsize 32768
defaults
log global
mode http
option httplog
option dontlognull
option forwardfor
# maxconn 1000000 #replaceable
timeout connect 3000000
timeout client 6000000
timeout server 6000000
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
Parte de configuración del Dashboard para HAProxy (se agregó integración con prometheus para monitoreo)
listen stats
bind fatlan.com:8989
mode http
stats enable
stats uri /stats
option http-use-htx
http-request use-service prometheus-exporter if { path /metrics }
#stats hide-version
stats realm HAProxy\ Statistics
stats auth admin:admin
En la siguiente configuración se usó ACL en dos bloques. En el primer bloque, si en cualquier parte del enlace aparece la palabra "rest", se ejecutará el bloque middleware-fatlan-backend; en el segundo, cuando se solicite un dominio diferente (forum.fatlan.com), se ejecutará el backend fatlan-forum-backend; todas las demás solicitudes se ejecutarán en el bloque fatlan-backend443, excepto otras redirecciones de puertos.
Parte de redirección del puerto 80 al puerto 443
frontend fatlan80
bind fatlan.com:80
mode http
redirect scheme https if !{ ssl_fc }
frontend fatlan443
bind fatlan.com:443 ssl crt /etc/ssl/private/haproxy.pem ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
option httplog
option forwardfor
#http-request set-header X-Client-IP req.hdr_ip([X-Forwarded-For])
#option forwardfor except 127.0.0.0/8
option http-server-close
http-request set-header X-Forwarded-Proto https
# reqadd X-Forwarded-Proto:\ https #old config
mode http
default_backend fatlan-backend443
Ejemplo de configuración ACL (proxypass): si en cualquier parte del enlace aparece la palabra rest, redirigir
acl middleware-fatlan path_beg /rest
use_backend middleware-fatlan-backend if middleware-fatlan
ACL para redirigir un host diferente de forum
acl host_fatlanforum hdr(host) -i forum.fatlan.com
use_backend fatlan-forum-backend if host_fatlanforum
Parte redirigida por defecto, para 443
backend fatlan-backend443
mode http
balance roundrobin
stick store-request src
stick-table type ip size 256k expire 30m
option forwardfor
# option httplog
option httpchk HEAD /
server frontend_01 10.10.37.12:8001 check port 8001 inter 3000 rise 2 fall 3
server frontend_02 10.10.37.13:8001 check port 8001 inter 3000 rise 2 fall 3
Parte redirigida por ACL, proveniente de rest
backend middleware-fatlan-backend
mode http
balance roundrobin
stick store-request src
stick-table type ip size 256k expire 30m
option forwardfor
# option httplog
option httpchk OPTIONS /login HTTP/1.0
http-check expect status 200
http-request replace-path (.*)(?:rest\/)(.*) \1\2
# reqrep ^([^\ :]*)\ /rest[/]?(.*) \1\ //\2 #old config
server middleware_01 10.10.37.34:3000 check port 4000 inter 12000 rise 3 fall 3
server middleware_02 10.10.37.35:3000 check port 4000 inter 12000 rise 3 fall 3