HAProxy és un programari que permet equilibrar la càrrega entre diversos servidors. Se sol fer servir per equilibrar la càrrega de serveis web, però pot equilibrar la de qualsevol servei que funcioni amb el protocol TCP. En aquest article veuràs diverses configuracions d'HAProxy, incloses les que tenen en compte les galetes. Pot semblar un detall sense importància, però pot provocar errors al web. Imagina que tens 2 servidors web, que d'ara endavant anomenarem frontals. Quan l'usuari arriba per primera vegada al web, ho fa al frontal-01. Quan es registra, es crea una galeta. L'usuari continua navegant i, de sobte, HAProxy envia el trànsit al frontal-2. En aquest servidor no hi ha la galeta i, per tant, es tanca la sessió de l'usuari. Si configures HAProxy adequadament, això no passarà.
La configuració mínima per poder equilibrar la càrrega és de 3 servidors: HAProxy + 2 frontals web. L'avantatge de fer servir HAProxy és que pots afegir més frontals en qualsevol moment.
Un altre avantatge de fer servir HAProxy és que pots restringir l'accés als frontals per l'adreça IP pública, de manera que no seran accessibles directament.
També hi ha altres serveis per equilibrar la càrrega d'un servidor, com ara nginx.
Instal·lació d'HAProxy
Amb les ordres següents tindràs HAproxy instal·lat:
# apt update && apt upgrade
# apt install haproxy
# mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.org
Configuració bàsica
Ara ja pots crear el primer fitxer de configuració. Executa:
nano /etc/haproxy/haproxy.cfg
Copia la configuració següent i substitueix les adreces IP dels servidors per les que facis servir:
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
Ara que ja tenim la configuració enllestida, hem de reiniciar el servei d'HAProxy. Ho haurem de fer cada vegada que canviem la configuració.
# systemctl restart haproxy
Consultar les estadístiques
Per consultar les estadístiques via web, afegeix la configuració següent amb nano /etc/haproxy/haproxy.cfg:
listen stats
bind *:8083
mode http
stats enable
stats uri /stats
stats realm HAProxy\ Statistics
stats auth haproxy:TestKB
Ara obre el navegador i accedeix a http://IP_Publica_HAProxy:8083/stats. Et demanarà un nom d'usuari i una contrasenya: introdueix haproxy i TestKB.
Si vols que la pàgina d'estadístiques s'actualitzi automàticament cada 10 minuts, afegeix aquesta directiva:
stats refresh 10s
Comprovar l'estat i controlar les galetes
Pots controlar que un usuari accedeixi sempre al mateix frontal. En el nostre exemple ens basarem en una variable de PHP, però pots utilitzar qualsevol 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
Afegir un certificat SSL de Let's Encrypt per a HAProxy
Ara que HAProxy funciona, és el moment de fer algunes modificacions perquè el lloc web amb la càrrega equilibrada estigui protegit amb un certificat. En el nostre cas ho farem amb Let's Encrypt. Cal tenir en compte els aspectes següents:
- HAProxy i Let's Encrypt no poden utilitzar els mateixos ports 80 i 443. Modificarem Let's Encrypt i la renovació automàtica perquè utilitzin un port diferent.
- HAProxy no pot llegir el certificat SSL distribuït en els diversos fitxers que es generen automàticament. Modificaràs el certificat SSL perquè HAProxy el pugui llegir.
- Hauràs de crear una regla de filtratge a HAProxy perquè les renovacions de Let's Encrypt funcionin i la resta de peticions s'enviïn al backend.
- Hauràs de crear un script per permetre la renovació automàtica del certificat i adaptar-lo per fer-lo servir amb HAProxy.
- Tingues en compte que hauràs de tenir els DNS configurats. Pots consultar com fer-ho a l'article següent: Configuració de les zones DNS per al nostre servidor
Primer de tot, instal·la Let's Encrypt amb les ordres següents:
# apt install -y certbot
Ara edita el fitxer següent:
# nano /etc/haproxy/haproxy.cfg
Deixa'l amb el contingut següent:
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
# Forcem HAProxy a redirigir a HTTPS
#redirect scheme https code 301 if !{ ssl_fc }
# Indiquem que les peticions de Lets Encrypt vagin al bloc backend letsencrypt
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
use_backend letsencrypt if letsencrypt-acl
#Backend de lets encrypt
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 aquest codi, l'identificador "edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host" s'ha de substituir pel nom de domini que es faci servir per al web, i les adreces IP dels servidors s'han de substituir per les que tinguis configurades al servidor.
Reinicia HAproxy:
# systemctl restart haproxy
El pas següent és generar el certificat SSL de Let's Encrypt per al domini, que després configuraràs a HAProxy. L'ordre que has d'executar és:
# certbot certonly --standalone -d de9dcd77-65a7-439a-8fa2-29eda02025a3.clouding.host --non-interactive --agree-tos --email soporte@clouding.io --http-01-port=8888
Com pots veure, has d'utilitzar el port 8888 perquè no entri en conflicte amb HAProxy.
Ara has de crear el directori i el fitxer on desaràs el certificat SSL adaptat perquè HAProxy el pugui llegir. Per fer-ho, executa:
# 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
Amb això ja tindràs el certificat adaptat, que s'utilitza a la configuració anterior d'HAProxy en aquesta línia:
bind *:443 ssl crt /etc/ssl/edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host/edf10be0-f2c0-4cef-b38b-eee8e9577d6f.clouding.host.pem
Ara ja pots descomentar les línies anteriors:
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 }
Perquè el certificat de Let's Encrypt es renovi automàticament, hauràs de crear un petit script i afegir-lo al crontab perquè s'executi una vegada al mes:
# crontab -e
Afegeix-hi la línia següent:
0 0 1 * * root bash /opt/renovar-certificados.sh
Ara crea l'script:
# nano /opt/renovar-certificados.sh
i afegeix-hi el contingut següent:
#!/usr/bin/env bash
# Renovar el certificat
certbot renew --force-renewal --tls-sni-01-port=8888
# Adaptem el certificat per a 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"
# Tornem a carregar haproxy
service haproxy reload
Finalment, hauries de comprovar que Let's Encrypt podrà renovar el certificat executant:
# certbot renew --tls-sni-01-port=8888
Recorda que, si tens consultes sobre aquesta qüestió o qualsevol altra relacionada amb els teus servidors a Clouding, pots escriure a soporte@clouding.io Som al teu costat per al que necessitis, consulta'ns!