我有几个 PHP 站点,我想在权限方面将它们分开。因此,我创建了一个新用户并为这些用户设置了一个 PHP 池。考虑以下配置:
- PHP-FPM 以用户身份运行
php
- nginx 以用户身份运行
nginx
- webroot 是
/srv/http
,可由 php 和 nginx 访问。 - 该文件
/srv/http/index.php
可由php读取,但不可由nginx读取。 - 该文件
fastcgi_stuff
包含用于设置标头、设置后端等的基本 fastcgi 参数。假设静态文件和 PHP 文件的 webroot 相同。
下面的 nginx.conf 包含了这个配置的要点,它被放在一个server
指令中:
server_name example.com;
root /srv/http;
index index.php;
location ~ \.php$ {
include fastcgi_stuff;
}
如果我请求http://example.com/
上述配置,页面将按预期加载。对于http://example.com/does.not.exist
,我得到了预期的 404。
为了防止将不存在的文件传递给 PHP-FPM,我尝试添加以下行之一:
try_files $uri =404;
if ( !-e $request_filename ){ return 404; }
两者都不像宣传的那样工作,它试图打开文件而不是通过stat()
调用检查文件是否存在。我通过检查源代码并strace
在工作进程上运行来确认这一点。
这是我遇到麻烦的一个基本情况,另一种情况是我隐藏了扩展名,因此将 atry_files $uri.php =404
放在位置块中。有什么建议么?
Nginx 尝试打开文件,因为我有
disable_symlinks on;
. 相关源码在core/ngx_open_file_cache.c, functionngx_file_info_wrapper
中。(称为来自ngx_open_cached_file
,来自ngx_http_script_file_code
)。如果
disable_symlinks
设置为off
,nginx 会执行一个简单的统计调用(在 *nix 上被定义为 typedef)ngx_file_info
。stat
当disable_symlinks
设置为其他内容(例如on
)时,它会尝试以一种对符号链接竞争安全的方式打开文件,然后fstat()
对打开的文件描述符执行调用。由于 nginx无法打开文件进行读取,因为它没有权限,因此它失败了。短期解决方案是再次使用启用符号链接
disable_symlinks off
,长期解决方案是修改函数以遍历包含目录,然后遍历该目录fstatat()
中的文件。请记住为不包含 PHP 脚本但可由 PHP 用户写入的目录禁用符号链接。如http://forum.nginx.org/read.php?2,225152,234724#msg-234724所述,此行为已记录:
我已经上传了一个补丁,允许您限制符号链接并且仍然可以
try_files
正常if
工作。另请参阅上面的链接线程。