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 >