HAProxy basic ddos protection and tricks


HAProxy is the defacto reverse proxy and loadbalancer. HAproxy has some very good mechanisms for basic DDos protection. In this read we are going to see 3 haproxy features that can save you time and headaches.

Let’s start

http request rate limiting

Any public api can become target for ddos attack or can be abused legaly from heavy traffic. Heavy traffic or an abuse might happen any time and for that reason an automatic mechanism to limit requests should be in place. In haproxy rate limiting per ip is very simple.

First we need to create a stick-table to store requests:

# Rate limit path
stick-table type ip size 100k expire 1h store http_req_rate(10s)

Then we need to create an acl for the path we want to rate limit:

# Check path /api
acl api path_beg /api

Then we need to command haproxy to store these request when they match our path:

# Track request ip if path matches
http-request track-sc0 src if api

If the requests per second exceed the limit they will be rate limited with an http 421 response:

# check request rate
acl abuse sc_http_req_rate(0) gt 1
# # Deny if exceeds limit
http-request deny deny_status 429 if abuse
# rate limit invites path ###

IP/Country blocking

Another very common use case is the desire to block a specific country or IP from accessing our website. To achieve that we need the following daily updated geoip map file from http://iwik.org/ipcountry/geoip.txt :

root@ha-proxy-0:~# wget http://iwik.org/ipcountry/geoip.txt -O /etc/haproxy/geoip.txt

You can update it daily or weekly using a cronjob:

echo '0 04 * * * wget http://iwik.org/ipcountry/geoip.txt -O /etc/haproxy/geoip.txt"' >> /etc/crontab

On the HAProxy config file we need to create an acl that will map ips to two letter coyntry codes: and an acl for specific ips we need to block manually:

acl is-blocked-country src,map_ip(/etc/haproxy/geoip.txt) -m reg -i (KP|IR|CU|SY|SD|MM)
acl is-blocked-ip src -f /etc/haproxy/blocklist.txt
http-request deny if is-blocked-ip or is-blocked-country

Should a client ip match the ip from the map or the blocklist.txt it will be denied access the requested page.

Custom Error Pages

HAProxy supports custom pages which can be very handy not only for design reasons but also for proper user experience. You can create a custom http 504/503 page and serve it as a diquised http 204 page. This can be handy for cases where something is down or very slow and you need to let the customer know it in more elegant way.

First lets a create a custom http response like bellow:

root@ha-proxy-0:~# cat /etc/haproxy/errors/custom-200.http
<!DOCTYPE html>
<html lang="en">
   <meta charset="utf-8" />
   <title>Site Under heavy traffic</title>
   The site is Under heavy traffic please bear with us.

Second lets configure HAProxy to serve that in case of a 504:

http-errors myerrors
    errorfile 503 /etc/haproxy/errors/custom-200.http
    errorfile 504 /etc/haproxy/errors/custom-200.http

frontend site1
    bind :80
    default_backend webservers
    errorfiles myerrors
    http-response return status 200 default-errorfiles if { status 504 }

Disclaimer: this is not a solution to slow responses but rather handy trick to buy some time.


Thanks for stopping by!

References: Country filtering


comments powered by Disqus