![PHP 异常导致 nginx 虚拟主机相互泄漏](https://linux22.com/image/666112/PHP%20%E5%BC%82%E5%B8%B8%E5%AF%BC%E8%87%B4%20nginx%20%E8%99%9A%E6%8B%9F%E4%B8%BB%E6%9C%BA%E7%9B%B8%E4%BA%92%E6%B3%84%E6%BC%8F.png)
我的服务器上设置了多个 nginx 虚拟主机。tershronalds.com 运行的是 vanilla wordpress 4.3,staging.ninjawars.net 运行的是自定义 php 代码库。两者都依赖于 php5-fpm。
如果没有触发 php 错误或异常,则两个站点似乎都运行正常。就 tershronalds.com wordpress 而言,几乎没有错误或异常,通常没有问题。staging.ninjawars.net 自定义 php 代码库使用 auto_prepend_file 来预先加载各种库:
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";
但是,如果自定义 php 代码库出错或出现异常,nginx 就会开始出现问题!它开始在虚拟主机之间共享配置,从而破坏 tershronalds.com wordpress 网站:
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"
换句话说,nginx 出现问题并且 wordpress 网站开始崩溃,因为它包含了来自 ninjawars 自定义代码库的代码,导致重复函数!
我曾想过尝试升级 nginx 来解决这个问题,但 nginx 似乎已经是最新版本了,php5-fpm 也一样(可能)。虚拟主机配置实际上可以工作,而且似乎有效……直到出现 php 错误/异常。我还应该研究什么来尝试解决这个错误行为?
软件版本信息:
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
而且 wordpress 版本是最新的 4.3,但我认为这不是一个相关因素。
编辑如果我关闭这个 nginx 虚拟主机配置,一切都会正常工作(当然,除了 staging.ninjawars.net 子域完全关闭)。
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;
}
}
以下是稍长的内容并将所有内容重定向至
无 www, https 域名 tershronalds.com 网站:
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;
}
}
答案1
我自己使用 Ubuntu 14.04 和 PHP 的经验表明,包含的文件中某些操作auto_prepend_file
可能会失败操作缓存扩展已启用。请尝试通过删除符号链接来禁用该扩展:/etc/php5/fpm/conf.d/05-opcache.ini(原本指../../mods-可用/opcache.ini)。这可能会降低性能,但不会破坏任何东西。
我对nginx所以我不能说你针对每个站点的 PHP 设置方法是否正确,但是利用php.ini 部分如果它与 PHP <-> nginx 连接相关,可能会增加可读性并使您的问题消失。
更好的是,您可以创建单独的 PHP-FPM 守护程序实例,每个实例处理一个网站。这需要稍微多一点的 RAM,但可以完全分离 Web 应用程序代码的处理。通过对open_basedir
每个disable_functions
应用程序进行足够严格的设置,这种方法可以提供额外的安全性。FPM 实例在/etc/php5/fpm/pool.d/。