how to create a reverse proxy with haproxy

Panoramica

Scoprite come impostare un reverse proxy con HAProxy su un VPS per nascondere il vostro IP di origine reale, migliorare le prestazioni e proteggere le vostre applicazioni da terzi. Come creare un reverse proxy con HAProxy per nascondere l’IP del server di origine reale?


Che cos’è un reverse proxy?

Un reverse proxy si colloca tra i client e i vostri server. Riceve le richieste in arrivo, decide dove inviarle e restituisce le risposte, mantenendo i vostri server di origine nascosti dalla rete pubblica. Può anche bilanciare il caricosu più backend, aggiungere intestazioni di sicurezza, limitare la velocità dei client abusivi e centralizzare la terminazione TLS (HTTPS). Consideratelo come un buttafuori intelligente: indirizza le persone verso le stanze giuste, ma mantiene il backstage privato.

In breve, un reverse proxy è il cavallo di battaglia silenzioso che fa funzionare tutto senza intoppi mentre la vostra origine rimane privata


Proxy inverso con HAProxy: Come funziona

HAProxy è un potente proxy L4/L7 e un bilanciatore di carico. Le richieste dei clienti arrivano prima a HAProxy, dove

  • TLS (HTTPS) può essere terminato.
  • Vengono aggiunte intestazioni come X-Forwarded-For, X-Forwarded-Proto e X-Forwarded-Host.
  • Il traffico viene instradato ai backend in base al nome dell’host, al percorso o a regole personalizzate.
  • Sono disponibili controlli sullo stato di salute, failover automatico, limiti di velocità, compressione, cache leggera, WebSocket e gRPC pass-through.
  • I registri dettagliati e una pagina di statistiche in tempo reale consentono di osservare la situazione.

In conclusione: HAProxy semplifica l’architettura, aumenta la sicurezza e le prestazioni e rende semplice la scalabilità


Pro e contro di HAProxy

Pro (perché HAProxy brilla)

  • Prestazioni elevate e basso overhead (event-driven, multi-thread).
  • Intelligenza L4 + L7 (passthrough TCP/SNI o routing/ritiro HTTP completo).
  • Robusto bilanciamento del carico e controlli sullo stato di salute (round-robin, leastconn, hashing; controlli attivi, failover).
  • Funzioni di sicurezza (terminazione TLS, HSTS, ACL, limitazione della velocità tramite stick-tables, IP allow/deny).
  • Osservabilità (registri ricchi, statistiche live socket/pagina; esportatori Prometheus disponibili).
  • Affidabilità (ricariche graziose, quasi a tempo zero; testato in battaglia).
  • Ingombro ridotto (funziona praticamente ovunque: Linux/BSD/container).

Contro (compromessi)

  • Curva di apprendimento (configurazione potente ma verbosa).
  • Automazione della certificazione non integrata (da abbinare a Certbot/lego o all’API Data Plane).
  • Individuazione manuale dei servizi per impostazione predefinita (i backend dinamici necessitano di modelli/API).
  • Caching/static serving integrato limitato (usare CDN/Varnish/Nginx se necessario).
  • Nessun WAF comunitario nativo (utilizzare un WAF separato o HAProxy Enterprise).
  • Le riscritture complesse possono risultare molto laboriose.
  • Supporto Windows limitato (meglio su Linux/BSD).

Cosa vi serve

  • Un server VPS/pubblico per HAProxy (il reverse proxy).
  • Il vostro server di origine (ad esempio, 10.0.0.10:8080).
  • Un dominio (ad esempio, example.com) con DNS A/AAA che punta all’IP pubblico del server HAProxy.

Suggerimento per la privacy: per nascondere veramente l’IP di origine, assicuratevi che l’origine non sia raggiungibile pubblicamente, che sia protetto da un firewall per accettare traffico solo dal server HAProxy e che non ci siano record DNS che rivelino l’origine


Passo 1 – Installare HAProxy

Ubuntu/Debian

sudo apt update sudo apt install -y haproxy

RHEL/Alma/Rocky

sudo dnf install -y haproxy

Passo 2 – Ottenere un certificato TLS (Let’s Encrypt)

Lasciamo che sia Certbot a ottenere un certificato e lo mettiamo in bundle con HAProxy

Installare certbot e ottenere il certificato (una sola volta)

# Ubuntu/Debian sudo apt install -y certbot sudo certbot certonly --standalone -d example.com --agree-tos -m you@example.com --non-interactive

Creare il bundle PEM di HAProxy (fullchain + privkey)

sudo mkdir -p /etc/haproxy/certs sudo bash -c 'cat /etc/letsencrypt/live/example.com/fullchain.pem  /etc/letsencrypt/live/example.com/privkey.pem  > /etc/haproxy/certs/example.com.pem' sudo chmod 600 /etc/haproxy/certs/example.com.pem

Ricaricare automaticamente HAProxy ai rinnovi

sudo bash -c 'cat >/etc/letsencrypt/renewal-hooks/deploy/haproxy.sh' <<'EOF' #!/usr/bin/env bash cat /etc/letsencrypt/live/example.com/fullchain.pem  /etc/letsencrypt/live/example.com/privkey.pem  > /etc/haproxy/certs/example.com.pem systemctl reload haproxy EOF sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/haproxy.sh

Passo 3 – Configurazione minima di HAProxy pronta per la produzione (HTTPS + redirect)

Sostituire example.com e l’IP/porta del backend dove indicato.

# /etc/haproxy/haproxy.cfg global log /dev/log local0 maxconn 50000 daemon defaults log global mode http option httplog timeout connect 5s timeout client 60s timeout server 60s http-reuse safe # Frontend: ascolto su 80/443, reindirizzamento su HTTPS, instradamento del traffico ACME e delle app frontend fe_https bind :80 bind :443 ssl crt /etc/haproxy/certs/example.com.pem alpn h2,http/1.1 # Forzare lo schema di reindirizzamento HTTPS http-request https unless { ssl_fc } # Intestazione di sicurezza di base http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" if { ssl_fc } # Preservare le informazioni sul client per la propria app option forwardfor header X-Forwarded-For http-request set-header X-Forwarded-Proto https if { ssl_fc } http-request set-header X-Forwarded-Host %[req.hdr(host)] # Semplice rate cap: 100 richieste / 10s per IP stick-table type ip size 100k expire 10m store http_req_rate(10s) http-request track-sc0 src acl too_fast sc0_http_req_rate gt 100 http-request deny status 429 if too_fast # Route ACME HTTP-01 challenges to local certbot (used during renewals) acl acme path_beg /.well-known/acme-challenge/ use_backend be_acme if acme # Indirizza il dominio al backend di origine acl host_example hdr(host) -i example.com use_backend be_app if host_example default_backend be_app # Backend: il vostro server di origine backend be_app balance leastconn option httpchk GET /health http-check expect status 200 server app1 10.0.0.10:8080 check # Backend per servire le sfide ACME (certbot standalone hook) backend be_acme server local 127.0.0.1:8081

Perché funziona

  • HAProxy termina il TLS su :443 e reindirizza :80 → HTTPS.
  • Il traffico regolare va all’origine 10.0.0.10:8080.
  • Solo /.well-known/acme-challenge/* viene indirizzato a un piccolo server web locale che Certbot eseguirà durante i rinnovi.

Passo 4 – Avviare, ricaricare e convalidare

# Convalidare la configurazione sudo haproxy -c -f /etc/haproxy/haproxy.cfg # Abilitare e avviare sudo systemctl enable --now haproxy # Ricaricare dopo modifiche/rinnovi sudo systemctl reload haproxy

Passo 5 – Rinnovi a mani libere

Lasciare che Certbot si leghi brevemente a :8081 mentre HAProxy mantiene aperto :80/:443:

# Tipicamente gestito dal timer di systemd; sicuro da eseguire manualmente per i test sudo certbot renew --deploy-hook "/etc/letsencrypt/renewal-hooks/deploy/haproxy.sh"  --http-01-port 8081 --pre-hook "systemctl start haproxy" --post-hook "systemctl start haproxy"

Durante il rinnovo, Certbot risponde alla sfida sulla porta 8081; HAProxy instrada già quel percorso a 127.0.0.1:8081


Varianti (scegliete quello che vi serve)

A) Origini multiple per nome di host

# Aggiungere nel frontend: acl host_api hdr(host) -i api.example.com use_backend be_api if host_api # Definire un backend API: backend be_api balance roundrobin option httpchk GET /healthz server api1 10.0.0.21:9000 check server api2 10.0.0.22:9000 check

B) TLS passthrough (l’origine gestisce TLS/mTLS)

Utilizzare la modalità TCP con instradamento SNI. Nessuna riscrittura delle intestazioni o funzionalità L7.

frontend fe_tcp mode tcp bind :443 tcp-request inspect-delay 5s tcp-request content accept if { req_ssl_hello_type 1 } use_backend be_tls_app if { req_ssl_sni -i example.com } backend be_tls_app mode tcp server app_tls 10.0.0.10:443 check

C) Proxy inverso minimo solo HTTP (senza TLS)

Solo per uso interno/test, utilizzare HTTPS per la produzione.

global log /dev/log local0 defaults mode http log global option httplog timeout connect 5s timeout client 60s timeout server 60s frontend public_http bind :80 option forwardfor default_backend app backend app server app1 10.0.0.10:8080 check

Controlli rapidi e risoluzione dei problemi

# Il DNS dovrebbe puntare a HAProxy dig +short example.com # HTTP dovrebbe reindirizzare a HTTPS (301) curl -I http://example.com # HTTPS dovrebbe servire il contenuto curl -I https://example.com # Vedere le intestazioni che l'applicazione riceve (nei log dell'applicazione): # X-Forwarded-For, X-Forwarded-Proto, X-Forwarded-Host

Consigli per il firewall

  • Bloccare l’origine in modo che accetti solo il traffico dal server HAProxy (ad esempio, con ufw, firewalld o gruppi di sicurezza del cloud).
  • Bloccare facoltativamente l’accesso pubblico diretto all’IP di origine a livello di provider.

Note finali

  • Mantenere timeout ragionevoli per i carichi di lavoro (WebSockets/gRPC potrebbero richiedere tempi più alti).
  • Esporre un endpoint /health nella propria applicazione per httpchk.
  • Pianificare distribuzioni a tempo zero: svuotare un server(disattivato) durante le distribuzioni, quindi riattivarlo.

Avviso importante:nel caso in cui non si sia sicuri di come configurare correttamente il server, si consiglia vivamente di rivolgersi a un professionista per completare la configurazione. È essenziale assicurarsi che tutte le impostazioni siano eseguite in modo accurato, compreso il controllo delle porte del firewall per verificare che non vi siano blocchi delle porte. È importante avere almeno una conoscenza di base dei firewall e dei comandi Linux per poter eseguire il processo di configurazione in modo efficace. Si prega di notare che non siamo responsabili per eventuali danni o problemi che possono derivare dal processo di configurazione. Tutte le informazioni fornite qui sono solo a scopo di conoscenza tecnica e di apprendimento. Grazie per la vostra comprensione