Skip to main content

Configuring HAProxy as Reverse Proxy (HTTP/HTTPS)

🌐 Overview

This guide shows how to configure HAProxy as an HTTP/HTTPS reverse proxy, with support for Let's Encrypt, load balancing, and sticky sessions. The configuration below is based on the standard SaveinCloud installation.


🧱 Configuration Structure

🔹 Global

global
log 127.0.0.1 local0
user haproxy
group haproxy
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 no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
ssl-default-server-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-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
ssl-dh-param-file /etc/haproxy/dhparam.pem
tune.ssl.default-dh-param 2048
pidfile /var/run/haproxy.pid
maxconn 10000
daemon

Explanation:

  • log: defines the log destination.
  • ssl-default-*: sets default security policies for SSL connections.
  • dhparam.pem: sets the Diffie-Hellman parameter for secure SSL (2048 bits).
  • maxconn: maximum number of simultaneous connections.
  • daemon: runs HAProxy as a background service.

🔸 Defaults

defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 10000

Explanation:

  • mode http: sets HTTP mode as default.
  • option httplog: enables detailed HTTP format logging.
  • timeout *: sets limits to avoid stuck connections.
  • redispatch: tries another backend if the current one fails.

📡 Frontend: Receiving Connections

frontend ft_http
bind :::80 v4v6
bind :::443 v4v6 ssl crt /var/lib/jelastic/SSL/jelastic.pem alpn h2,http/1.1
mode http

acl host_app1 hdr(host) -i app1.exemplo.com
acl host_app2 hdr(host) -i app2.exemplo.com

use_backend bk_app1 if host_app1
use_backend bk_app2 if host_app2

stats enable
stats auth admin:<senha>
stats refresh 30s
stats uri /haproxy_adm_panel
stats show-node
stats admin if TRUE

option forwardfor

http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header HTTPS on if { ssl_fc }
http-request set-header Ssl-Offloaded 1 if { ssl_fc }

default_backend bk_http

Explanation:

  • bind :::80 / :::443: listens on all IPv4/IPv6 interfaces on ports 80 (HTTP) and 443 (HTTPS).
  • ssl crt ...: uses certificate automatically generated by Let's Encrypt.
  • alpn: enables HTTP/2 support.
  • acl hdr(host): creates rules based on the accessed domain.
  • use_backend: routes traffic based on the corresponding ACL.
  • default_backend: used if no ACL is matched.
  • stats *: enables admin panel via /haproxy_adm_panel.
  • set-header: adds useful headers for backend (such as real HTTPS via proxy).

🧩 Default Backend (example with load balancing)

backend bk_http
mode http
cookie SRVNAME insert
balance roundrobin
server webserver1 10.100.75.251:${BACKEND_PORT} check cookie S1

Explanation:

  • mode http: explicit HTTP mode.

  • cookie SRVNAME insert: enables sticky sessions via cookie (client is kept on the same backend).

  • balance roundrobin: distributes requests evenly among servers.

  • server: defines the backend server.

    • check: enables health check.
    • cookie S1: value to be inserted in the cookie for sticky session.

🧩 Backend by Domain (Example with ACLs)

backend bk_app1
server app1_backend 10.0.0.101:80 check

backend bk_app2
server app2_backend 10.0.0.102:80 check

Explanation:

  • Allows separating traffic from different domains to distinct destinations.
  • Can be expanded with mode http, load balancing, and cookies as needed.

🔄 balance: Load Balancing Strategies

Defines how requests are distributed among backend servers.

balance roundrobin
ModeDescription
roundrobinDefault. Distributes requests sequentially.
leastconnGoes to the server with the fewest active connections.
sourceUses client IP as basis for persistence.
uriUses URL path to distribute requests.
hdr(name)Uses the value of an HTTP header (e.g., User-Agent).
rdp-cookieSpecific for balancing RDP sessions.

cookie SRVNAME insert
OptionDescription
insertAutomatically inserts the cookie in the response.
rewriteUses cookie received from the client.
prefixAdds server name at the beginning of the cookie.
indirectDoes not resend cookie if already present.
nocachePrevents caching of the cookie by intermediate proxies.

Each server must have a cookie identifier:

server app1 10.0.0.1:80 cookie A1 check

🌍 mode: Communication Types

Defines the type of protocol inspected on frontend/backend.

mode http
ModeDescription
httpDefault mode. Allows inspecting and manipulating HTTP headers.
tcpRaw mode. Ideal for protocols like MySQL, PostgreSQL, SMTP, etc.
healthUsed only for health checks.

🛑 Default Backend (fallback)

backend default
mode http
errorfile 503 /etc/haproxy/welcome.http

Explanation:

  • Used as fallback when no valid backends are available.
  • Serves a static 503 error file with a custom message.

🎯 Tips and Best Practices

  • Use maxconn to avoid overload on HAProxy.
  • The panel at /haproxy_adm_panel requires basic authentication — change the default password!
  • The Let's Encrypt certificate is automatically updated by the platform.
  • To redirect HTTP to HTTPS, you can use:
    redirect scheme https if !{ ssl_fc }

Place this at the beginning of frontend ft_http if you want to enforce HTTPS.


📘 Additional Documentation