HAProxy Security Hardening: DDoS Protection, SSL & Rate Limiting (2025 Checklist)
A practical, step-by-step guide to hardening HAProxy for production: configure DDoS mitigation, enforce modern TLS, implement rate limiting with stick tables, block malicious traffic, and monitor for attacks. Includes a 15-point security checklist and copy-paste config snippets.
HAProxy Security Checklist (15 Points)
Use this as your audit checklist. Each item is covered in detail below with config examples.
SSL/TLS
DDoS
Hardening
Monitoring
1. SSL/TLS Hardening
SSL misconfiguration is responsible for a significant portion of web security incidents. HAProxy gives you full control over TLS settings — use it.
Enforce TLS 1.2+ and Modern Cipher Suites
Add these settings to your global section:
global
# Enforce minimum TLS version
ssl-default-bind-options ssl-min-ver TLSv1.2 no-sslv3 no-tls-tickets
# Modern cipher suites (ECDHE only - provides forward secrecy)
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
# Same settings for server-side connections
ssl-default-server-options ssl-min-ver TLSv1.2 no-sslv3 no-tls-tickets
ssl-default-server-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256Add HSTS and Security Headers
frontend web_frontend
bind *:443 ssl crt /etc/ssl/certs/site.pem alpn h2,http/1.1
# HSTS - tells browsers to always use HTTPS
http-response set-header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
# Additional security headers
http-response set-header X-Frame-Options "DENY"
http-response set-header X-Content-Type-Options "nosniff"
http-response set-header X-XSS-Protection "1; mode=block"
http-response set-header Referrer-Policy "strict-origin-when-cross-origin"
# Remove server information
http-response del-header Server
http-response del-header X-Powered-ByOCSP Stapling
frontend web_frontend
bind *:443 ssl crt /etc/ssl/certs/site.pem \
crt-ignore-err all \
alpn h2,http/1.1 \
ocsp-update on2. DDoS Mitigation with Stick Tables
HAProxy's stick tables are its most powerful DDoS mitigation tool. They allow you to track connection counts, request rates, and other metrics per client IP — and automatically block abusive clients.
TCP-Layer Connection Rate Limiting
This stops connection floods before HAProxy even parses the HTTP request:
frontend web_frontend
bind *:443 ssl crt /etc/ssl/certs/site.pem
# Track connection count per IP (TCP layer)
tcp-request connection track-sc0 src table conn_per_ip_tracker
tcp-request connection reject if { sc_conn_cur(0) gt 100 }
tcp-request connection reject if { sc_conn_rate(0) gt 200 }
backend conn_per_ip_tracker
stick-table type ip size 100k expire 30s store conn_cur,conn_rate(3s)HTTP Request Rate Limiting
After TCP connection is established, track HTTP request rates per IP:
frontend web_frontend
bind *:443 ssl crt /etc/ssl/certs/site.pem
mode http
# Track request rate per IP
http-request track-sc0 src table req_rate_tracker
# Deny if more than 100 requests in 10 seconds
http-request deny deny_status 429 if { sc_http_req_rate(0) gt 100 }
# Whitelist your own IPs
acl is_trusted_ip src 10.0.0.0/8 192.168.0.0/16
http-request allow if is_trusted_ip
backend req_rate_tracker
stick-table type ip size 100k expire 30s store http_req_rate(10s),http_err_rate(10s)Automatic IP Banning
For persistent attackers, implement automatic banning with a longer ban table:
frontend web_frontend
bind *:443 ssl crt /etc/ssl/certs/site.pem
mode http
# Check the ban table first
http-request deny deny_status 403 if { src,table_gpc0(ban_table) gt 0 }
# Track error rates - if >50 errors in 3 minutes, add to ban table
http-request track-sc1 src table ban_table
http-request sc-inc-gpc0(1) if { sc_http_err_rate(1) gt 50 }
backend ban_table
stick-table type ip size 100k expire 24h store gpc0,http_err_rate(3m)3. Blocking Bad Bots and Scanners
A significant portion of attack traffic comes from known malicious scanners, vulnerability tools, and bad bots. Block them at the edge with User-Agent ACLs:
frontend web_frontend
bind *:443 ssl crt /etc/ssl/certs/site.pem
mode http
# Block known malicious scanners
acl bad_bot hdr_sub(user-agent) -i sqlmap nikto masscan zgrab nmap dirbuster
acl bad_bot hdr_sub(user-agent) -i python-requests curl libwww-perl
acl empty_ua hdr_len(user-agent) eq 0
# Deny empty user agents (bots often omit them)
http-request deny if empty_ua !{ path /health /metrics }
http-request deny if bad_botNote: Be careful blocking curl and python-requests — these are also used by legitimate monitoring tools. Only block them if they're actually causing you problems.
4. Slow HTTP Attack Prevention
Slow HTTP attacks (like Slowloris) tie up server connections by sending requests extremely slowly. Configure timeouts to protect against them:
defaults
# Connection must complete within 5 seconds
timeout connect 5s
# Client must send headers within 10 seconds
timeout http-request 10s
# No more than 30 seconds between keep-alive requests
timeout http-keep-alive 15s
# Kill connections idle for more than 30 seconds
timeout client 30s
timeout server 30s
# Tunnel timeouts for WebSockets
timeout tunnel 3600s5. Hardening HAProxy Process Security
Run as Non-Root
global
user haproxy
group haproxy
daemon
# Restrict to single process (better for stick tables)
nbthread 4
cpu-map auto:1/1-4 0-3Restrict the Stats Endpoint
frontend stats
bind *:8404
stats enable
stats uri /haproxy-stats
stats realm "HAProxy Statistics"
stats auth admin:$(openssl rand -base64 16)
stats hide-version
# Only allow from internal network
acl internal_network src 10.0.0.0/8 172.16.0.0/12
http-request deny unless internal_network6. Hardened HAProxy Config (Complete Example)
Here is a production-ready, hardened haproxy.cfg incorporating all the security measures above:
global
log /dev/log local0
maxconn 100000
user haproxy
group haproxy
daemon
nbthread 4
# TLS hardening
ssl-default-bind-options ssl-min-ver TLSv1.2 no-sslv3 no-tls-tickets
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
defaults
log global
mode http
option httplog
option dontlognull
option forwardfor
option http-server-close
timeout connect 5s
timeout http-request 10s
timeout http-keep-alive 15s
timeout client 30s
timeout server 30s
# Connection rate tracker (TCP layer)
backend conn_rate_backend
stick-table type ip size 200k expire 30s store conn_cur,conn_rate(3s)
# HTTP request rate tracker
backend http_rate_backend
stick-table type ip size 200k expire 30s store http_req_rate(10s),http_err_rate(3m)
# Ban table for persistent offenders
backend ban_backend
stick-table type ip size 100k expire 24h store gpc0
frontend web_frontend
bind *:80
bind *:443 ssl crt /etc/ssl/certs/site.pem alpn h2,http/1.1
# Redirect HTTP to HTTPS
http-request redirect scheme https unless { ssl_fc }
# TCP-layer rate limiting
tcp-request connection track-sc0 src table conn_rate_backend
tcp-request connection reject if { sc_conn_rate(0) gt 200 }
# Check ban list
http-request deny status 403 if { src,table_gpc0(ban_backend) gt 0 }
# HTTP request rate limiting
http-request track-sc1 src table http_rate_backend
http-request deny status 429 if { sc_http_req_rate(1) gt 100 }
http-request sc-inc-gpc0(2) if { sc_http_err_rate(1) gt 50 }
# Block bad bots
acl bad_bot hdr_sub(user-agent) -i sqlmap nikto masscan zgrab nmap
http-request deny if bad_bot
# Security headers
http-response set-header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
http-response set-header X-Frame-Options "DENY"
http-response set-header X-Content-Type-Options "nosniff"
http-response del-header Server
http-response del-header X-Powered-By
default_backend web_servers
backend web_servers
balance roundrobin
option httpchk GET /health HTTP/1.1
http-check expect status 200
server app1 10.0.0.1:8080 check inter 2s fall 3 rise 2
server app2 10.0.0.2:8080 check inter 2s fall 3 rise 2
server app3 10.0.0.3:8080 check inter 2s fall 3 rise 27. Monitoring for Security Events
A hardened config is only as good as your ability to detect attacks in progress. Set up Prometheus metrics to alert on:
- Sudden spikes in 4xx/5xx error rates
- Connection rate increases (>2x normal baseline)
- Stick table entries approaching capacity
- Backend server health check failures
frontend prometheus
bind *:8405
http-request use-service prometheus-exporter if { path /metrics }
http-request deny unless { path /metrics }Pair this with our cloud infrastructure monitoring setup for full Prometheus + Grafana alerting on your load balancer.
Frequently Asked Questions
How do I configure HAProxy for DDoS protection?
Use stick tables to track connection and request rates per IP, then use tcp-request connection reject and http-request deny rules to block IPs that exceed your thresholds. The complete config example above shows the full implementation.
How do I enable TLS 1.3 in HAProxy?
Add "ssl-default-bind-options ssl-min-ver TLSv1.2" to the global section and use TLS 1.3 cipher suites in ssl-default-bind-ciphersuites. HAProxy 2.0+ supports TLS 1.3 natively via OpenSSL 1.1.1+.
Under attack or concerned about security?
Our team has hardened HAProxy for companies handling millions of requests per day. We implement DDoS protection, rate limiting, and full security monitoring.
Need Production-Grade HAProxy Security?
PentaSynth implements HAProxy security hardening including DDoS protection, rate limiting, TLS 1.3 enforcement, and 24/7 monitoring. Part of our DevOps & Cloud infrastructure service.
Talk to Our Security Team