我有一个相当简单的 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_FILENAME
为request_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