Nginx & UserDir & PHP

Nginx & UserDir & PHP

我有一个相当简单的 nginx/1.4.7 安装(来自 Debian/unstable),并且我试图让 PHP 脚本在用户目录

服务器 {
        听 8083;                                
        服务器名称sid0.local;
        索引 index.php 索引.html;
        根/data/www/sid0.local;

        地点 / {
                尝试文件$uri $uri/ =404;
        }

        # PHP-FPM
        位置 ~ \.php$ {
                包括 fastcgi_params;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index索引.php;
        }

        # 用户目录
        位置 ~ ^/~(.+?)(/.*)?$ {
                别名/home/$1/www$2;
                自动索引开启;
        }
}

访问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 [错误] 4237#0:*9 FastCGI 在从上游读取响应标头时在 stderr 中发送:“主要脚本未知”,客户端:192.168.0.103,服务器:sid0.local,请求:“GET /~dummy/bar/HTTP/1.1”,上游:“fastcgi://unix:/var/run/php5-fpm.sock:”,主机:“sid0.local:8083”

现在,很多人似乎有这个问题,其中一些人甚至发布解决方案,例如确保设置SCRIPT_FILENAMErequest_filename- 但情况已经如此(它在 fastcgi_params 中设置)。

但是,strace(1)针对 nginx 进程运行会出现(为便于阅读已编辑):

4045 连接(16,{sa_family=AF_FILE,路径="/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\0\1\4\0\1\3T\4\0\f\0
      查询字符串\16\3
      REQUEST_METHODGET\f\0
      内容类型\16\0
      内容长度\0170
      SCRIPT_FILENAME/data/www/sid0.local/~dummy/bar/index.php\v\25
      脚本名称/~dummy/bar/index.php\v\f
      REQUEST_URI/~dummy/bar/\f\25
      DOCUMENT_URI/~dummy/bar/index.php\r\33
      DOCUMENT_ROOT/数据/www/sid0.local

正如您所见,SCRIPT_FILENAME不是request_filename而是document_root+fastcgi_script_name—— 因此当然是 404。

所以,我想我的问题是:为什么我的是SCRIPT_FILENAME混乱的(我甚至将它设置为fastcgi_script_name,但没有运气)以及如何在UserDir运行中获得 PHP 脚本?

答案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,命名捕获可以工作,而数字引用则失败。我猜,数字引用以某种方式在嵌套位置被清除了。

答案2

基于 Alexy Ten 的回答,我放置了以下配置文件,/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;
}

注意在匹配符号?后添加的符号没有尾部斜杠。这修复了一个 404 错误。/hostname/~user

如果您因 SELinux 而收到 403 错误,则需要更新您的访问规则:

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

相关内容