Назад | Перейти на главную страницу

nginx, php-fpm и несколько корней - как правильно try_files?

У меня есть контекст сервера, который основан на приложении входа в систему. Приложение входа в систему обрабатывает, ну, входы в систему, а затем возвращает перенаправление на «/ app» на том же сервере, если вход в систему был успешным. Приложение находится в другом месте, что обрабатывается блоком местоположения, показанным здесь:

location ^~ /app {
        alias /usr/share/nginx/www/website.com/content/public;
        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_pass unix:/tmp/php5-fpm.sock;
                include fastcgi_params;
        }
}

Это работает нормально, однако $ uri, передаваемый в PHP, все еще содержит /app, хотя я использую псевдоним, а не root. Из-за этого try_files директива не соответствует 404 если я не свяжу app -> ./ в /usr/share/nginx/www/website.com/content/public.

Очевидно, глупо иметь там эту ссылку, и если эта ссылка когда-нибудь потеряется, сайт мертв без очевидной причины.

Следующее, что я попробовал ...

Было удалить try_files директива целиком. Это позволило мне rm в app ссылка в моем /public папка, и у PHP не было проблем с поиском файла и его запуском. Я использовал это, чтобы сбросить $_SERVER global из PHP и обнаружил, что "SCRIPT_FILENAME" => "/usr/share/nginx/www/website.com/content/public/index.php" когда URI браузера /app.

Это совершенно верно. На основе моих fastcgi_params ниже, это привело меня к мысли, что try_files $request_filename =404; должно работать, но без кубиков. nginx по-прежнему не находит файл и возвращает 404.

Так что сейчас это будет работать только без try_files директива. PHP находит файл, а try_files - нет. Я понимаю, что это может быть угрозой безопасности PHP. Может кто подскажет, как двигаться дальше? Насколько я могу судить, журналы nginx не содержат ничего, связанного с неудачной попыткой try_files.

fastcgi_aparams

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_FILENAME     $request_filename;
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;

fastcgi_param   HTTPS           $server_https;

Чтобы заставить его работать, fastcgi_param SCRIPT_FILENAME $request_filename необходимо скопировать в блок местоположения, например:

location ^~ /app {
        alias /usr/share/nginx/www/website.com/content/public;
        location ~ \.php$ {
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $request_filename;

                fastcgi_pass unix:/tmp/php5-fpm.sock;
                try_files $uri =404; 
                # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
                fastcgi_split_path_info         ^(.+\.php)(/.+)$;
                fastcgi_index               index.php;
        }
}

Это связано с тем, что во включенных файлах конфигурации $ request_filename не отражает новый псевдоним из-за того, как nginx наследует значения конфигурации между уровнями.

Проверьте свой файл fastcgi_params. Скорее всего, ваш SCRIPT_FILENAME определен как $ document_root $ fastcgi_script_name, который явно указывает ему не учитывать псевдоним (часть $ document_root является явной частью)

Если вы хотите использовать псевдоним с PHP, вам, вероятно, следует определить SCRIPT_FILENAME как $ request_filename, которое учитывает псевдоним.