frontend
/listen
: No name, only one nd only used in that sectionstick-table type ip ...
http-request track-sc0 src
track-sc0
increase counter index 0. track-sc
counter 1, and so on
stick-table type string ....
acl has_token url_param(token) -m found
acl exceeds_limit url_param(token),table_http_req_rate() gt ....
http-request track-sc0 url_param(token) unless exceeds_limit
http-request deny deny_status 429 if !has_token or exceeds_limit
....
http-request track-sc0 req.hdr(Host)
...
stick-table type binary len 20 size 100k expire 10s store http_req_rate(10s)
# Increase counter
# hash of (Host header + URL path + src IP)
http-request track-sc0 base32+src
# Lookup rate limit per URL stored in a map file, which is a text file of following
# /url/a 10
# /url/b 20
# /url/c 30
# If not found, use default value 20
#
http-request set-var(req.rate_limit) path,map_beg(/etc/haproxy/rates.map,20)
# Lookup the current counter from the stick table
http-request set-var(req.request_rate) base32+src,table_http_req_rate()
# Math: req.rate_limit - req.request_rate
acl rate_abuse var(req.rate_limit),sub(req.request_rate) lt 0
http-request deny deny_status 429 if rate_abuse
frontend ...
...
# SLIDING WINDOW
# storing:
# - a counter of average number of requests over 10 seconds. Multiple counters can be stored
# - per every IPv4 address
# - maximum 100x2^10 IPs. Old entries will be remored once full
# - unused IPs will be removed after 30 seconds
stick-table type ip size 100k expire 30s store http_req_rate(10s)
# enables tracking of sticky counters from current request
# - src: add client IP to the table
# - increase counter index 0 (src0)
http-request track-sc0 src
# get the first counter from the stick table (sc_http_req_rate(0), multiple counters can be stored)
# if more than 20 requests, deny
http-request deny deny_status 429 if { sc_http_req_rate(0) gt 20 }
...