让我们看看这两个Nginx配置:

server {
    listen         80;
    server_name    example.com;
    location / {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME  /var/www/html/site1/i.php;
        fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root:/var/www/html/site1:/tmp/:/proc/"; #禁止跨目录访问 
        include fastcgi_params;
    }
}
server { 
    listen         80;
    server_name    example.net;
    location / {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME  /var/www/html/site2/i.php;
        include fastcgi_params;
    }
}

/srv/www/i.php文件:

<?php phpinfo(); 正如你所看到的,唯一的区别是fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root:/var/www/html/site1:/tmp/:/proc/"

现在,如果你重启php-fpm 和nginx,并打开example.net,你会看到open_basedir为 no value 。在example.com会看到open_basedir是/var/www/html/site1:/tmp/:/proc/。

但是,如果你再次访问example.net,你会看到example.net的open_basedir的值也变为了 /var/www/html/site1:/tmp/:/proc/。

这会导致example.net的站点程序不正常运行。因为如果example.net的根目录不是/var/www/html/site1。所以include file时就会出错。

发生这种情况的原因很可能是“PHP设置通过PHP_ADMIN_VALUE或php_flag将覆盖其先前的值”,如PHP-FPM文档所述

问题:如何使example.net使用默认设置(no value)?

解决方案:

  • 最简单的是为exmaple.net也设置PHP_ADMIN_VALUE值如 fastcgi_param PHP_ADMIN_VALUE "open_basedir=none";#不启用open_basedir或者 fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root:/var/www/html/site2:/tmp/:/proc/";
  • 似乎是一个“更好”的解决方案 - 为每个站点创建单独的php-fpm进程池

ps:

.net站没有设置PHP_ADMIN_VALUE值

然后,访问.com站,Nginx将传递PHP_ADMIN_VALUE值给同一进程池中的PHP-FPM worker程序。

现在PHP-FPM进程池设置PHP_ADMIN_VALUEopen_basedir=$document_root:/var/www/html/site1:/tmp/:/proc/

当再次访问.net页面时,它的open_basedir也被设置为了 $document_root:/var/www/html/site1:/tmp/:/proc/,因为Nginx将PHP_ADMIN_VALUE值传递到现在处理你的另一个网站的同一个进程池时它被覆盖了。

解决方案是将网站移动到另一台服务器。或者为你的站点创建一个专用的PHP-FPM进程池,这是你应该做的。

提示:

你也可以在php-fpm配置文件中配置PHP_ADMIN_VALUE,最好是在站点自己的fpm进程池配置中。

将多个站点放在一个进程池上是一个坏主意,因为我只需要让你的一个站点执行我的恶意php脚本就可以来危害所有其他使用同一个worker的站点。

注意另外需要开启php.ini中的 opcache.validate_permission和opcache.validate_root,否则还是会不安全

参考 为PHP-FPM和nginx设置多个进程池而安全地运行多个网站

原创文章,转载请注明:来自lenix的博客,地址 http://blog.p2hp.com/archives/5778

nginx不同站点的php-fpm的PHP_ADMIN_VALUE值会覆盖其它站点值的问题!
标签: