I have a Symfony app that I want to rate limit. I want a general limit and a limit for PHP requests. However only the general limit seems to apply.
Here's the config (the rate values are of course for testing purposes only):
limit_req_zone $binary_remote_addr zone=limit_zone_general:10m rate=2r/m;
limit_req_zone $binary_remote_addr zone=limit_zone_php:10m rate=1r/m;
server {
# ...
root /var/www/html/public;
index index.php;
limit_req zone=limit_zone_general;
limit_req_status 429;
location / {
error_page 404 /meta/404;
try_files $uri /index.php$is_args$args;
}
location ~ ^/index\.php(/|$) {
limit_req zone=limit_zone_php;
limit_req_status 429;
}
}
If I now call domain.local/ I would expect it to be callable only once per minute as there is no static document to serve and it should therefore call index.php and use it's limit. However the general limit applies and I can call it twice per minute.
Can anyone hint me towards what it is that I'm not getting right?
If a similar question has already been asked I'll gladly look there but so far my search hasn't brought up anything usable.
Edit: What I have treid so far:
- I've tried moving the general limit from the server block to the location block for / (because maybe the server definition "outranks" the location definition, but it doesn't)
- I've tried using different keys for the zones but this also doesn't change anything.
- Removing the general limit altogether. Now the php specific limit worked. So the limit itself is not faulty.
The reason it doesn't work seems to be that
limit_reg
only works once per request. So after the server block's limit is being applied, nginx doesn't care about other limits in other applicable locations. See this question: https://stackoverflow.com/q/27073091/1016033Thanks to Alexey Ten for hinting me to it.