3

У меня довольно простая установка nginx/1.4.7 (из Debian/unstable), и я пытаюсь заставить PHP-скрипты работать внутри 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;
        }
}

Доступ к http://sid0.local/~dummy работает, он перечисляет содержимое /home/dummy/www/ и я могу получить доступ к файлам там. Ниже ~dummy/bar находится файл с именем index.php но доступ к http://sid0.local/~dummy/bar/ приводит к ужасному «Файл не найден». ошибка (не 404). error.log имеет:

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"

Теперь, похоже, у многих людей есть эта проблема, и некоторые из них даже публикуют решения, например, удостоверившись, что для SCRIPT_FILENAME установлено значение request_filename - но это уже имеет место (это установлено в fastcgi_params).

Однако, выполнение strace(1) для процесса nginx дает (отредактировано для удобства чтения):

4045  connect(16, {sa_family=AF_FILE, path="/var/run/php5-fpm.sock"}, 110) = 0
4045  writev(16, [{"\1\1\0\1\0\10\0\0\0\1\0\0\0\0\0\0\1\4\0\1\3T\4\0\f\0
      QUERY_STRING\16\3
      REQUEST_METHODGET\f\0
      CONTENT_TYPE\16\0
      CONTENT_LENGTH\0170
      SCRIPT_FILENAME/data/www/sid0.local/~dummy/bar/index.php\v\25
      SCRIPT_NAME/~dummy/bar/index.php\v\f
      REQUEST_URI/~dummy/bar/\f\25
      DOCUMENT_URI/~dummy/bar/index.php\r\33
      DOCUMENT_ROOT/data/www/sid0.local

Как вы можете видеть, SCRIPT_FILENAME НЕ request_filename , но вместо этого document_root+fastcgi_script_name - следовательно, 404, конечно.

Итак, я предполагаю, что мой вопрос: почему мой SCRIPT_FILENAME (я даже установил его на fastcgi_script_name , не повезло) и как я могу запустить PHP-скрипты внутри UserDir ?

2 ответа2

1

Я бы изменил корневой каталог вместо использования псевдонима в местоположении. Это может выглядеть так:

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;
}

Еще одна версия без переписывания:

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;
    }
}

По какой-то причине alias с именованными захватами работает, в то время как с числовыми ссылками это не удается. Я предполагаю, что числовые ссылки очищаются как-то во вложенном месте.

0

Основываясь на ответе Алекси Тен, я поместил следующие файлы конфигурации в /etc/nginx/default.d/ как они включены в nginx.conf при моей установке по умолчанию:

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

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

Обратите внимание на добавленное ? символ после символа / соответствует hostname/~user без завершающей косой черты. Это исправляет одну ошибку 404.

Если вы получаете 403 ошибки из-за SELinux, вам необходимо обновить правила доступа:

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .