Потребовалось несколько часов, чтобы узнать, как правильно настроить NginX , но я все еще думаю, что мог что-то упустить. Главным образом потому, что эта отлично работающая установка вызывает больше вопросов, чем ответов. Возможно, это даже NginX NginX или что-то, представленное Debian в Version: 1.2.1-2.2+wheezy2 Package: nginx-extras , я просто не знаю.
Обратите внимание, что мой пример уже урезан до минимума (поэтому примите это как отправную точку), но он все равно должен содержать все необходимые текущие исправления безопасности.
Обратите внимание, что мне не нравится эвристика, склонная к ошибкам. Для этого он работает с /etc/php/fpm/pool.d/www.conf установленным таким образом, что php-fpm берет скрипт непосредственно из PATH_TRANSLATED вместо того, чтобы угадывать его:
php_admin_value[cgi.fix_pathinfo]=0
security.limit_extensions = .php
php_admin_flag[expose_php] = off
Вот php /home/tino/www/index.php который выводит переменные:
<?
header("content-type: text/plain");
$a = array("PATH_TRANSLATED", "SCRIPT_FILENAME", "DOCUMENT_URI", "PATH_INFO", "QUERY_STRING" );
foreach ($a as &$v)
printf("%-15s %s\n", $v, $_SERVER[$v]);
?>
Рабочая конфигурация NginX
Обратите внимание, что /home/tino/www - это место, где живет мой тестовый скрипт. И вы, возможно, захотите заполнить все остальные параметры из /etc/nginx/fastcgi_params . Например вам нужно
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
заполнить PHP_SELF .
server_tokens off;
server {
listen 80;
root /home/tino/www;
if ($request_uri ~ " ") { return 444; }
location ~ [^/]\.php(/|$) {
limit_except GET HEAD POST { deny all; }
fastcgi_split_path_info ^((?U).+\.php)(.*)$;
try_files $fastcgi_script_name =404;
set $wtf $fastcgi_path_info;
fastcgi_param PATH_INFO $wtf;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
}
}
Это дает мне следующий вывод для http://example.com/index.php/a.php?b=b.php
PATH_TRANSLATED /home/tino/www/index.php
SCRIPT_FILENAME /home/tino/www/index.php
DOCUMENT_URI /index.php
PATH_INFO /a.php
QUERY_STRING b=b.php
Это именно то, что я хочу. Обратите внимание, что это работает и для менее проблемных URI, конечно.
Не работающий конфиг
Тем не менее, прямая конфигурация не работает, и я действительно озадачен, почему:
server_tokens off;
server {
listen 80;
root /home/tino/www;
if ($request_uri ~ " ") { return 444; }
location ~ [^/]\.php(/|$) {
limit_except GET HEAD POST { deny all; }
fastcgi_split_path_info ^((?U).+\.php)(.*)$;
try_files $fastcgi_script_name =404;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
}
}
Это то же самое, что и выше, только обходной путь $wtf отсутствует:
set $wtf $fastcgi_path_info;
fastcgi_param PATH_INFO $wtf;
стал
fastcgi_param PATH_INFO $fastcgi_path_info;
Но это не работает, вывод для http://example.com/index.php/a.php?b=b.php теперь таков :
PATH_TRANSLATED /home/tino/www/index.php
SCRIPT_FILENAME /home/tino/www/index.php
DOCUMENT_URI /index.php
PATH_INFO
QUERY_STRING b=b.php
Как видите: PATH_INFO исчез. Это не имеет ничего общего с php-fpm , это чисто NginX !
Небезопасный конфиг работает снова
Следующая конфигурация, которая открывает большую дыру в безопасности из-за проверки отсутствующего файла, работает снова:
server_tokens off;
server {
listen 80;
root /home/tino/www;
if ($request_uri ~ " ") { return 444; }
location ~ [^/]\.php(/|$) {
limit_except GET HEAD POST { deny all; }
fastcgi_split_path_info ^((?U).+\.php)(.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
}
}
На http://example.com/index.php/a.php?b=b.php результат немного отличается (SCRIPT_FILENAME выглядит неправильно, DOCUMENT_URI может быть правильным с другой точки зрения).
PATH_TRANSLATED /home/tino/www/index.php
SCRIPT_FILENAME /home/tino/www/index.php/a.php
DOCUMENT_URI /index.php/a.php
PATH_INFO /a.php
QUERY_STRING b=b.php
Так пожалуйста
Очевидно, что try_files ломает способ $fastcgi_path_info после установки регулярного выражения с fastcgi_split_path_info .
Так, пожалуйста, кто-нибудь может сказать мне, если этот обходной путь $wtf действительно является правильным решением, или мне все еще нужно беспокоиться о дополнительных плохих побочных try_files?
Благодарю. (Если я пропустил важный бит безопасности, пожалуйста, прокомментируйте.)
