Multiple matching limit_req
Francis Daly
francis at daoine.org
Fri Jan 9 19:16:08 UTC 2015
On Fri, Jan 09, 2015 at 07:18:37PM +0530, Joyce Babu wrote:
Hi there,
> I would like to apply rate limiting based on 3 different criteria.
>
> 1. CDN should have rate limit of 100 r/s (identified by $http_host)
> 2. Whitelisted bots should have a rate limit of 15 r/s (identified by
> $http_user_agent)
> 3. All other users should have a rate limit of 5 r/s
>
> The rules should be applied in the above order of preference. If a rule
> matches two criteria, the earlier one should get applied. How can I ensure
> this?
You can't.
All limits that match are applied, which means that the most restrictive
one is seen.
What you *can* do is change your specification with that in mind, and
choose your keys so that they are empty when you do not want the limit
to apply.
> map $http_host $limit_cdn {
> default '';
> "cdn-cname.mydomain.com" $binary_remote_addr;
> }
> map $http_user_agent $limit_bot {
> default '';
> ~*(google|bing) $binary_remote_addr;
> }
Add the following variables with names that more closely resemble what they
are intended to do:
map $limit_cdn $limit_bot_not_cdn {
default '';
'' $limit_bot;
}
map $limit_cdn$limit_bot $limit_not_bot_not_cdn {
'' $binary_remote_addr;
default '';
}
And use those variables as the keys that you actually mean:
> limit_req_zone $limit_cdn zone=limit_cdn:1m rate=100r/s;
Leave that one as-is.
> limit_req_zone $limit_bot zone=limit_bot:1m rate=15r/s;
Change that to be
limit_req_zone $limit_bot_not_cdn zone=limit_bot:1m rate=15r/s;
> limit_req_zone $binary_remote_addr zone=limit_all:10m rate=5r/s;
Change that to be
limit_req_zone $limit_not_bot_not_cdn zone=limit_all:10m rate=5r/s;
> limit_req zone=limit_all burst=12;
> limit_req zone=limit_bot burst=50 nodelay;
> limit_req zone=limit_cdn burst=200 nodelay;
and the rest should work as you want.
(Unless you use "return".)
f
--
Francis Daly francis at daoine.org
More information about the nginx
mailing list