HAProxy (High Availability Proxy) is a free, open-source load balancer and proxy server designed to improve the performance, reliability, and security of web applications. It distributes traffic across servers to ensure high availability and scalability.
- Distributes traffic across backend servers (HTTP/TCP/UDP).
- Algorithms: Round Robin, Least Connections, Source IP Hash, and more.
- Automatic failover with health checks (active/passive).
- Removes failed servers from the pool.
- Acts as an intermediary for clients/servers.
- Offloads SSL/TLS encryption (HTTPS termination).
- Balances traffic at both transport and application layers.
- Uses ACLs (Access Control Lists) for rules based on:
- URL paths, headers, cookies, etc.
- Rate limiting, connection throttling.
- Basic WAF (Web Application Firewall) capabilities.
- Detailed logs for debugging.
- Integrates with Prometheus, StatsD, and Syslog.
- Handles millions of requests/sec with low latency.
- Multithreading for optimal CPU usage.
- HTTP/2, WebSockets, gRPC.
- Modify settings without restarting (via CLI/API).
- Web Application Load Balancing
- API Gateway & Microservices
- Database Load Balancing (MySQL, PostgreSQL)
- Kubernetes Ingress Controller
- DDoS Protection & Traffic Filtering
frontend http_front
bind *:80
mode http
default_backend http_back
backend http_back
balance roundrobin
server server1 192.168.1.10:80 check
server server2 192.168.1.11:80 check
assume that we have below test environments :
first we install nginx on both two ubuntu 24.04 servers and install haproxy on haproxy node .
now we copy config file for backup and then change the config file :
# sudo cp /etc/haproxy/haproxy.conf /etc/haproxy/haproxy.conf.back
# sudo vi /etc/haproxy/haproxy.conf
haproxy config has four main parts :
1- Global:
the main part for haproxy proccessing
2- defaults:
some defaults configuaraion like mode is store here . if in that file , we use other mode like tcp , tcp is the main mode and overwrite the default config on top of the file
3- frontend:
the part to define reverse proxy .
4- backend:
the pool of backnd server for answering requests .
note : for checking haproxy config we can use :
# sudo haproxy -c -f /etc/haproxy/haproxy.cfg
note: we have three timeout in default config:
1- timeout connect :
the time that haproxy check the backend server for up and running . if the backend server does not answer to haproxy , server failed and haproxy does not send data to it .
2- timeout client :
time wait for answering client to proccessed data to haproxy .
3- timeout server :
time wait for answering backend server to proccesses data to haproxy .
now we import below config and reload haproxy :
frontend http_front
bind *:80
mode http
default_backend http_back
backend http_back
balance roundrobin
server server1 192.168.1.59:80 check
server server2 192.168.1.12:80 check
# sudo systemctl reload haproxy
now based on roundrobin algorithm one request send to server 1 and next one send to server 2
You have two Nginx servers (web1
and web2
) behind an HAProxy load balancer.
Scenario: Route /blog
to web1 and /shop
to web2
frontend http_front
bind *:80
acl is_blog path_beg /blog
acl is_shop path_beg /shop
use_backend blog_servers if is_blog
use_backend shop_servers if is_shop
default_backend web_servers
backend blog_servers
server web1 192.168.1.10:80 check
backend shop_servers
server web2 192.168.1.11:80 check
backend web_servers
server web1 192.168.1.10:80 check
server web2 192.168.1.11:80 check
Scenario: Route internal network (192.168.1.0/24) to web1 only
frontend http_front
bind *:80
acl is_internal src 192.168.1.0/24
use_backend internal_servers if is_internal
default_backend web_servers
backend internal_servers
server web1 192.168.1.10:80 check
backend web_servers
server web1 192.168.1.10:80 check
server web2 192.168.1.11:80 check
Scenario: Block scanner user agents
frontend http_front
bind *:80
acl is_scanner hdr_sub(User-Agent) -i scanner
http-request deny if is_scanner
default_backend web_servers
backend web_servers
server web1 192.168.1.10:80 check
server web2 192.168.1.11:80 check
How It Works: hdr_sub(User-Agent) examines the User-Agent header
-i makes the match case-insensitive
Looks for the substring "scanner" in User-Agent
Common patterns to block:
acl is_scanner hdr_sub(User-Agent) -i (nmap|wget|curl|nikto|dirbuster)
acl is_bot hdr_sub(User-Agent) -i (bot|crawl|spider)
Scenario: Route based on preferred_server
cookie
frontend http_front
bind *:80
acl prefers_web1 cook(preferred_server) -m str -i web1
use_backend web1_servers if prefers_web1
default_backend web_servers
backend web1_servers
server web1 192.168.1.10:80 check
backend web_servers
server web1 192.168.1.10:80 check
server web2 192.168.1.11:80 check
Scenario: Block specific IP from /admin
frontend http_front
bind *:80
acl is_bad_ip src 192.168.1.100
acl is_admin path_beg /admin
http-request deny if is_bad_ip is_admin
default_backend web_servers
backend web_servers
server web1 192.168.1.10:80 check
server web2 192.168.1.11:80 check
Scenario: send request with special url param to one server
in this example if search ?region=east request goes to server 2 and search ?region=west request goes to server one
frontend http_front
bind *:80
acl urlparam1 url_param(region) -i -m str west
acl urlparam2 url_param(region) -i -m str east
use_backend web1 if urlparam1
use_backend web2 if urlparam2
default_backend web_servers
backend web1
server web1 192.168.1.10:80 check
backend web2
server web2 192.168.1.11:80 check
backend web_servers
server web1 192.168.1.10:80 check
server web2 192.168.1.11:80 check
β Define true/false conditions for traffic handling
β Combine multiple conditions with logical operators
β Support various matching criteria:
- IP addresses
- HTTP headers
- URL paths
- Cookies
- and more...
β Enable smart routing decisions
β Provide security controls
frontend http_in
bind *:80
mode http
redirect scheme https code 301 if !{ ssl_fc }
Listens on port 80 (HTTP).
Redirects all traffic to HTTPS.
Uses HTTP status code 301 (permanent redirect).
if !{ ssl_fc } ensures the redirect only applies if the request is not already SSL/TLS.
frontend http_in
bind *:80
mode http
acl is_old_url path_beg /oldpath
redirect location https://newdomain.com/newpath code 301 if is_old_url
Redirects requests from /oldpath to https://newdomain.com/newpath.
Uses an Access Control List (ACL) to match paths beginning with /oldpath.
frontend http_in
bind *:80
mode http
acl is_old_domain hdr(host) -i olddomain.com
redirect prefix https://newdomain.com code 301 if is_old_domain
Redirects all requests from olddomain.com to https://newdomain.com.
Preserves the original URI path.
Matches requests using the Host header.
we can use drop query to do this (prefix-drop-query):
nextsysadmin.com/path --> nextsysadmin.ir
it means all the path after url removed .