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.

# On Aloha, the global section is already setup for you
# and the haproxy stats socket is available at /var/run/haproxy.stats
  stats socket ./haproxy.stats level admin

  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
  stats enable
  stats hide-version
  stats uri     /
  stats realm   HAProxy Statistics
  stats auth    admin:admin

frontend ft_web

  # 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 check cookie srv1 maxconn 100
  server srv2 check cookie srv2 maxconn 100

# Static objects
backend bk_web_static
  balance roundrobin
  server srv1 check maxconn 1000
  server srv2 check maxconn 1000