Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm using Nginx with PHP-FPM, and I want to restrict access to a subdirectory of PHP files on my site so that only traffic from my IP address is allowed.

Here is what I have tried, assuming my IP is 1.1.1.1:

location ^~ /blocktest/
    {
            if ($remote_addr != "1.1.1.1")
            {
                    return 503;
            }
    }

This blocks the public, but PHP scripts are no longer executed for me, and I'm just prompted to download the raw file. So, I tried including my PHP configuration file in the block, like this:

location ^~ /blocktest/
    {
            if ($remote_addr != "1.1.1.1")
            {
                    return 503;
            }

            include /usr/local/nginx/conf/php.conf;
    }

...but then the public could access the PHP files again. Ugh. Any idea on how I could get this to work? Thanks!

For reference, here's my php.conf file:

location ~ \.php$ {
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;

    fastcgi_connect_timeout 60;
    #fastcgi_send_timeout 180;
    #fastcgi_read_timeout 180;
    fastcgi_send_timeout 2000;
    fastcgi_read_timeout 2000;
    fastcgi_buffer_size 256k;
    fastcgi_buffers 4 256k;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    fastcgi_intercept_errors on;

    fastcgi_param  PATH_INFO          $fastcgi_path_info;
    fastcgi_param  PATH_TRANSLATED    $document_root$fastcgi_path_info;

    fastcgi_param  QUERY_STRING   $query_string;
    fastcgi_param  REQUEST_METHOD     $request_method;
    fastcgi_param  CONTENT_TYPE   $content_type;
    fastcgi_param  CONTENT_LENGTH     $content_length;

    fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
    fastcgi_param  REQUEST_URI        $request_uri;
    fastcgi_param  DOCUMENT_URI   $document_uri;
    fastcgi_param  DOCUMENT_ROOT      $document_root;
    fastcgi_param  SERVER_PROTOCOL    $server_protocol;

    fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
    fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

    fastcgi_param  REMOTE_ADDR        $remote_addr;
    fastcgi_param  REMOTE_PORT        $remote_port;
    fastcgi_param  SERVER_ADDR        $server_addr;
    fastcgi_param  SERVER_PORT        $server_port;
    fastcgi_param  SERVER_NAME        $server_name;

    # PHP only, required if PHP was built with --enable-force-cgi-redirect
    fastcgi_param  REDIRECT_STATUS    200;
}
share|improve this question
add comment

2 Answers 2

nginx only processes one location, so you need to add the restriction in every location that you want to restrict. In your case you would have to create a second location to process PHP files in the subdirectory, similar to the first with the addition of your restriction.

share|improve this answer
    
But if it only matches one 'location', how would it ever reach the second? Nginx won't let you have two identical location directives. Could you provide a specific example of what this would look like? –  0Seven Oct 4 '13 at 16:45
    
It would begin with something like location ~ /blocktest/.*\.php { and contain your blocking directives and a more-or-less complete copy of the existing block. –  Michael Hampton Oct 4 '13 at 17:44
    
Hmm, I guess I still don't understand. Here's what I have now: pastebin.com/HRtCWnXc This blocks access to static files, but still lets the public execute the PHP scripts. –  0Seven Oct 4 '13 at 18:19
add comment
up vote 0 down vote accepted

I've figured this out. Apparently, the only way to actually prevent the PHP files from being processed by PHP-FPM is to use HttpAccessModule's "deny all", you can't just "return 503".

Here is a Nginx configuration snippet which defines a custom 503 error page and lets you block all public access to a subdirectory, including PHP files generated by PHP-FPM. You can define which IPs have access to the blocked subdirectory using the rules defined by the Nginx HttpAccessModule documentation.

# DEFINE CUSTOM 503 ERROR PAGE
error_page  503 /maintenance/503.htm;

location = /maintenance/503.htm
{
    internal;
}

# BLOCK A DIRECTORY
location ^~ /directory_to_block/
{
    error_page 403 =503 /maintenance/503.htm;

    allow 1.1.1.1; # your IP here
    deny all;

    include /usr/local/nginx/conf/php.conf;
}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.