I'm routing everything through an index.php file. I don't want anyone to have access directly to php files in my /var/www/html directory except index.php.
I have this to disable access to php files:
location ~ /*.php {
return 404;
}
But unfortunately I still get a 404 for my index.php file.
I'm using the following to route everything through index.php:
location / {
try_files $uri $uri/ /index.php?$args;
}
How can I get both of these to work simultaneously?
CodePudding user response:
With your configuration you return HTTP 404 Not Found for any request containing php
substring at all:
'/*' '.' 'php'
| | |
| | --- 'php' substring
| ---------- any single char
----------------- 0 or more '/' chars
I don't think it is really what you mean writing it. The right regex pattern to match anything ending with .php
is the \.php$
one. Check PCRE regex patterns syntax for an additional info.
To match all PHP files except index.php
you can use exact match location (which have precedence over a regex matching location):
location / {
try_files $uri $uri/ /index.php?$args;
}
location = /index.php {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
fastcgi_pass <your_PHP-FPM_backend>;
}
location ~ \.php$ { # will be used for any PHP request except 'index.php'
return 404;
}
The same can be achieved using ^~
location modifier. If the longest matching prefix location has the ^~
modifier then regular expressions are not checked:
location / {
try_files $uri $uri/ /index.php?$args;
}
location ^~ /index.php {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
fastcgi_pass <your_PHP-FPM_backend>;
}
location ~ \.php$ { # will be used for any PHP request except 'index.php'
return 404;
}
If you have multiply index.php
files in different directories, previous solutions won't work and you'll need to use two regex matching locations instead:
location / {
index index.php;
try_files $uri $uri/ /index.php?$args;
}
location ~ /index\.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass <your_PHP-FPM_backend>;
}
location ~ \.php$ { # will be used for any PHP request except 'index.php'
return 404;
}
This is the only configuration where location blocks order matters. location ~ /index\.php$ { ... }
should be the first or any PHP file request will be blocked with the location ~ \.php$ { ... }
one.
Check location
directive description and How nginx processes a request documentation page for more info. You can also check Nginx redirect all traffic to index.php, but don't allow arbitrary file access SO thread for some additional examples.