Apply nginx rate limits to certain IP addresses, and another rate limit to others
In our Nginx config we currently have this:-
limit_req_zone $binary_remote_addr zone=two:10m rate=15r/m;
limit_req zone=two burst=5 nodelay;
Now we want to change this so that this rate limit applies to certain IP addresses, and then have another rate limit that applies to others that is slightly less restrictive.
geo $limited_net {
default 0;
111.222.333.444 1;
}
map $limited_net $addr_to_limit {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $addr_to_limit zone=two:10m rate=15r/m;
geo $less_limited_net {
default 1;
111.222.333.444 0;
}
map $less_limited_net $addr_to_limit {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $addr_to_limit zone=three:10m rate=25r/m;
So the traffic from the IP 111.222.333.444 will be affected by the rate 1st more restrictive rate limit, and not by the second less restrictive one.
We also use cloudflare and have the cloudflare ip addresses set in the /etc/nginx/cloudflare.conf similar to this https://support.cloudflare.com/hc/en-us/articles/200170706-How-do-I-restore-original-visitor-IP-with-Nginx-
Will this give me what I want?
Or should it be more like this?
geo $limited_net {
default 0;
111.222.333.444 1;
}
map $limited_net $addr_to_limit {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $addr_to_limit zone=two:10m rate=15r/m;
limit_req_zone $binary_remote_addr; zone=three:10m rate=25r/m;
Even though this question is old, it might be relevant for people stumbling across this in the future:
You can use multiple limit_req_zone directives to process requests from different sources at a different rate:
There could be several limit_req directives. For example, the following configuration will limit the processing rate of requests coming from a single IP address and, at the same time, the request processing rate by the virtual server:
limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;
limit_req_zone $server_name zone=perserver:10m rate=10r/s;
server {
...
limit_req zone=perip burst=5 nodelay;
limit_req zone=perserver burst=10;
}
These directives are inherited from the previous level if and only if there are no limit_req directives on the current level.
http://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req
after so much time of this question I have encountered this problem in a configuration,
this is correct, the only problem you have is you're checking the $addr_to_limit variable in every ratelimit instead of maped variables ($limited_net or $less_limited_net)
plus some details
the correct config should be:
geo $limited_net {
default 0;
111.222.333.444 1;
}
map $addr_to_limit1 $limited_net {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $limited_net zone=addr_to_limit1:10m rate=15r/m;
geo $less_limited_net {
default 1;
111.222.333.444 0;
}
map $addr_to_limit2 $less_limited_net {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $less_limited_net zone=addr_to_limit2:10m rate=25r/m;