I have been struggling to get this rate-limiting configuration to work on HAProxy. As seen below I am attempting to use “sc2_get_gpc0” to get a second value stored in the hour_hold stick table. This gpc value is incremented every time a request is made when a client has already hit the standard rate limit. This value is supposed to stay in the table for the expiration time of 1 hour. I can’t seem to get the acl to find that the value is greater than 0 and block connections after the standard rate limit “is_abuse” has passed 20 seconds without a rate of requests higher than the 10 requests in 20 seconds limit.
backend hour_hold
stick-table type binary len 8 size 100k expire 60m store gpc0
backend backend
stick-table type binary len 8 size 100k expire 60m store http_req_rate(20s)
http-request track-sc1 base32+src table backend
http-request set-var(req.rate_limit) path,map_beg(/usr/local/etc/haproxy/rates.map,10)
http-request set-var(req.request_rate) base32+src,table_http_req_rate(backend)
acl is_abuse var(req.rate_limit),sub(req.request_rate) lt 0
http-request track-sc2 base32+src table hour_hold if is_abuse
http-request sc-inc-gpc0(2) if is_abuse
# acl inc_abuse_cnt sc2_inc_gpc0(hour_hold) gt 0
acl abuse_cnt sc2_get_gpc0(hour_hold) gt 0
http-request deny deny_status 429 if is_abuse or abuse_cnt
# http-request deny deny_status 429 if abuse_cnt
# http-request deny deny_status 429 if is_abuse inc_abuse_cnt