2015-02-09 4 views
0

Я пытаюсь реализовать простой ограничение скорости системы с Nginx (v1.6.2)Nginx limit_req не работает

сайтов доступный/mysite.com:

limit_req_zone $binary_remote_addr zone=myzone:10m rate=2r/m; 

server { 
    listen      80; 
    server_name     mysite.com; 
    root      /var/www/vhosts/mysite.com; 
    error_log     [..]; 
    access_log     [..]; 

    include      conf.d/php-fpm.conf; 

    location =/{ 
     limit_req    zone=myzone burst=3 nodelay; 
     index     index.html; 
    } 

    location/{ 
     try_files    $uri =404; 
    } 

    location ^~ /pages { 
     include     conf.d/php-fpm.conf; 
     internal; 
    } 

    location = /email { 
     rewrite ^(.*)$   /pages/email.html; 
    } 

    location = /email/subscribe { 
     limit_req    zone=myzone burst=2 nodelay; 
     rewrite ^(.*)$   /pages/email.php?action=subscribe; 
    } 

    location ~ /api { 
     limit_req    zone=myzone burst=5 nodelay; 
     rewrite ^(.*)$   /pages/api.php; 
    } 
} 

конф. д/PHP-fpm.conf:

location ~ \.php$ { 
    if (!-f $document_root$fastcgi_script_name) { 
     return 404; 
    } 
    fastcgi_pass    unix:/var/run/php5-fpm.sock; 
    fastcgi_index    index.php; 
    fastcgi_param    SCRIPT_FILENAME $document_root$fastcgi_script_name; 
    fastcgi_split_path_info  ^(.+?\.php)(/.*)$; 
    fastcgi_param    PATH_INFO $fastcgi_path_info; 
    include      fastcgi_params; 
} 

nginx.conf: Ничего интересного, только
include sites-enabled/*;

Ограничение скорости / работает отлично. Я получаю сообщение об ошибке 503, если у меня слишком много запросов на эту страницу.
Проблема: ни /email/subscribe, /api, ни /api/test - это ограниченная ставка, и я не знаю почему. Нужно что-то делать с rewrite, но в чем проблема?
Любые идеи? Я все испробовал!

Обратите внимание: я изменил имена файлов и конечные точки URL.

+0

Вы слишком много вырезали из конфигурации –

+0

Я так не думаю. Там не так много, кроме server_name .. –

+0

Ну, ваше местоположение '/ test' переписывается в'/test.txt', и этот файл не соответствует 'location =/test', поэтому он обслуживается каким-либо другим местоположением (или по адресу _default_), который, очевидно, не содержит директивы limit_req. –

ответ

3

Проблема заключается в том, что запрос процесс Nginx в нескольких phases и переписывание фаза идет перед preaccess один (это где limit_req применяется). Поэтому в ваших конфигурационных запросах переписываются /pages/..., прежде чем у них будет шанс быть ограниченным. Чтобы этого избежать, вы либо должны оставаться в том же блоке местоположения после перезаписи (используя флаг break), либо немного взломать с помощью try_files.

Я предпочитаю первый вариант, так что ваш конфиг может выглядеть следующим образом:

limit_req_zone $binary_remote_addr zone=myzone:10m rate=2r/m; 

server { 
    listen      80; 
    server_name     mysite.com; 
    root      /var/www/vhosts/mysite.com; 
    error_log     [..]; 
    access_log     [..]; 

    include      conf.d/php-fpm.conf; 

    location =/{ 
     limit_req    zone=myzone burst=3 nodelay; 
     index     index.html; 
    } 

    location/{ 
     try_files    $uri =404; 
    } 

    location ^~ /pages { 
     include     conf.d/php-fpm.conf; 
     internal; 
    } 

    location = /email { 
     rewrite ^(.*)$   /pages/email.html; 
    } 

    location = /email/subscribe { 
     limit_req    zone=myzone burst=2 nodelay; 
     rewrite ^(.*)$   /pages/email.php?action=subscribe break; 
     fastcgi_pass   unix:/var/run/php5-fpm.sock; 
     fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name; 
     include     fastcgi_params; 
    } 

    location ~ /api { 
     limit_req    zone=myzone burst=5 nodelay; 
     rewrite ^(.*)$   /pages/api.php break; 
     fastcgi_pass    unix:/var/run/php5-fpm.sock; 
     fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name; 
     include     fastcgi_params; 
    } 
} 

Если вы идете с вторым вариантом, ваш конфиг будет немного чист, но немного Hacky. Мы будем использовать тот факт, что фаза try_files проходит после фазы limit_req и что try_files делает внутреннюю переадресацию на последний аргумент.

limit_req_zone $binary_remote_addr zone=myzone:10m rate=2r/m; 

server { 
    listen      80; 
    server_name     mysite.com; 
    root      /var/www/vhosts/mysite.com; 
    error_log     [..]; 
    access_log     [..]; 

    include      conf.d/php-fpm.conf; 

    location =/{ 
     limit_req    zone=myzone burst=3 nodelay; 
     index     index.html; 
    } 

    location/{ 
     try_files    $uri =404; 
    } 

    location ^~ /pages { 
     include     conf.d/php-fpm.conf; 
     internal; 
    } 

    location = /email { 
     rewrite ^(.*)$   /pages/email.html; 
    } 

    location = /email/subscribe { 
     limit_req    zone=myzone burst=2 nodelay; 
     try_files SOME_NONEXISTENT_FILE /pages/email.php?action=subscribe; 
    } 

    location ~ /api { 
     limit_req    zone=myzone burst=5 nodelay; 
     try_files SOME_NONEXISTENT_FILE /pages/api.php; 
    } 
} 
+0

Вау, это действительно единственный возможный способ? Я имею в виду, что это * действительно * хакерство .. :( –

Смежные вопросы