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.