Safer PHP
Setting up PHP is always a bit tricky, and you should consider some pitfalls. The example below should help get you on your way.
Website with many accessed PHP-files.
Most websites will host multiple applications (and not just a CMS). Therefore you will need something like the following:
server {
...
index index.php;
location / {
try_files $uri $uri/ /index.php?xxx...;
}
...
location ~ \.php$ {
# This splits the URI into two variables:
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# First, make a copy of $fastcgi_path_info, due to try_files
# making $fastcgi_path_info empty after doing the try_files.
set $path_info $fastcgi_path_info;
# For the sake of security, don't pass non-existing files.
try_files $fastcgi_script_name =404;
# 1) $fastcgi_script_name for SCRIPT_FILENAME
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# 2) The copied $fastcgi_path_info for PATH_INFO
fastcgi_param PATH_INFO $path_info;
# Include other environment defaults for FastCGI.
include fastcgi_params;
# This is the socket of the running PHP-FPM.
fastcgi_pass finalx:9000;
}
}
Websites with just one accessed PHP-file.
If you know that your entire website will be run through a single PHP-file (and its includes), like for example a CMS like Pagekit, you could use this instead.
Safer (can't access other scripts) and performing slightly better (no more need for try_files
).
Below an example:
server {
...
index index.php;
location / {
try_files $uri $uri/ /index.php?xxx...;
}
...
# The = in the location is an "exact"-identifier.
# Without it, it would be matching the 404 section below.
location = /index.php {
# This splits the URI into two variables:
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# 1) $fastcgi_script_name for SCRIPT_FILENAME
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# 2) $fastcgi_path_info for PATH_INFO
fastcgi_param PATH_INFO $fastcgi_path_info;
# Include other environment defaults for FastCGI.
include fastcgi_params;
# This is the socket of the running PHP-FPM.
fastcgi_pass finalx:9000;
}
# WARNING: Do not forget this or your PHP-scripts can be accessed
# directly and possibly expose code you don't want others to see.
# All other PHP-files should just return a "404 Not Found".
location ~ \.php$ {
# Use 404 and not 403, that way attackers will not be wiser as
# to the existence of a file and think it does not exist.
return 404;
}
}