Como verificar a existência de arquivos ilegíveis antes de passá-lo para um backend fastcgi?

1

Eu tenho vários sites PHP que eu quero separar em termos de permissões. Portanto, criei um novo usuário e configurei um pool PHP para esses usuários. Considere a configuração abaixo:

  • O PHP-FPM está sendo executado como usuário php
  • o nginx está sendo executado como usuário nginx
  • A webroot é /srv/http , acessível por ambos php e nginx.
  • O arquivo /srv/http/index.php é legível por php, mas não legível por nginx.
  • O arquivo fastcgi_stuff contém parâmetros rápidos de configuração para definir cabeçalhos, definir o backend, etc. Assuma que a raiz da web para arquivos estáticos e arquivos PHP é a mesma.

O nginx.conf abaixo contém o essencial desta configuração, é colocado em uma diretiva server :

server_name example.com;
root /srv/http;

index index.php;
location ~ \.php$ {
    include fastcgi_stuff;
}

Se eu solicitar http://example.com/ com a configuração acima, a página será carregada conforme o esperado. Para http://example.com/does.not.exist , recebo um 404 como esperado.

Para evitar a transmissão de arquivos inexistentes para o PHP-FPM, tentei adicionar uma das linhas abaixo:

    try_files $uri =404;
    if ( !-e $request_filename ){ return 404; }

Ambos não funcionam como anunciado, ele tenta abrir os arquivos em vez de verificar a existência fazendo stat() call. Confirmei isso verificando o código-fonte e executando strace em um processo de trabalho.

Este é um caso básico com o qual eu estava tendo problemas, outro caso é onde oculto a extensão e, portanto, coloco um try_files $uri.php =404 no bloco de localização. Alguma sugestão?

    
por Lekensteyn 05.01.2013 / 12:02

1 resposta

1

O Nginx tenta abrir o arquivo porque eu tinha disable_symlinks on; . O código-fonte relevante está no core / ngx_open_file_cache.c, function ngx_file_info_wrapper . (chamado de ngx_open_cached_file , de ngx_http_script_file_code ).

Se disable_symlinks estiver definido como off , nginx fará uma chamada de estatística simples ( ngx_file_info é digitado para stat em * nix). Quando disable_symlinks é definido como algo diferente (por exemplo, on ), ele tenta abrir o arquivo de forma segura contra as corridas de links simbólicos e, em seguida, executa uma chamada fstat() no descritor de arquivo aberto. Como o nginx não pode abrir o arquivo para leitura, pois não tem permissões para isso, ele falha.

A solução de curto prazo é habilitar links simbólicos novamente usando disable_symlinks off , uma solução de longo prazo é modificar as funções para atravessar o diretório contido e, em seguida, fstatat() o arquivo nesse diretório . Lembre-se de desativar links simbólicos para diretórios que não contêm scripts PHP, mas que podem ser gravados pelo usuário PHP.

Como mencionado no link , esse comportamento é documentado :

On systems that do not support opening directories for search only, the use of these parameters requires that worker processes have read permissions for all checked directories.

Eu carreguei um patch que permite você para restringir links simbólicos e ainda fazer try_files ou if funcionar. Veja também o tópico vinculado acima.

    
por 05.01.2013 / 14:03