I'm trying to limit requests with nginx based on response status code. I'd like to slow down requests with too many 4xx or 5xx responses. I have this code block in my config file:
map $status $bad_guy {
~^[23] "";
default $binary_remote_addr;
}
limit_req_zone "$bad_guy" zone=badguy:10m rate=1r/s;
server {
limit_req zone=badguy burst=20;
It seems that the above config block all IP addresses sending more than 1 rps, including those with only 200 OK responses.
Could you help me please? Why do the above config not work? Do I have to use something else (maybe openresty?) to achieve this? Thank you.
Best Answer
This is quite tricky because the $status variable is empty when declaring the limit_req_zone. The $status is only known after nginx has processed the request. For example after a proxy_pass directive.
The closest I could get to achieve rate limiting by status is doing the following:
The drawback is that this way you must return a different status code then the proxy pass response.