In a recent article, we saw how we can use a load-balancer as a first row of defense against DDOS.

The purpose of the present article to provide a configuration to protect your applications against HTTP request flood.

The configuration below allows only 10 requests per source IP over a period of 10s for the dynamic part of the website.
If the user go above this limit, it gets blacklisted until he stops browsing the website for 10 seconds.
HAProxy would return him a 403 for requests over an established connection and would refuse any new connection from this user.

[sourcecode language=”text”]
# On Aloha, the global section is already setup for you
# and the haproxy stats socket is available at /var/run/haproxy.stats
global
stats socket ./haproxy.stats level admin

defaults
option http-server-close
mode http
timeout http-request 5s
timeout connect 5s
timeout server 10s
timeout client 30s

# On Aloha, you don’t need to set up the stats page, the GUI already provides
# all the necessary information
listen stats
bind 0.0.0.0:8880
stats enable
stats hide-version
stats uri /
stats realm HAProxy Statistics
stats auth admin:admin

frontend ft_web
bind 0.0.0.0:8080

# Use General Purpose Couter (gpc) 0 in SC1 as a global abuse counter
# Monitors the number of request sent by an IP over a period of 10 seconds
stick-table type ip size 1m expire 10s store gpc0,http_req_rate(10s)
tcp-request connection track-sc1 src
# refuses a new connection from an abuser
tcp-request content reject if { src_get_gpc0 gt 0 }
# returns a 403 for requests in an established connection
http-request deny if { src_get_gpc0 gt 0 }

# Split static and dynamic traffic since these requests have different impacts on the servers
use_backend bk_web_static if { path_end .jpg .png .gif .css .js }

default_backend bk_web

# Dynamic part of the application
backend bk_web
balance roundrobin
cookie MYSRV insert indirect nocache

# If the source IP sent 10 or more http request over the defined period,
# flag the IP as abuser on the frontend
acl abuse src_http_req_rate(ft_web) ge 10
acl flag_abuser src_inc_gpc0(ft_web) ge 0
# Returns a 403 to the abuser
http-request deny if abuse flag_abuser

server srv1 192.168.1.2:80 check cookie srv1 maxconn 100
server srv2 192.168.1.3:80 check cookie srv2 maxconn 100

# Static objects
backend bk_web_static
balance roundrobin
server srv1 192.168.1.2:80 check maxconn 1000
server srv2 192.168.1.3:80 check maxconn 1000
[/sourcecode]

Links