dongzhuifeng1843 2019-05-02 08:03
浏览 468

Nginx选错了$ document_root

On a simple configuration nginx seems to be picking a random configuration file's document root to set as the $_SERVER['DOCUMENT_ROOT'] inside the PHP process it's attempting to fastcgi proxy to.

I've tried numerous configurations to try and scope the problem including nginx's debug log however to no avail

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;        
    }
}

What happens is that the request picks a random other configuration and applies the document root from that to it. THe other configurations tend to have an auto_prepend line in the PHP part of the config that auto_prepends a config.php file to every request. The strange part os that the config.php from another random site (it's never the same site twice in a row) has some includes in it - one of which is an autoloader. The autoloader tries to load a file which does not exist (error below)

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

What this error is saying is that it's prepending the config.php file from /var/www/www.anotherdomain.co.uk/config.php which is ultimately causing the error chain.

I am absolutely lost on how to start debugging this, I've been at it for two whole days and am none the wiser!

As I say, most of the other site configs have the auto_prepend PARAM in the config so my question is really why is nginx picking one of those at random to apply to the config file in question?

If I change fastcgi_params to remove $document_root the problem goes away which tells me that nginx doens't know what the $document_root is at the time of the request for some really strange reason.

Thanks in advance!

  • 写回答

1条回答 默认 最新

  • douzhouqin6223 2019-05-02 09:17
    关注

    The issue you are having is due to a failure to understand how PHP-FPM operates. Each PHP process is long lived and reused, however for performance each process loads in it's ini config (including PHP_VALUE env vars) and any extensions it requires on the first request.

    In your scenario you have two websites sharing the same PHP-FPM pool, lets call these "SiteA" and "SiteB", and each are configured the way you mentioned, using the PHP_VALUE environment variable with separate prepend files.

    1. A user hits SiteA, PHP is not yet initialised, so it loads it's config, and the prepend file loaded and cached for use.
    2. A user now hits SiteB, but now PHP is already initialized, so it continues using the existing loaded configuration, attempting to use SiteA's prepend file.

    If you were to reverse this and hit SiteB first, then forever SiteB's prepend file would be loaded until you restarted the FPM pool.

    To correct this you need to run a separate pool for each website, with a auto_prepend_file for each, ideally configured in the pool's config instead of by setting a Nginx environment variable. This is highly recommended anyway for security as it adds a level of isolation you would otherwise be missing.

    I suggest you follow the guide I made here on an optimal, multi-user secure PHP+Nginx configuration and alter it to your requirements.

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

    Note: this guide is part of a series from start to finish on how to setup a fully featured HTTP server from scratch, if you need more information check out the prior videos.

    Edit2: Please note that this video needs an update, the usage of try_files is far better then the if usage described in the video. See: https://nealpoole.com/blog/2011/04/setting-up-php-fastcgi-and-nginx-dont-trust-the-tutorials-check-your-configuration/

    评论

报告相同问题?

悬赏问题

  • ¥15 flink cdc无法实时同步mysql数据
  • ¥100 有人会搭建GPT-J-6B框架吗?有偿
  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决