1

I want configure different rate limiting for php-fpm.

I want to:

  1. static files had no limits,
  2. PHP requests had limits,
  3. PHP requests to / admin /.+ had different limits.

I have problem with implementation point 3. Now I test:

limit_req_zone $binary_remote_addr zone=php:10m rate=2r/s;
limit_req_zone $binary_remote_addr zone=admin:10m rate=9r/s;

server {
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
    limit_req_status 429;
# limitng works, server return 404
    location ~ /admin/ {limit_req zone=admin...}

    location ~ [^/]\.php(/|$) {
        limit_req zone=php burst=9 delay=4;
#limit_req not allowed here
        if($request_uri ~ /admin) {limit_req zone=admin...}
#not update limits (lower)
        location ~ ^/admin/ {limit_req zone=admin...}
#negative matching returns index.php content
        location location ~ ^/(?!(admin)) {limit_req zone=php...}
    }
}

Also is limit_req_zone $request_uri but if I understand, this create different pools for /admin/1 and /admin/2.

//update 1:

I need different pools for request like: /index.php?/.* and less strict for /index.php?/admin/.*

bato3
  • 143
  • 1
  • 7

2 Answers2

4

According to the limit_req_zone directive documentation:

Requests with an empty key value are not accounted.

So just use two limit_req directives in your PHP handler location and made one of the zone keys empty depending on the $request_uri (either first or second request limit rate won't be applied in this case):

map $request_uri $is_admin {
    ~^/admin/  1;
    default    0;
}
map $is_admin $php_key {
    0 $binary_remote_addr;
    # an empty value otherwise by default
}
map $is_admin $admin_key {
    1 $binary_remote_addr;
    # an empty value otherwise by default
}

limit_req_zone $php_key zone=php:10m rate=2r/s;
limit_req_zone $admin_key zone=admin:10m rate=9r/s;

server {
    ...
    location ~ [^/]\.php(/|$) {
        limit_req zone=php ...
        limit_req zone=admin ...
        ...
Ivan Shatsky
  • 2,726
  • 2
  • 7
  • 19
0

According to documetation limit_req is allowed only in http, server, location.

I would suggest to exclude 1 & 2 and have common location with same policy as for / and admin :

server {
listen 127.0.0.1:8088;
location / {
content_by_lua_block {
    ngx.say("root")
    ngx.exit(ngx.HTTP_OK)

}
}
location ~* .(jpg|jpeg|gif|png|ico|css|bmp|swf|js|html|txt)$ {
content_by_lua_block {
    ngx.say("static")
    ngx.exit(ngx.HTTP_OK)

}
}
location ~* "^\/admin($|\/(.*)$)" {
content_by_lua_block {
    ngx.say("processed by php with first ratelimit")
    ngx.exit(ngx.HTTP_OK)

}
}
location ~* "\.php$" {
content_by_lua_block {
    ngx.say("processed by php with second ratelimit")
    ngx.exit(ngx.HTTP_OK)

}
}
}

And tests:

# curl 127.0.0.1:8088/admin
processed by php with first ratelimit
# curl 127.0.0.1:8088/admin.php
processed by php with second ratelimit
# curl 127.0.0.1:8088/admin/
processed by php with first ratelimit
# curl 127.0.0.1:8088/admin/test.php
processed by php with first ratelimit
# curl 127.0.0.1:8088/test/php
root
user2986553
  • 390
  • 1
  • 4
  • We didn't understand each other. Route `/admin/` must be processed by php, but should have a different rate-limiting. – bato3 Sep 06 '19 at 13:05
  • I updated my unswer with test codeblock – user2986553 Sep 06 '19 at 13:14
  • Sorry, I can't find the solution into to your answer. I have the situation: `/index.php?/some` - rate-limiting-1 and `/index.php?/admin` - less-strict-rate-limiting – bato3 Sep 06 '19 at 13:34
  • I didn;t get properly from first time) Updated once more – user2986553 Sep 06 '19 at 13:36
  • Yup for `location ~* "^\/admin($|\/(.*)$)" ` limiting work OK, but php not. I can't imagine repeating the entire `php` section. I also considered using `include`, but I don't really like to split the domain configuration into 2 files. – bato3 Sep 06 '19 at 13:45
  • 1
    yes in such case you will need to duplicate your php configuration inside 2 locations or create a separate file and include it. – user2986553 Sep 06 '19 at 13:59
  • Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/98367/discussion-between-user2986553-and-bato3). – user2986553 Sep 06 '19 at 14:08