Nginx e UserDir e PHP

3

Eu tenho uma instalação nginx / 1.4.7 bastante simples (do Debian / unstable) e estou tentando fazer com que scripts PHP sejam executados dentro de um UserDir .

server {
        listen          8083;                                
        server_name     sid0.local;
        index           index.php index.html;
        root            /data/www/sid0.local;

        location / {
                try_files $uri $uri/ =404;
        }

        # PHP-FPM
        location ~ \.php$ {
                include         fastcgi_params;
                fastcgi_pass    unix:/var/run/php5-fpm.sock;
                fastcgi_index   index.php;
        }

        # UserDir
        location ~ ^/~(.+?)(/.*)?$ {
                alias           /home/$1/www$2;
                autoindex       on;
        }
}

Acessando http://sid0.local/~dummy works, ele lista o conteúdo de /home/dummy/www/ e eu posso acessar arquivos lá. Sob ~dummy/bar é um arquivo chamado index.php - ainda assim, acessar http://sid0.local/~dummy/bar/ traz o temido "Arquivo não encontrado". erro (não um 404). O error.log tem:

2014/04/30 23:07:44 [error] 4237#0: *9 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 192.168.0.103, server: sid0.local, request: "GET /~dummy/bar/ HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "sid0.local:8083"

Agora, muitas pessoas parecem ter esse problema e algumas delas até mesmo postando soluções , como garantir que SCRIPT_FILENAME esteja definido como request_filename - mas esse já é o caso (é definido em fastcgi_params).

No entanto, executar strace(1) no processo nginx fornece (editado para legibilidade):

4045  connect(16, {sa_family=AF_FILE, path="/var/run/php5-fpm.sock"}, 110) = 0
4045  writev(16, [{"
server {
        listen          8083;                                
        server_name     sid0.local;
        index           index.php index.html;
        root            /data/www/sid0.local;

        location / {
                try_files $uri $uri/ =404;
        }

        # PHP-FPM
        location ~ \.php$ {
                include         fastcgi_params;
                fastcgi_pass    unix:/var/run/php5-fpm.sock;
                fastcgi_index   index.php;
        }

        # UserDir
        location ~ ^/~(.+?)(/.*)?$ {
                alias           /home/$1/www$2;
                autoindex       on;
        }
}
2014/04/30 23:07:44 [error] 4237#0: *9 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 192.168.0.103, server: sid0.local, request: "GET /~dummy/bar/ HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "sid0.local:8083"
4045  connect(16, {sa_family=AF_FILE, path="/var/run/php5-fpm.sock"}, 110) = 0
4045  writev(16, [{"%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%T%pre%\f%pre%
      QUERY_STRING
      REQUEST_METHODGET\f%pre%
      CONTENT_TYPE%pre%
      CONTENT_LENGTH70
      SCRIPT_FILENAME/data/www/sid0.local/~dummy/bar/index.php\v
      SCRIPT_NAME/~dummy/bar/index.php\v\f
      REQUEST_URI/~dummy/bar/\f
      DOCUMENT_URI/~dummy/bar/index.php\r
      DOCUMENT_ROOT/data/www/sid0.local
%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%T%pre%\f%pre% QUERY_STRING REQUEST_METHODGET\f%pre% CONTENT_TYPE%pre% CONTENT_LENGTH70 SCRIPT_FILENAME/data/www/sid0.local/~dummy/bar/index.php\v SCRIPT_NAME/~dummy/bar/index.php\v\f REQUEST_URI/~dummy/bar/\f DOCUMENT_URI/~dummy/bar/index.php\r DOCUMENT_ROOT/data/www/sid0.local

Como você pode ver, SCRIPT_FILENAME NÃO é request_filename , mas document_root+fastcgi_script_name - daí o 404, é claro.

Então, eu acho que a minha pergunta é: por que meu SCRIPT_FILENAME ficou confuso (eu mesmo o defini como fastcgi_script_name , sem sorte) e como obter scripts PHP dentro de UserDir em execução?

    
por ckujau 01.05.2014 / 08:36

2 respostas

1

Eu altero o diretório raiz em vez de usar o alias no local. Poderia ser assim:

listen          8083;                                
server_name     sid0.local;
index           index.php index.html;

# Here is magic
set $root_dir /data/www/sid0.local;
rewrite ^(/~[^/]+)$ $1/ redirect;
rewrite ^/~(?<user>[^/]+)(.+) $2;
if ($user) {
    set $root_dir /home/$user/www;
}
root $root_dir;

# PHP-FPM
location ~ \.php$ {
    try_files $uri =404;
    include         fastcgi_params;
    fastcgi_pass    unix:/var/run/php5-fpm.sock;
    fastcgi_index   index.php;
}

Outra versão sem reescrever:

listen          8083;                                
server_name     sid0.local;
index           index.php index.html;

root /data/www/sid0.local;

location ~ ^/~(?<user>[\w-]+)(?<path>/.*)$ {
    alias /home/lynn/tmp/site/$user/www$path;
    autoindex on;

    # PHP-FPM
    location ~ \.php$ {
        try_files $uri =404;
        include         fastcgi_params;
        fastcgi_pass    unix:/var/run/php5-fpm.sock;
        fastcgi_index   index.php;
    }
}

Por algum motivo alias com capturas nomeadas funcionando, enquanto com referências numéricas ele falha. Meu palpite, que as referências numéricas são limpas de alguma forma em local aninhado.

    
por 02.05.2014 / 00:53
0

Com base na resposta de Alexy Ten, coloquei os seguintes arquivos de configuração em /etc/nginx/default.d/ , conforme eles são incluídos por nginx.conf na minha instalação padrão:

$ cat 00-index.conf 
index index.html;

$ cat 50-userdirs.conf
location ~ ^/~(?<user>[\w-]+)(?<path>/?.*)$ {
    alias /home/$user/www$path;
    autoindex on;
}

Observe o símbolo ? adicionado após o símbolo / para corresponder a hostname/~user sem uma barra final. Isso corrige um erro 404.

Se você está recebendo erros 403 devido ao SELinux, você precisará atualizar suas regras de acesso:

# semanage fcontext -a -t httpd_user_content_t '/home/[^/]*/www/.*'
# for userdir in /home/* ; do restorecon -Rvi "$userdir/www" ; done
    
por 13.04.2016 / 03:56