简体   繁体   中英

Nginx Location Block - Exclude Specific PHP File

I have the following Nginx server block for a site on a clients server cluster:

# Create shared memory zone for managing requests from IP's. Request rate set at 60 requests per minute, equates to 1 per second.
# Any quicker than this and nginx will serve 404, instead of the resource.
limit_req_zone $binary_remote_addr zone=xmlrpc:10m rate=60r/m;

# Create shared memory zone for managing active connections. Works almost the same as above. Not currently using this.
limit_conn_zone $binary_remote_addr zone=addr:10m;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  REMOVED;
        root         /var/www/REMOVED/html;
        client_max_body_size 20M;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/ *.conf;

        location / {
        #root         /var/www/REMOVED/html;
        index  index.php index.htm index.html;
        proxy_read_timeout 200;
        #try_files $uri $uri/ =404;
        try_files $uri $uri/ /index.php?$args;
        include /var/www/REMOVED/html/nginx.conf;
        }

        location /xmlrpc.php {
        limit_req zone=xmlrpc;
        #limit_conn addr 10;#DO NOT USE
        }

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        location ~ \.php$ {
                root           /var/www/REMOVED/html;
                fastcgi_pass   127.0.0.1:9000;
                fastcgi_index  index.php;
                fastcgi_read_timeout 200;
                fastcgi_param  SCRIPT_FILENAME   $document_root$fastcgi_script_name;
                include        fastcgi_params;
        }

        location ~ ^/(status|ping)$ {
        access_log off;
        allow 127.0.0.1;
        allow 10.10.10.0/24;
        allow 10.10.33.11;
        deny all;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass 127.0.0.1:9000;
        }

        error_page 404 /404.html;
            location = /404.html {
        }

        error_page 500 /500.html;
            location = /500.html {
        }
    }

The area of interest here is the top few lines where I am attempting to limit the number of requests in a given time frame for a single given IP address to a single resource. Specifically I am trying to limit the number of requests per second from 1 IP to xmlrpc.php in a wordpress installation.

If I create a test htm file and change the location block from xmlrpc.php to testfile.htm, this all works as intended, any requests that are more frequent that 1 per second, get blocked and hit a 404 instead. However, if i make the location block xmlrpc.php, it doesn't work, I can still hit domain.com/xmlrpc.php all I want, and I'm never blocked.

I use php-fpm to process all PHP requests, Nginx acts only as a proxy for PHP files as you can see. The location ~ \\.php$ { location block deals with that.

My current theory is that the xmlrpc.php requests, as they are not directly processed and served by Nginx, are ignoring the requests limit that is set within Nginx.

Is there a way I can exclude xmlrpc.php from the main location ~ \\.php$ { location, so they are effected by the request limitations, but the xmlrpc.php file still works as intended when accessed in a legitimate way? Thanks.

Resolved. The issue was that nginx continued to process the location blocks and used the catch all .php files one. Ignoring my original xmlrpc.php one.

I used the "=" operator to seek exact match to /xmlrpc.php, hence causing nginx to stop processing more location blocks after it had matched that one.

My final location block ended up looking like this:

    location = /xmlrpc.php {
    limit_req zone=xmlrpc;
    #limit_conn addr 10;#DO NOT USE
            root           /var/www/REMOVED/html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_read_timeout 200;
            fastcgi_param  SCRIPT_FILENAME   $document_root$fastcgi_script_name;
            include        fastcgi_params;
    }

This has been tested and verified, works fine. Thanks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM