HAProxy: Difference between revisions
| (81 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
== HAProxy | == HAProxy - Load Balancing Standard (Grup Unic Backend) == | ||
[[File:HAProxy.png|782x616px|none|HAProxy]] | [[File:HAProxy.png|782x616px|none|HAProxy]] | ||
=== Instalare HAProxy === | === Instalare HAProxy === | ||
| Line 68: | Line 68: | ||
</code> | </code> | ||
* * | * bind *:80 – ascultă pe portul 80. | ||
* mode http – procesează header-ele HTTP. | * mode http – procesează header-ele HTTP. | ||
* option forwardfor – adaugă X‑Forwarded‑For cu IP-ul real al clientului. | * option forwardfor – adaugă X‑Forwarded‑For cu IP-ul real al clientului. | ||
| Line 82: | Line 82: | ||
    server vm01 192.168.14.11:80 check |     server vm01 192.168.14.11:80 check | ||
    server vm02 192.168.14.22:80 check |     server vm02 192.168.14.22:80 check | ||
    server vm03 192.168.14. |     server vm03 192.168.14.33:80 check | ||
</code> | </code> | ||
| Line 94: | Line 94: | ||
În această situaţie HAProxy gestionează certificatul. | În această situaţie HAProxy gestionează certificatul. | ||
Generare certificat Let’s Encrypt | ==== Generare certificat Let’s Encrypt ==== | ||
Necesită port 80 public și domeniu valid. | Necesită port 80 public și domeniu valid.<br> | ||
Certbot, în modul <span style=" font-family: Courier New;">--standalone</span>, pornește un mini‑webserver intern pe portul 80 pentru a răspunde la challenge-ul HTTP‑01 de la Let’s Encrypt. | Certbot, în modul <span style=" font-family: Courier New;">--standalone</span>, pornește un mini‑webserver intern pe portul 80 pentru a răspunde la challenge-ul HTTP‑01 de la Let’s Encrypt.<br> | ||
Dacă HAProxy este pornit, acesta ocupă portul 80 și Certbot nu poate porni serverul de validare, ceea ce duce la eșecul generării certificatului. | Dacă HAProxy este pornit, acesta ocupă portul 80 și Certbot nu poate porni serverul de validare, ceea ce duce la eșecul generării certificatului. | ||
Instalare certbot | '''Instalare certbot''' | ||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | <code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | ||
| Line 106: | Line 106: | ||
</code> | </code> | ||
Oprire temporară HAProxy | '''Oprire temporară HAProxy''' | ||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | <code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | ||
| Line 112: | Line 112: | ||
</code> | </code> | ||
Generare certificat | '''Generare certificat''' | ||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | <code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | ||
| Line 118: | Line 118: | ||
</code> | </code> | ||
Creare fișier PEM pentru HAProxy | '''Creare fișier PEM pentru HAProxy''' | ||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | <code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | ||
| Line 127: | Line 127: | ||
 # chmod 600 /etc/haproxy/certs/wiki.stradivart.ro.pem |  # chmod 600 /etc/haproxy/certs/wiki.stradivart.ro.pem | ||
</code> | </code> | ||
==== Frontend HTTPS (SSL termination) ==== | |||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | |||
--> frontend https_in | |||
    bind *:443 ssl crt /etc/haproxy/certs/wiki.stradivart.ro.pem | |||
    mode http | |||
    option forwardfor | |||
    default_backend http_webserver | |||
</code> | |||
* *bind :443 ssl crt ... – HAProxy decriptează SSL. | |||
* mode http – traficul devine HTTP după terminarea SSL. | |||
* default_backend http_webserver – backend-ul HTTP unic. | |||
==== Backend HTTPS (SSL termination) ==== | |||
În cazul SSL termination, backend-ul nu procesează trafic HTTPS.<br> | |||
HAProxy decriptează SSL în frontend, iar backend-ul primește trafic HTTP normal (non‑SSL).<br> | |||
De aceea backend-ul este identic cu backend-ul HTTP. | |||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | |||
--> backend http_webserver | |||
    mode http | |||
    balance leastconn | |||
    option httpchk GET / | |||
    server vm01 192.168.14.11:80 check | |||
    server vm02 192.168.14.22:80 check | |||
    server vm03 192.168.14.33:80 check | |||
</code> | |||
* mode http – backend-ul procesează HTTP. | |||
* balance leastconn – trimite traficul către serverul cu cele mai puține conexiuni active. | |||
* option httpchk GET / – health-check HTTP. | |||
* server vm01/vm02/vm03 – cele trei VM. | |||
=== HTTPS (port 443) cu SSL Passthrough === | |||
Webserver-ul gestionează certificatul. HAProxy doar forward-ează pachetele SSL. | |||
==== Frontend HTTPS (SSL passthrough) ==== | |||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | |||
--> frontend https_in | |||
    bind *:443 | |||
    mode tcp | |||
    default_backend httpS_webserver | |||
</code> | |||
* *bind :443 – ascultă pe portul 443. | |||
* mode tcp – HAProxy nu decriptează SSL. | |||
* default_backend httpS_webserver – backend separat în modul TCP. | |||
==== Backend HTTPS (SSL passthrough) ==== | |||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | |||
--> backend httpS_webserver | |||
    mode tcp | |||
    balance leastconn | |||
    server vm01 192.168.14.11:443 check | |||
    server vm02 192.168.14.22:443 check | |||
    server vm03 192.168.14.33:443 check | |||
</code> | |||
* mode tcp – forward transparent al pachetelor SSL. | |||
* balance leastconn – distribuție inteligentă. | |||
* server vm01/vm02/vm03 – VM-urile ISPConfig. | |||
=== Frontend HTTP (port 80) - ACME Challenge === | |||
Această secțiune descrie configurarea HAProxy pentru a permite generarea certificatelor Let’s Encrypt în ISPConfig atunci când HAProxy funcționează în modul SSL Passthrough. | |||
Pentru validarea HTTP‑01, traficul către <span style="">/.well-known/acme-challenge/</span> trebuie direcționat către backend-ul HTTP al ISPConfig. | |||
==== Frontend HTTP (ACME Challenge Forwarding) ==== | |||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | |||
--> frontend http_in | |||
    bind *:80 | |||
    mode http | |||
    acl letsencrypt-acl path_beg /.well-known/acme-challenge/ | |||
    use_backend letsencrypt-backend if letsencrypt-acl | |||
    default_backend ispconfig_http | |||
</code> | |||
* acl letsencrypt-acl path_beg - detectăm cererile ACME challenge | |||
* use_backend - Forward ACME challenge către backend-ul dedicat | |||
* default_backend - Restul traficului HTTP merge către backend-ul HTTP normal | |||
==== Backend HTTP (ACME Challenge Forwarding) ==== | |||
Backend dedicat pentru Let’s Encrypt. | |||
Acesta trebuie să trimită cererile către portul 80 al serverrelor ISPConfig. | |||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | |||
--> backend letsencrypt-backend | |||
    mode http | |||
    server isp1 192.168.14.11:80 check | |||
    server isp2 192.168.14.22:80 check | |||
    server isp3 192.168.14.33:80 check | |||
</code> | |||
==== Backend HTTP (trafic normal) ==== | |||
Backend-ul standard pentru HTTP (port 80), folosit pentru redirectări, panel ISPConfig, sau site-uri HTTP. | |||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | |||
--> backend ispconfig_http | |||
    mode http | |||
    balance roundrobin | |||
    option httpchk GET / | |||
    server isp1 192.168.14.11:80 check | |||
    server isp2 192.168.14.22:80 check | |||
    server isp3 192.168.14.33:80 check | |||
</code> | |||
== HAProxy cu SSL Passthrough și Mapări Dinamice Layer 7 == | |||
[[File:haproxyLayer7.png|782x616px|none|HAProxy Layer7]] | |||
Acest scenariu avansat descrie configurarea HAProxy ca un "Router Layer 7 (Content-Based Switch)". Această arhitectură permite consolidarea mai multor domenii și subdomenii complet diferite pe un singur IP public extern, rutând traficul dinamic către mașini virtuale (backend-uri) separate, fără ca HAProxy să decripteze traficul SSL/TLS (SSL Passthrough). | |||
=== Configurare Frontend-uri și Backend-uri Modulare === | |||
Fișierele sunt stocate modular în directorul inclus secundar (`conf.d/`). | |||
==== Configurare Frontend ==== | |||
Fișierele sunt stocate modular în directorul inclus secundar (`conf.d/`). | |||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | |||
--> # nano /etc/haproxy/conf.d/websites.cfg | |||
  | |||
 # FRONTEND HTTP - Port 80 (Cu suport ACME Challenge integrat dinamic) | |||
  | |||
 frontend fe_http | |||
    bind *:80 | |||
    mode http | |||
  | |||
    # Extrage stringul curat al domeniului (taie portul :80 trimis de unele browsere) | |||
    http-request set-var(txn.backend) req.hdr(host),field(1,:),lower,map(/etc/haproxy/maps/web-http.map) | |||
  | |||
    # Detecție trafic ACME Challenge (Let's Encrypt / ISPConfig) | |||
    acl is_acme path_beg /.well-known/acme-challenge/ | |||
  | |||
    # Securitate: Blocare 403 dacă domeniul nu există în map ȘI nu este o cerere ACME | |||
    http-request deny deny_status 403 if ! { var(txn.backend) -m found } !is_acme | |||
  | |||
    # Rutare: Trimite către backend-ul identificat în map | |||
    use_backend %[var(txn.backend)] if { var(txn.backend) -m found } | |||
  | |||
    # Fallback obligatoriu pentru procesarea automată a certificatelor ACME generate în ISPConfig | |||
    default_backend be_vm1_http | |||
  | |||
 # FRONTEND HTTPS - Port 443 (SSL Passthrough transparent pe bază de SNI) | |||
  | |||
 frontend fe_https | |||
    bind *:443 | |||
    mode tcp | |||
  | |||
    # Inspectează pachetele inițiale TCP pentru a citi header-ul TLS nesecurizat | |||
    tcp-request inspect-delay 5s | |||
    tcp-request content accept if { req.ssl_hello_type 1 } | |||
  | |||
    # Rutare Layer 4 bazată pe SNI-ul extras din handshake-ul TLS potrivit în map-ul HTTPS | |||
    use_backend %[req.ssl_sni,lower,map(/etc/haproxy/maps/web-https.map)] | |||
  | |||
    # Dacă domeniul accesat prin TLS nu există în map, conexiunea este respinsă direct | |||
    default_backend be_https_deny | |||
  | |||
</code> | |||
==== Configurare Backend ==== | |||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | |||
--> # nano /etc/haproxy/conf.d/websites.cfg | |||
  | |||
 # DEFINIRE BACKEND-URI SERVERE VIRTUALE | |||
  | |||
 # BACKEND-URI VM1 (192.168.14.11) | |||
 backend be_vm1_http | |||
    mode http | |||
    server vm1_web 192.168.14.11:80 check | |||
  | |||
 backend be_vm1_https | |||
    mode tcp | |||
    server vm1_ssl 192.168.14.11:443 check | |||
  | |||
 # BACKEND-URI VM2 (192.168.14.22) | |||
 backend be_vm2_http | |||
    mode http | |||
    server vm2_web 192.168.14.22:80 check | |||
  | |||
 backend be_vm2_https | |||
    mode tcp | |||
    server vm2_ssl 192.168.14.22:443 check | |||
  | |||
 # BACKEND-URI VM3 (192.168.14.33) | |||
 backend be_vm3_http | |||
    mode http | |||
    server vm3_web 192.168.14.33:80 check | |||
  | |||
 backend be_vm3_https | |||
    mode tcp | |||
    server vm3_ssl 192.168.14.33:443 check | |||
  | |||
 # BACKEND SIGURANȚĂ (DENY) | |||
 backend be_https_deny | |||
    mode tcp | |||
</code> | |||
=== Structură Fișiere Mapare Dinamică === | |||
Pentru a evita modificarea continuă a fișierului principal de configurare la adăugarea de noi domenii, folosim fișiere de mapare de tip cheie-valoare (*.map). | |||
==== Fișier Mapare HTTP (Port 80) ==== | |||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | |||
--> # nano /etc/haproxy/maps/web-http.map | |||
 # VM1 - 192.168.1.11 | |||
 domeniu.eu be_vm1_http | |||
 sub.domeniu.eu be_vm1_http | |||
 # VM2 - 192.168.1.22 | |||
 domeniu.com be_vm2_http | |||
 sub.domeniu.com be_vm2_http | |||
 # VM3 - 192.168.1.33 | |||
 domeniu.ro be_vm3_http | |||
 sub.domeniu.ro be_vm3_http | |||
</code> | |||
==== Fișier Mapare HTTPS (Port 443) ==== | |||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | |||
--> # nano /etc/haproxy/maps/web-https.map | |||
 # VM1 - 192.168.1.11 | |||
 domeniu.eu be_vm1_https | |||
 sub.domeniu.eu be_vm1_https | |||
 # VM2 - 192.168.1.22 | |||
 domeniu.com be_vm2_https | |||
 sub.domeniu.com be_vm2_https | |||
 # VM3 - 192.168.1.33 | |||
 domeniu.ro be_vm3_https | |||
 sub.domeniu.ro be_vm3_https | |||
</code> | |||
=== Integrare Modulară în Systemd (conf.d) === | |||
Pentru ca HAProxy să încarce automat toate fișierele de configurare din directorul secundar <tt>conf.d/</tt>, trebuie modificat scriptul de pornire al serviciului în Systemd. | |||
==== Modificarea fișierului de serviciu ==== | |||
Caută linia implicită de pornire și comenteaz-o | |||
Adaugă direct sub ea noua instrucțiune care include ambele căi de configurare ("haproxy.cfg" și directorul "conf.d/"). | |||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | |||
--> # nano /usr/lib/systemd/system/haproxy.service | |||
  | |||
 # ExecStart=/usr/sbin/haproxy -Ws -f $CONFIG -p $PIDFILE $EXTRAOPTS | |||
 ExecStart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d/ -p /run/haproxy.pid | |||
</code> | |||
==== Reîncărcarea și Aplicarea Modificărilor ==== | |||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | |||
--> # systemctl daemon-reload | |||
 # systemctl restart haproxy | |||
</code> | |||
==== Managementul Configurării ==== | |||
Unul dintre marile avantaje ale acestei arhitecturi este capacitatea de a aplica modificări fără a întrerupe sesiunile HTTP/HTTPS active ale utilizatorilor (Zero-Downtime). | |||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | |||
--> # haproxy -c -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d/ <span style="font-style: italic;color:#4d4d4d"># Validarea sintaxei</span> | |||
 # systemctl reload haproxy <span style="font-style: italic;color:#4d4d4d"># Reîncărcarea serviciului cu noua configurare</span> | |||
</code> | |||
== HAProxy pentru Baze de Date (MySQL / MariaDB) == | |||
Această secțiune descrie configurarea HAProxy în Modul TCP (Layer 4) pentru baze de date. Deoarece MySQL/MariaDB folosește un protocol binar propriu, HAProxy nu va inspecta conținutul pachetelor, ci doar va ruta conexiunile la nivel de port. | |||
=== Prerechizite: Utilizatorul de Health Check === | |||
Pentru ca HAProxy să poată verifica dacă serverele MySQL sunt "vii" (fără a deschide doar portul TCP orbește), trebuie creat un utilizator fără parole și fără privilegii pe serverul de baze de date. | |||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | |||
--> CREATE USER 'haproxy_check'@'192.168.14.11'; | |||
 FLUSH PRIVILEGES; | |||
</code> | |||
Se execută pe Master (dacă replicarea este pornită). | |||
=== Replicare Master/Slave === | |||
[[File:HaproxySQL_MS.png|782x616px|none|HAProxy Master-Slave]] | |||
Destinat infrastructurilor clasice Master/Slave. Aplicația folosește un singur punct de conexiune (db.domeniu.lan:3306). HAProxy trimite tot traficul către Master, în timp ce Slave-ul stă în așteptare (backup) și preia automat activitatea doar dacă Masterul intră în crash. | |||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | |||
-->''' # nano /etc/haproxy/haproxy.cfg''' | |||
  | |||
 # FRONTEND DATABASE (Master/Slave) | |||
 frontend fe_mysql_master_slave | |||
    bind *:3306 | |||
    mode tcp | |||
    default_backend be_mysql_master_slave | |||
  | |||
 # BACKEND DATABASE (Master/Slave) | |||
 backend be_mysql_master_slave | |||
    mode tcp | |||
    balance leastconn | |||
    option mysql-check user haproxy_check | |||
  | |||
    # Serverul Master - preia 100% din trafic în mod normal | |||
    server dbm 192.168.14.11:3306 check on-marked-down shutdown-sessions | |||
  | |||
    # Serverul Slave - preia traficul DOAR dacă dbm devine offline | |||
    server dbs 192.168.14.22:3306 check backup | |||
</code> | |||
* mode tcp - Obligatoriu pentru baze de date. Suprascrie modul HTTP implicit. | |||
* balance leastconn - Direcționează conexiunile noi către nodul cu cele mai puține sesiuni active. | |||
* option mysql-check user ... - Interoghează nativ serverul MySQL pentru a-i verifica starea. | |||
* on-marked-down shutdown-sessions - Dacă Masterul pică testul de sănătate, HAProxy taie instant toate conexiunile active/persistente din pool, forțând aplicația să se mute imediat pe Slave-ul de backup. | |||
* backup - Marchează serverul ca pasiv. Nu primește trafic atât timp cât nodul principal este online. | |||
=== Replicare Multi-Master / Multi-Node === | |||
[[File:HaproxySQL_MM.png|782x616px|none|HAProxy Multi-Master]] | |||
Destinat arhitecturilor sincrone de tip MariaDB Galera Cluster sau MySQL Group Replication. Deoarece toate cele 3 noduri pot accepta simultan operațiuni de scriere și citire (Read/Write), HAProxy va distribui conexiunile dinamic între toate mașinile virtuale. | |||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | |||
--> ''' # nano /etc/haproxy/haproxy.cfg''' | |||
  | |||
 # FRONTEND DATABASE (Multi-Master) | |||
 frontend fe_mysql_multimaster | |||
    bind *:3306 | |||
    mode tcp | |||
    default_backend be_mysql_multimaster | |||
  | |||
 # BACKEND DATABASE (Multi-Master) | |||
 backend be_mysql_multimaster | |||
    mode tcp | |||
    balance leastconn | |||
    option mysql-check user haproxy_check | |||
  | |||
    # Traficul este împărțit dinamic pe toate cele 3 noduri active | |||
    server db_node1 192.168.14.11:3306 check weight 1 | |||
    server db_node2 192.168.14.22:3306 check weight 1 | |||
    server db_node3 192.168.14.33:3306 check weight 1 | |||
</code> | |||
* Fără directiva backup - Toate nodurile sunt tratate ca primare și rulează în paralel. | |||
* balance leastconn - Esențial în Multi-Master. Deoarece interogările SQL au durate și eforturi complet diferite, algoritmul trimite conexiunile noi către cel mai liber server hardware în acea milisecundă, prevenind suprasaturarea unui singur nod. | |||
* weight 1 - Toate serverele au ponderi egale. Dacă un nod din cluster este mai puternic din punct de vedere hardware, îi puteți crește valoarea (ex: weight 2) pentru a-i aloca proporțional mai multe conexiuni. | |||
== Pagina de statistici HAProxy == | |||
<code class="mw-code mw-highlight plainlinks" style="display:block"><!-- | |||
--> ''' # nano /etc/haproxy/haproxy.cfg''' | |||
  | |||
 listen stats | |||
    bind *:9000 | |||
    mode http | |||
    stats enable | |||
    stats uri /stats | |||
    stats refresh 5s | |||
    stats auth admin:pass123 | |||
</code> | |||
* *bind :9000 – port dedicat pentru statistici. | |||
* stats uri /stats – URL-ul paginii. | |||
* stats auth – autentificare basic HTTP. | |||
==== Accesare pagina de statistici ==== | |||
http://192.168.14.123:9000/stats | |||
[[File:HAProxy stats.png|782x616px|none|HAProxy_stats]] | |||
Latest revision as of 03:11, 1 November 2026
HAProxy - Load Balancing Standard (Grup Unic Backend)[edit | edit source]

Instalare HAProxy[edit | edit source]
La instalare HAProxy activează serviciul systemd.
# apt -y install haproxy
Structura fișierului de configurare[edit | edit source]
Fișierul principal:
# nano /etc/haproxy/haproxy.cfg
Configurația este împărțită în:
- global – setări pentru procesul HAProxy
- defaults – setări implicite pentru toate secțiunile
- frontend – puncte de intrare pentru trafic
- backend – serverele către care se trimite traficul
Secțiunea global[edit | edit source]
global
log /dev/log local0
log /dev/log local1 notice
maxconn 4096
user haproxy
group haproxy
daemon
- log /dev/log local0 – trimite logurile către syslog.
- log /dev/log local1 notice – al doilea canal de log, nivel minim notice.
- maxconn 4096 – număr maxim de conexiuni simultane.
- user/group haproxy – rulează cu userul de sistem haproxy.
- daemon – rulează în background.
Secțiunea defaults[edit | edit source]
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5s
timeout client 30s
timeout server 30s
- log global – folosește setările din secțiunea global.
- mode http – modul implicit pentru frontend/backend.*
- option httplog – loguri detaliate HTTP.
- option dontlognull – nu loghează conexiuni goale.
- timeout connect/client/server – limite de timp pentru conexiuni.
* Dacă un frontend sau backend are propriul mode (ex: mode tcp), acesta suprascrie automat valoarea din defaults
Frontend HTTP (port 80)[edit | edit source]
frontend http_in
bind *:80
mode http
option forwardfor
default_backend http_webserver
- bind *:80 – ascultă pe portul 80.
- mode http – procesează header-ele HTTP.
- option forwardfor – adaugă X‑Forwarded‑For cu IP-ul real al clientului.
- default_backend http_webserver – trimite traficul către backend-ul HTTP.
Backend HTTP[edit | edit source]
backend http_webserver
mode http
balance leastconn
option httpchk GET /
server vm01 192.168.14.11:80 check
server vm02 192.168.14.22:80 check
server vm03 192.168.14.33:80 check
- mode http – backend-ul procesează HTTP.
- balance leastconn – trimite traficul către serverul cu cele mai puține conexiuni active.
- option httpchk GET / – health-check HTTP.
- server vm01/vm02/vm03 – cele trei VM.
HTTPS (port 443) cu SSL Termination în HAProxy[edit | edit source]
În această situaţie HAProxy gestionează certificatul.
Generare certificat Let’s Encrypt[edit | edit source]
Necesită port 80 public și domeniu valid.
Certbot, în modul --standalone, pornește un mini‑webserver intern pe portul 80 pentru a răspunde la challenge-ul HTTP‑01 de la Let’s Encrypt.
Dacă HAProxy este pornit, acesta ocupă portul 80 și Certbot nu poate porni serverul de validare, ceea ce duce la eșecul generării certificatului.
Instalare certbot
apt -y install certbot
Oprire temporară HAProxy
systemctl stop haproxy
Generare certificat
certbot certonly --standalone -d wiki.stradivart.ro
Creare fișier PEM pentru HAProxy
# mkdir -p /etc/haproxy/certs
# cat /etc/letsencrypt/live/wiki.stradivart.ro/fullchain.pem \
/etc/letsencrypt/live/wiki.stradivart.ro/privkey.pem \
> /etc/haproxy/certs/wiki.stradivart.ro.pem
# chmod 600 /etc/haproxy/certs/wiki.stradivart.ro.pem
Frontend HTTPS (SSL termination)[edit | edit source]
frontend https_in
bind *:443 ssl crt /etc/haproxy/certs/wiki.stradivart.ro.pem
mode http
option forwardfor
default_backend http_webserver
- *bind :443 ssl crt ... – HAProxy decriptează SSL.
- mode http – traficul devine HTTP după terminarea SSL.
- default_backend http_webserver – backend-ul HTTP unic.
Backend HTTPS (SSL termination)[edit | edit source]
În cazul SSL termination, backend-ul nu procesează trafic HTTPS.
HAProxy decriptează SSL în frontend, iar backend-ul primește trafic HTTP normal (non‑SSL).
De aceea backend-ul este identic cu backend-ul HTTP.
backend http_webserver
mode http
balance leastconn
option httpchk GET /
server vm01 192.168.14.11:80 check
server vm02 192.168.14.22:80 check
server vm03 192.168.14.33:80 check
- mode http – backend-ul procesează HTTP.
- balance leastconn – trimite traficul către serverul cu cele mai puține conexiuni active.
- option httpchk GET / – health-check HTTP.
- server vm01/vm02/vm03 – cele trei VM.
HTTPS (port 443) cu SSL Passthrough[edit | edit source]
Webserver-ul gestionează certificatul. HAProxy doar forward-ează pachetele SSL.
Frontend HTTPS (SSL passthrough)[edit | edit source]
frontend https_in
bind *:443
mode tcp
default_backend httpS_webserver
- *bind :443 – ascultă pe portul 443.
- mode tcp – HAProxy nu decriptează SSL.
- default_backend httpS_webserver – backend separat în modul TCP.
Backend HTTPS (SSL passthrough)[edit | edit source]
backend httpS_webserver
mode tcp
balance leastconn
server vm01 192.168.14.11:443 check
server vm02 192.168.14.22:443 check
server vm03 192.168.14.33:443 check
- mode tcp – forward transparent al pachetelor SSL.
- balance leastconn – distribuție inteligentă.
- server vm01/vm02/vm03 – VM-urile ISPConfig.
Frontend HTTP (port 80) - ACME Challenge[edit | edit source]
Această secțiune descrie configurarea HAProxy pentru a permite generarea certificatelor Let’s Encrypt în ISPConfig atunci când HAProxy funcționează în modul SSL Passthrough. Pentru validarea HTTP‑01, traficul către /.well-known/acme-challenge/ trebuie direcționat către backend-ul HTTP al ISPConfig.
Frontend HTTP (ACME Challenge Forwarding)[edit | edit source]
frontend http_in
bind *:80
mode http
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
use_backend letsencrypt-backend if letsencrypt-acl
default_backend ispconfig_http
- acl letsencrypt-acl path_beg - detectăm cererile ACME challenge
- use_backend - Forward ACME challenge către backend-ul dedicat
- default_backend - Restul traficului HTTP merge către backend-ul HTTP normal
Backend HTTP (ACME Challenge Forwarding)[edit | edit source]
Backend dedicat pentru Let’s Encrypt. Acesta trebuie să trimită cererile către portul 80 al serverrelor ISPConfig.
backend letsencrypt-backend
mode http
server isp1 192.168.14.11:80 check
server isp2 192.168.14.22:80 check
server isp3 192.168.14.33:80 check
Backend HTTP (trafic normal)[edit | edit source]
Backend-ul standard pentru HTTP (port 80), folosit pentru redirectări, panel ISPConfig, sau site-uri HTTP.
backend ispconfig_http
mode http
balance roundrobin
option httpchk GET /
server isp1 192.168.14.11:80 check
server isp2 192.168.14.22:80 check
server isp3 192.168.14.33:80 check
HAProxy cu SSL Passthrough și Mapări Dinamice Layer 7[edit | edit source]

Acest scenariu avansat descrie configurarea HAProxy ca un "Router Layer 7 (Content-Based Switch)". Această arhitectură permite consolidarea mai multor domenii și subdomenii complet diferite pe un singur IP public extern, rutând traficul dinamic către mașini virtuale (backend-uri) separate, fără ca HAProxy să decripteze traficul SSL/TLS (SSL Passthrough).
Configurare Frontend-uri și Backend-uri Modulare[edit | edit source]
Fișierele sunt stocate modular în directorul inclus secundar (`conf.d/`).
Configurare Frontend[edit | edit source]
Fișierele sunt stocate modular în directorul inclus secundar (`conf.d/`).
# nano /etc/haproxy/conf.d/websites.cfg
# FRONTEND HTTP - Port 80 (Cu suport ACME Challenge integrat dinamic)
frontend fe_http
bind *:80
mode http
# Extrage stringul curat al domeniului (taie portul :80 trimis de unele browsere)
http-request set-var(txn.backend) req.hdr(host),field(1,:),lower,map(/etc/haproxy/maps/web-http.map)
# Detecție trafic ACME Challenge (Let's Encrypt / ISPConfig)
acl is_acme path_beg /.well-known/acme-challenge/
# Securitate: Blocare 403 dacă domeniul nu există în map ȘI nu este o cerere ACME
http-request deny deny_status 403 if ! { var(txn.backend) -m found } !is_acme
# Rutare: Trimite către backend-ul identificat în map
use_backend %[var(txn.backend)] if { var(txn.backend) -m found }
# Fallback obligatoriu pentru procesarea automată a certificatelor ACME generate în ISPConfig
default_backend be_vm1_http
# FRONTEND HTTPS - Port 443 (SSL Passthrough transparent pe bază de SNI)
frontend fe_https
bind *:443
mode tcp
# Inspectează pachetele inițiale TCP pentru a citi header-ul TLS nesecurizat
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
# Rutare Layer 4 bazată pe SNI-ul extras din handshake-ul TLS potrivit în map-ul HTTPS
use_backend %[req.ssl_sni,lower,map(/etc/haproxy/maps/web-https.map)]
# Dacă domeniul accesat prin TLS nu există în map, conexiunea este respinsă direct
default_backend be_https_deny
Configurare Backend[edit | edit source]
# nano /etc/haproxy/conf.d/websites.cfg
# DEFINIRE BACKEND-URI SERVERE VIRTUALE
# BACKEND-URI VM1 (192.168.14.11)
backend be_vm1_http
mode http
server vm1_web 192.168.14.11:80 check
backend be_vm1_https
mode tcp
server vm1_ssl 192.168.14.11:443 check
# BACKEND-URI VM2 (192.168.14.22)
backend be_vm2_http
mode http
server vm2_web 192.168.14.22:80 check
backend be_vm2_https
mode tcp
server vm2_ssl 192.168.14.22:443 check
# BACKEND-URI VM3 (192.168.14.33)
backend be_vm3_http
mode http
server vm3_web 192.168.14.33:80 check
backend be_vm3_https
mode tcp
server vm3_ssl 192.168.14.33:443 check
# BACKEND SIGURANȚĂ (DENY)
backend be_https_deny
mode tcp
Structură Fișiere Mapare Dinamică[edit | edit source]
Pentru a evita modificarea continuă a fișierului principal de configurare la adăugarea de noi domenii, folosim fișiere de mapare de tip cheie-valoare (*.map).
Fișier Mapare HTTP (Port 80)[edit | edit source]
# nano /etc/haproxy/maps/web-http.map
# VM1 - 192.168.1.11
domeniu.eu be_vm1_http
sub.domeniu.eu be_vm1_http
# VM2 - 192.168.1.22
domeniu.com be_vm2_http
sub.domeniu.com be_vm2_http
# VM3 - 192.168.1.33
domeniu.ro be_vm3_http
sub.domeniu.ro be_vm3_http
Fișier Mapare HTTPS (Port 443)[edit | edit source]
# nano /etc/haproxy/maps/web-https.map
# VM1 - 192.168.1.11
domeniu.eu be_vm1_https
sub.domeniu.eu be_vm1_https
# VM2 - 192.168.1.22
domeniu.com be_vm2_https
sub.domeniu.com be_vm2_https
# VM3 - 192.168.1.33
domeniu.ro be_vm3_https
sub.domeniu.ro be_vm3_https
Integrare Modulară în Systemd (conf.d)[edit | edit source]
Pentru ca HAProxy să încarce automat toate fișierele de configurare din directorul secundar conf.d/, trebuie modificat scriptul de pornire al serviciului în Systemd.
Modificarea fișierului de serviciu[edit | edit source]
Caută linia implicită de pornire și comenteaz-o Adaugă direct sub ea noua instrucțiune care include ambele căi de configurare ("haproxy.cfg" și directorul "conf.d/").
# nano /usr/lib/systemd/system/haproxy.service
# ExecStart=/usr/sbin/haproxy -Ws -f $CONFIG -p $PIDFILE $EXTRAOPTS
ExecStart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d/ -p /run/haproxy.pid
Reîncărcarea și Aplicarea Modificărilor[edit | edit source]
# systemctl daemon-reload
# systemctl restart haproxy
Managementul Configurării[edit | edit source]
Unul dintre marile avantaje ale acestei arhitecturi este capacitatea de a aplica modificări fără a întrerupe sesiunile HTTP/HTTPS active ale utilizatorilor (Zero-Downtime).
# haproxy -c -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d/ # Validarea sintaxei
# systemctl reload haproxy # Reîncărcarea serviciului cu noua configurare
HAProxy pentru Baze de Date (MySQL / MariaDB)[edit | edit source]
Această secțiune descrie configurarea HAProxy în Modul TCP (Layer 4) pentru baze de date. Deoarece MySQL/MariaDB folosește un protocol binar propriu, HAProxy nu va inspecta conținutul pachetelor, ci doar va ruta conexiunile la nivel de port.
Prerechizite: Utilizatorul de Health Check[edit | edit source]
Pentru ca HAProxy să poată verifica dacă serverele MySQL sunt "vii" (fără a deschide doar portul TCP orbește), trebuie creat un utilizator fără parole și fără privilegii pe serverul de baze de date.
CREATE USER 'haproxy_check'@'192.168.14.11';
FLUSH PRIVILEGES;
Se execută pe Master (dacă replicarea este pornită).
Replicare Master/Slave[edit | edit source]

Destinat infrastructurilor clasice Master/Slave. Aplicația folosește un singur punct de conexiune (db.domeniu.lan:3306). HAProxy trimite tot traficul către Master, în timp ce Slave-ul stă în așteptare (backup) și preia automat activitatea doar dacă Masterul intră în crash.
# nano /etc/haproxy/haproxy.cfg
# FRONTEND DATABASE (Master/Slave)
frontend fe_mysql_master_slave
bind *:3306
mode tcp
default_backend be_mysql_master_slave
# BACKEND DATABASE (Master/Slave)
backend be_mysql_master_slave
mode tcp
balance leastconn
option mysql-check user haproxy_check
# Serverul Master - preia 100% din trafic în mod normal
server dbm 192.168.14.11:3306 check on-marked-down shutdown-sessions
# Serverul Slave - preia traficul DOAR dacă dbm devine offline
server dbs 192.168.14.22:3306 check backup
- mode tcp - Obligatoriu pentru baze de date. Suprascrie modul HTTP implicit.
- balance leastconn - Direcționează conexiunile noi către nodul cu cele mai puține sesiuni active.
- option mysql-check user ... - Interoghează nativ serverul MySQL pentru a-i verifica starea.
- on-marked-down shutdown-sessions - Dacă Masterul pică testul de sănătate, HAProxy taie instant toate conexiunile active/persistente din pool, forțând aplicația să se mute imediat pe Slave-ul de backup.
- backup - Marchează serverul ca pasiv. Nu primește trafic atât timp cât nodul principal este online.
Replicare Multi-Master / Multi-Node[edit | edit source]

Destinat arhitecturilor sincrone de tip MariaDB Galera Cluster sau MySQL Group Replication. Deoarece toate cele 3 noduri pot accepta simultan operațiuni de scriere și citire (Read/Write), HAProxy va distribui conexiunile dinamic între toate mașinile virtuale.
# nano /etc/haproxy/haproxy.cfg
# FRONTEND DATABASE (Multi-Master)
frontend fe_mysql_multimaster
bind *:3306
mode tcp
default_backend be_mysql_multimaster
# BACKEND DATABASE (Multi-Master)
backend be_mysql_multimaster
mode tcp
balance leastconn
option mysql-check user haproxy_check
# Traficul este împărțit dinamic pe toate cele 3 noduri active
server db_node1 192.168.14.11:3306 check weight 1
server db_node2 192.168.14.22:3306 check weight 1
server db_node3 192.168.14.33:3306 check weight 1
- Fără directiva backup - Toate nodurile sunt tratate ca primare și rulează în paralel.
- balance leastconn - Esențial în Multi-Master. Deoarece interogările SQL au durate și eforturi complet diferite, algoritmul trimite conexiunile noi către cel mai liber server hardware în acea milisecundă, prevenind suprasaturarea unui singur nod.
- weight 1 - Toate serverele au ponderi egale. Dacă un nod din cluster este mai puternic din punct de vedere hardware, îi puteți crește valoarea (ex: weight 2) pentru a-i aloca proporțional mai multe conexiuni.
Pagina de statistici HAProxy[edit | edit source]
# nano /etc/haproxy/haproxy.cfg
listen stats
bind *:9000
mode http
stats enable
stats uri /stats
stats refresh 5s
stats auth admin:pass123
- *bind :9000 – port dedicat pentru statistici.
- stats uri /stats – URL-ul paginii.
- stats auth – autentificare basic HTTP.
Accesare pagina de statistici[edit | edit source]
http://192.168.14.123:9000/stats
