limit_req and @named locations

Maxim Dounin mdounin at mdounin.ru
Tue Sep 24 14:38:32 UTC 2013


Hello!

On Tue, Sep 24, 2013 at 09:12:54AM -0400, robw wrote:

> Hi list
> 
> I am experiencing some problems with a rate-limiting setup.
> 
> I have a "global" limit_req declared in my http block.
> 
> I also have additional limit_req declarations in various locations, both
> @named and unnamed, to provide proper protection to different backend
> endpoints.
> 
> It seems that additional limit_req is working fine in unnamed locations, but
> being ignored in @named locations.
> 
> I've linked to an example config exhibiting the problem:
> https://gist.github.com/anonymous/bf347d5302b3463f970b
> 
> If I remove the limit_req in the http block, the @dynamic limit_req works
> perfectly. If I enable limit_req in the http block, the @dynamic limit_req
> is ignored. In both cases, the limit_req in the unnamed location works
> perfectly!
> 
> Am I approaching this in the wrong way? How can I make limit_req work
> properly in the @dynamic location?

The limit_req directives are executed only once per request 
lifetime.  If a request was checked against any limits configured 
in a location - regardless of future internal redirects further 
limits won't be checked.  This is a simple way to protect requests 
from checking against the same limits again and again after 
redirections.

In your configuration limit_req STATIC_LIMIT_REQ is checked for 
all requests matching location /, and requests are redirected to 
@dynamic location via try_files only after this.

There are two basic ways to fix things:

1) Select a location before limit_req's are executed.  Recommended 
way is to use separate URL prefixes and use prefix string 
locations, like you already do with /admin.  (Alternatively, you 
may also use return + error_page to switch to a named location as 
rewrite module directives are executed before limit_req's, but 
this kind of defeats simplicity of try_files.)

2) Avoid using any limits in locations which aren't a final match.  
This is essentially what happens if you remove the limit_req in the 
http block.

-- 
Maxim Dounin
http://nginx.org/en/donation.html



More information about the nginx mailing list