0

I have multiple nginx virtualhosts set up on my server. tershronalds.com is running vanilla wordpress 4.3, and staging.ninjawars.net is running a custom php codebase. Both are relying on php5-fpm.

If no php errors or exceptions are triggered, both sites seem to operate ok. In the case of the tershronalds.com wordpress, there are few errors or exceptions, normally no problem. The staging.ninjawars.net custom php codebase uses an auto_prepend_file to front-load a variety of libraries:

fastcgi_param PHP_VALUE "auto_prepend_file=/path/to/ninjawars/deploy/lib/base.inc.php \n session.cookie_domain=staging.ninjawars.net \n date.timezone=America/New_York \n default_charset=UTF-8 \n";

However, if the custom php codebase errors out or an exception occurs, nginx starts misbehaving! It starts sharing configuration between virtualhosts, breaking the tershronalds.com wordpress site:

2015/09/04 13:37:58 [error] 13145#0: *17413 FastCGI sent in stderr:
"PHP message: PHP Fatal error:  Cannot redeclare validate_username() (previously declared in /path/to/ninjawars/deploy/lib/control/lib_auth.php:317) in /path/to/tersh/www/wp-includes/user.php on line 1792" while reading response header from upstream, client: 10.183.252.21, server: tershronalds.com, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "tershronalds.com"

In other words, nginx goes crazy and the wordpress site starts breaking because it includes code from the ninjawars custom codebase that causes duplicate functions!

I have thought of trying to upgrade nginx to work around it, but nginx seems to be at it's latest version, and same with php5-fpm (maybe). The virtualhost configurations actually work and seem valid... ...until a php error/exception occurs. What else should I look into to try to work around this buggy behavior?

Software version information:

apt-cache policy nginx nginx:   Installed: 1.4.6-1ubuntu3.3   Candidate: 1.4.6-1ubuntu3.3   Version table:  *** 1.4.6-1ubuntu3.3 0
        500 http://mirror.rackspace.com/ubuntu/ trusty-updates/main amd64 Packages
        100 /var/lib/dpkg/status
     1.4.6-1ubuntu3.1 0
        500 http://mirror.rackspace.com/ubuntu/ trusty-security/main amd64 Packages
     1.4.6-1ubuntu3 0
        500 http://mirror.rackspace.com/ubuntu/ trusty/main amd64 Packages admin@megaman:~$ apt-cache policy php5-fpm php5-fpm:   Installed: 5.5.9+dfsg-1ubuntu4.11   Candidate: 5.5.9+dfsg-1ubuntu4.11  Version table:  *** 5.5.9+dfsg-1ubuntu4.11 0
        500 http://mirror.rackspace.com/ubuntu/ trusty-updates/universe amd64 Packages
        500 http://mirror.rackspace.com/ubuntu/ trusty-security/universe amd64 Packages
        100 /var/lib/dpkg/status
     5.5.9+dfsg-1ubuntu4 0
        500 http://mirror.rackspace.com/ubuntu/ trusty/universe amd64 Packages

And the wordpress version is the latest 4.3, not that I expect that to be a relevant factor.

Edit if I turn this nginx virtualhost config off, everything works fine (apart, of course, from the staging.ninjawars.net subdomain being fully down).

Staging.ninjawars.net:

server {
        listen 80;
        server_name staging.ninjawars.net www.ninjawars.net ninjawars.net nw.local nw.remote;

        root /path/to/ninjawars/deploy/www;

        error_page 404 /404.php;

        # redirect server error pages to the static page /50x.html
        #
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
                root /usr/share/nginx/html;
        }

        index index.php;

        location / {
                try_files $uri $uri/ =404; # /index.php?$args;
        }

        location ~ \.php$ {
                fastcgi_param PHP_VALUE "auto_prepend_file=/path/to/ninjawars/deploy/lib/base.inc.php \n session.cookie_domain=staging.ninjawars.net \n date.timezone=America/New_York \n default_charset=UTF-8 \n";
                try_files $uri =404;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include fastcgi_params;
        }
}

Here is the somewhat longer & redirecting everything to

no-www, https domain tershronalds.com site:

server {
    listen 80;
    server_name         tershronalds.com;
    return 301          https://tershronalds.com$request_uri;
}
server {
    listen 80;
    server_name         www.tershronalds.com;
    return 301          https://tershronalds.com$request_uri;
}
server {
    listen 80;
    server_name         tershronalds.net www.tershronalds.net tershart.net www.tershart.net;
    return 302          https://tershronalds.com$request_uri;
    # Temporarily redirect these domains for now.
}

server {
    listen 443 ssl;
    server_name tershronalds.com www.tershronalds.com tersh.remote;
    root /path/to/tersh/www;
    index index.php

#   ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers various_cyphers_here
    ssl_certificate /somecrt;
    ssl_certificate_key /somekey;


    #location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        #try_files $uri $uri/ =404;
        # Uncomment to enable naxsi on this location
        # include /etc/nginx/naxsi.rules
    #}


    error_page 404 /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }

    error_page  401  https://tershronalds.com/forbidden.html;

    # Standard wordpress includes !!!
    include global/wordpress.conf;


    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    location ~ /\.ht {
        deny all;
    }
}
Kzqai
  • 1,278
  • 4
  • 17
  • 32
  • show a nginx config.. it might be php-fpm that is the issue if you use the same php-fpm pool for both sites – Mike Sep 04 '15 at 18:03
  • Right, they're long, but I pasted 'em now. – Kzqai Sep 04 '15 at 19:08
  • Using `auto_prepend_file` is a serious code smell. Have the developer get rid of it. – Michael Hampton Sep 04 '15 at 23:17
  • @MichaelHampton What is the alternative to auto_prepend_file? Obviously in an environment with a front-controller, one can just include directly, but the custom php codebase I'm working with does not have a single front controller in place. – Kzqai Sep 07 '15 at 03:03

1 Answers1

1

My own experience with Ubuntu 14.04 and PHP shows that certain operations within files included by auto_prepend_file can fail with opcache extension enabled. Try disabling the extension by deleting the symlink: /etc/php5/fpm/conf.d/05-opcache.ini (originally pointing to ../../mods-available/opcache.ini). It can decrease performance, but shouldn't break anything.

I know little of nginx so I can't say if your method for per-site PHP settings is correct, but utilizing php.ini sections may increase readability and also make your problem disappear if it is related to PHP <-> nginx connection.

Even better, you can create separate instances of PHP-FPM daemon, each one handling a single website. This requires slightly more RAM but fully separates processing of your web applications code. With open_basedir and disable_functions set tightly enough per-app, this approach gives additional security. FPM instances are defined under /etc/php5/fpm/pool.d/.

sam_pan_mariusz
  • 2,053
  • 1
  • 12
  • 15
  • Thanks, I used your suggestion to set php.ini settings for particular hosts at the end of php-fpm's php.ini file and that seems to have worked. (didn't really want to split into multiple configs for each vhost at this stage) – Kzqai Sep 07 '15 at 04:51