Nginx选择错误的$ document_root

时间:2019-05-02 08:03:14

标签: php nginx

在一个简单的配置中,nginx似乎正在选择一个随机配置文件的文档根目录,以将其设置为试图fastcgi代理的PHP进程内的$ _SERVER ['DOCUMENT_ROOT']。

我尝试了多种配置来尝试解决问题,包括nginx的调试日志,但是无济于事

server {
    listen 80;
    server_name domain.co.uk;
    index index.php;
    error_log /var/log/nginx/domain.co.uk.error.log debug;
    access_log /var/log/nginx/domain.co.uk.access.log;
    root /var/www/domain.co.uk;

    location / {
      try_files $uri /index.php$is_args$args;
    }

    location ~ \.php {
      try_files $uri =404;
      fastcgi_split_path_info ^(.+\.php)(/.+)$;
      fastcgi_param SCRIPT_FILENAME /var/www/domain.co.uk/index.php;
      fastcgi_param SCRIPT_NAME $fastcgi_script_name;
      include fastcgi_params;        
      fastcgi_index index.php;
      fastcgi_pass  unix:/dev/shm/php.7.2.sock;        
    }
}

发生的事情是该请求选择了一个随机的其他配置,并从中应用了文档根目录。其他配置通常在配置的PHP部分中有一个auto_prepend行,该行自动将config.php文件添加到每个请求中。奇怪的是,来自另一个随机站点(它从未连续两次出现在同一站点)的config.php中包含一些内容-其中之一是 autoloader 自动加载器尝试加载不存在的文件(以下错误)

2019/05/02 08:37:34 [error] 19105#0: *575827 FastCGI sent in stderr: "PHP message: PHP Fatal error: require(): Failed opening required '/var/www/domain.co.uk/resources/lib/class.autoloader.php' (include_path='.:/usr/share/php') in /var/www/www.anotherdomain.co.uk/config.php on line 84

此错误的意思是它在config.php的{​​{1}}文件之前,最终导致了错误链。

我对如何开始调试它完全迷失了,我已经整整整整整整两天了,没有一个人更明智!

正如我所说,大多数其他站点配置在配置中都具有/var/www/www.anotherdomain.co.uk/config.php PARAM,所以我的问题是,为什么nginx会随机选择其中一个应用到有问题的配置文件中?

如果我更改auto_prepend以删除fastcgi_params,问题就消失了,这告诉我nginx在请求时不知道$document_root是什么,这是出于某些非常奇怪的原因

谢谢!

1 个答案:

答案 0 :(得分:0)

您遇到的问题是由于无法了解PHP-FPM的运行方式。每个PHP进程都可以长期使用和重用,但是为了提高性能,每个进程都会在其ini配置(包括PHP_VALUE env vars)及其在第一个请求中所需的任何扩展中加载。

在您的方案中,您有两个共享相同PHP-FPM池的网站,我们将它们分别称为“ SiteA”和“ SiteB”,并使用带有单独的前置文件的PHP_VALUE环境变量按照您提到的方式进行配置。

  1. 用户点击了SiteA,PHP尚未初始化,因此它会加载它的配置,并加载和缓存使用的前置文件。
  2. 用户现在点击了SiteB,但现在PHP已被初始化,因此它将继续使用现有的已加载配置,尝试使用SiteA的前置文件。

如果您要撤消此操作并首先点击SiteB,则将永久加载SiteB的前置文件,直到重新启动FPM池为止。

要解决此问题,您需要为每个网站运行一个单独的池,并为每个网站运行一个auto_prepend_file,最好在该池的配置中对其进行配置,而不是通过设置Nginx环境变量来实现。无论如何,强烈建议这样做,以确保安全性,因为它会增加您可能会丢失的隔离级别。

我建议您遵循在最佳,多用户安全PHP + Nginx配置上所做的指导,并根据需要进行更改。

https://www.youtube.com/watch?v=NIwadOtwdaI

注意:本指南是从头到尾的系列文章的一部分,内容涉及如何从头开始设置功能齐全的HTTP服务器,如果您需要更多信息,请查看以前的视频。

Edit2:请注意,该视频需要更新,try_files的使用要比视频中描述的if的使用要好得多。参见:https://nealpoole.com/blog/2011/04/setting-up-php-fastcgi-and-nginx-dont-trust-the-tutorials-check-your-configuration/