1

This is sample configuration,

frontend fe_app

    bind 0.0.0.0:8484 name http
    acl has_auth_header req.fhdr(api-key) -m found



    acl mark_as_abuser       sc0_inc_gpc0(be_429_table_api) gt 10
    acl req_rate_api_abuse   sc0_http_req_rate(be_429_table_api) gt 10


    http-request set-header X-Concat %[req.fhdr(api-key)]_%[src] if has_auth_header
    http-request track-sc0 req.fhdr(X-Concat) table be_429_table_api if has_auth_header
    capture request header X-Concat len 100 

    use_backend be_429_slow_down if mark_as_abuser req_rate_api_abuse has_auth_header

    default_backend be_default

backend be_429_table_api
    stick-table type string size 100k expire 10s store http_req_rate(10s),http_req_cnt,gpc0,gpt0

backend be_429_slow_down
    timeout tarpit 10s
    http-request tarpit

And I tested with watch -n2 'echo "show table be_429_table_api" | socat stdio unix:/var/run/haproxy.sock'

The issue is upon receiving request gpc0 automatically starts increasing. Until table is expired. It doesn't seem to related to http_req_rate any way at all. What is the purpose of this counter then ?

I want a counter which only increases when http_req_rate >10. So when it goes over 3 ( i.e the offender repeats it for more than 3 time during 1 m) I can block. Something like following

1) 2:00:00 pm : http_req_rate > 10, abuae_counter =1

2) 2:00:07 pm: http_req_rate > 10, abuse_counter = 2

3) 2:00:17 pm : http_req_rate > 10 abuse_counter =3

4) 2:00:45 pm: http_req_rate > 10 abuse_counter =4 > Block

I can then simply use

use_backend be_429_slow_down if abuse_counter has_auth_header

How to achieve that ? I thought about using lua or set.var but nothing worked.

1 Answer 1

0

if you want a simple count with a big time slice, you can use

frontend website
    bind :80
    stick-table  type ip  size 100k  expire store http_req_rate(24h)
    http-request track-sc0 src
    http-request deny deny_status 429 if { sc_http_req_rate(0) gt 20 }
    default_backend servers

I removed the expires parameter from the stick table as from documentation:

A stick table record expires and is removed after a period of inactivity by the client, as set by the expire parameter. That’s just a way of freeing up space. Without an expire parameter, oldest records are evicted when the storage becomes full
2
  • Did you even read my question ? I don't want to do it for 24 hr, I want to do it per second. For the time being g let's say the time duration is 1m or 2m. I want to block if req rate is greater than the specified limit for more than 3 times. And even with your example it is still blocking the first time it crosses the rate limit ? So what's the point of 24 h or 10 h? Oct 16, 2019 at 6:31
  • I got it :) the count of count, if you are a bad bot now you need to bad1, bad2, bad3 and now you a big bad boy :)
    – c4f4t0r
    Oct 16, 2019 at 12:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .