Eu estava trabalhando ontem na configuração do meu primeiro servidor Nginx com o PHP-FPM e posso ter encontrado o mesmo problema que o seu. Para encurtar a história, eu não fui capaz de configurar o Nginx corretamente e com segurança, com todas as variáveis de servidor do PHP sendo definidas corretamente. Eu finalmente encontrei uma configuração adequada que compartilharei com você. No entanto, seria muito bom ouvir de um especialista da Nginx sobre esse assunto. Sério, nos deparamos com questões realmente estranhas que nunca deveriam acontecer.
Seus problemas de configuração
Então, basicamente, você quer uma instalação Nginx + PHP-FPM segura e funcional. Quero dizer, com o "trabalho", que as variáveis de servidor do PHP estão definidas corretamente e com "seguro", que o Nginx está protegido contra vulnerabilidades conhecidas.
Primeiro , eu consegui reproduzir sua configuração e seus problemas. Por algum motivo, o try_files
está quebrando alguma coisa. Eu não posso dizer por que, mas você está certo quando diz isso. A substituição da diretiva try_files
pelo código a seguir parece corrigir esse problema:
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
EDITAR: Como discutido abaixo no comentário, o código acima deve ser evitado . Além disso, a diretiva try_files
original está funcionando conforme o esperado.
Segundo , notei que você não incluiu o arquivo fastcgi_params
, que é responsável por definir todos os parâmetros necessários (e obrigatórios) do FastCGI que serão usados para definir o PHP variáveis do servidor. Eu não sei porque você não incluiu este arquivo, já que toda a documentação que eu li na web nos diz para usar esse arquivo. Agora que o arquivo está incluído, precisamos modificar alguns parâmetros que não estão definidos corretamente por padrão. No final, precisamos adicionar as seguintes diretrizes:
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
Observe como o SCRIPT_FILENAME
é diferente do seu. Mais uma vez, eu li muita documentação que nos diz para usar esse valor (vou ligar para aqueles abaixo). Você pode colocar a diretiva fastcgi_param
diretamente no arquivo fastcgi_params
ou na sua seção location
.
Então , nada está funcionando. Se eu usar o mesmo link que o seu, obtenho No input file specified
. Examinando os arquivos de log, recebo Unable to open primary script: /var/www/a.php (No such file or directory)
. Eu não sei porque está fazendo isso, mas todos os parâmetros do fastcgi parecem ser confusos.
Agora , a parte mais estranha, se eu remover esta linha:
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
está funcionando novamente, mas com a confusão de variáveis de servidor do PHP. Não apenas PATH_TRANSLATED
não está definido, PHP_SELF
e outros não estão definidos corretamente. É aqui que eu luto há muito tempo. Felizmente, encontrei uma solução que parece se encaixar no que pretendemos.
Configuração de trabalho
Se reativarmos cgi.fix_pathinfo
na configuração do PHP, tudo funcionará. No começo, pensei que era uma má ideia fazer isso. No entanto, eu li sobre os riscos de segurança com cgi.fix_pathinfo
habilitado, apenas para descobrir que já estamos protegidos contra eles. Com security.limit_extensions
definido como .php
por padrão, estamos protegidos contra cgi.fix_pathinfo
problemas. Além disso, a verificação de existência de arquivo (a condição if
que adicionamos anteriormente) nos protege ainda mais, evitando o caso em que o FastCGI tenta interpretar outros arquivos como PHP.
A seção location
final deve ter esta aparência:
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^((?U).+\.php)(.*)$;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
}
Outros desafios
Há uma coisa sobre a qual ninguém fala, mesmo que todos estejam fazendo isso de forma diferente. Estou falando dos regexes usados na diretiva location
e fastcgi_split_path_info
. Pessoalmente, eu escolho estes porque eles estão fazendo mais sentido para mim:
location ~ ^.+\.php(/|$) { ... }
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
Eu realmente gostaria de saber as vantagens e desvantagens do outro. Mais uma vez, seria muito bom ouvir um especialista da Nginx sobre esse assunto.
Fontes
- Tutorial que eu segui principalmente
- Outro tutorial genérico
- questão de segurança cgi.fix_pathinfo explicada
- Conselhos gerais de segurança