I'm a somewhat experienced Apache admin in a past life, but I've decided to take the plunge and learn nginx. So far everything seems fairly intuitive, but it's clear that I haven't quite internalized the nginx way of doing things yet so I'm fairly certain this is an easy problem to resolve, but I can't seem to find an obvious answer.

I have a server which uses the php-fpm server for PHP where I wish to restrict access to some subdirectories in my document root by source IP (e.g.: phpmyadmin, some test scripts I've written, etc.). For whatever reason the restriction I have in place appears to work fine for directories and files, but the PHP files served by the FastCGI server are apparently bypassing this access restriction. I've verified that this is the case by creating test files of different types in the restricted directory. Text and HTML files are indeed denied and return a 403, but the PHP files no matter their contents appear to be parsed and served back to the client.

Here are what I believe are the relevant sections of my site config:

# pass all PHP scripts to FastCGI server socket
location ~ \.php$ {
  # Filter out arbitrary code execution
  location ~ \..*/.*\.php$ {return 404;}
  fastcgi_index index.php;
  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  include fastcgi_params;
  fastcgi_pass unix:/var/run/php5-fpm.sock;

# allow access to tools pages as necessary
location ~ /tools/ {
  deny all;

There's more in the config but no directives that affect PHP files or the /tools/ location as far as I can tell. The behaviour I'm looking for is for all files under /tools/ to be restricted no matter the file type unless there is an explicit allow rule for the IP range in question.

Any light you can shed on this to point me in the right direction would be most welcome!


That's because nginx serves a request from one matching location block, not multiple. Also, nginx has a specific process to choose it, read my answer on a similar question or read the official documentation for the details.

I'm guessing that you are also using the index directive somewhere to tell nginx to serve an index.php file when entering tools directory or subdirectory and this directive triggers an internal redirect to the php location block where access isn't restricted.

You will need to use nested location blocks or use more specific regexs.

  • 1
    Thanks for the explanation. I started to stumble across the answer myself pretty much as soon as I posted the question... that's the way it always is! :) This clarifies things. I'm starting to get the feel of how nginx works now and it's becoming a lot more intuitive. I just need to stop trying to import my Apache knowledge quite so aggressively. – Gabriel Mar 20 '15 at 3:05

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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