I've been doing something similar for years. No need for fail2ban.

frontend fe-main
  acl host_dynamic hdr_dom(host) -i newgrounds.com
  acl limit_exceeded sc1_http_err_rate(be-dynamic) gt XXX
  tcp-request content track-sc1 src table be-dynamic if host_dynamic
  use_backend be-rate-limit if limit_exceeded
  use_backend be-dynamic if host_dynamic

backend be-rate-limit
  # haproxy normally returns a 503 but we want to return a 429 here.
  errorfile 503 /etc/haproxy/errorfiles/429.http
  # This may flood your error logs, so you can set this:
  # http-request set-log-level silent

backend be-dynamic
  stick-table type ipv6 size 100k expire 1m store
http_err_rate(1m),http_req_rate(1m)
  # other stuff

Hope this helps!

--
Brendon Colby
Senior DevOps Engineer
Newgrounds.com

On Wed, Jan 23, 2019 at 9:19 AM Marco Colli <collimarc...@gmail.com> wrote:
>
> Hello!
>
> I use HAProxy in front of a web app / service and I would like to add DDoS 
> protection and rate limiting. The problem is that each part of the 
> application has different request rates and for some customers we must accept 
> very hight request rates and burst, while this is not allowed for 
> unauthenticated users for example. So I was thinking about this solution:
>
> 1. Based on advanced conditions (e.g. current user) our Rails application 
> decides whether to return a normal response (e.g. 2xx) or a 429 (Too Many 
> Requests); it can also return other errors, like 401
> 2. HAProxy bans clients if they produce too many 4xx errors
>
> What do you think about this solution?
> Also, is it correct to use HAProxy directly or it is more performant to use 
> fail2ban on HAProxy logs?
>
> This is the HAProxy configuration that I would like to use:
>
> frontend www-frontend
>   tcp-request connection reject if { src_http_err_rate(st_abuse) ge 5 }
>   http-request track-sc0 src table st_abuse
>   ...
>   default_backend www-backend
>
> backend www-backend
>   ...
>
> backend st_abuse
>   stick-table type ipv6 size 1m expire 10s store http_err_rate(10s)
>
>
>
> Do you think that the above rules are correct? Am I missing something?
> Also, is it correct to mix *tcp*-request and src_*http*_err_rate in the 
> frontend?
> Is it possible to include only the 4xx errors (and not 5xx) in http_err_rate?
>
>
> Any suggestion would be greatly appreciated
> Thank you
> Marco Colli
>

Reply via email to