我的问题如下:
1 台在虚拟机中运行 Debian 11 的服务器(尽管我已经测试过 9 和 10,它们都显示相同的行为)
有 2 个网站都配置为使用 php-fpm 和 apache 运行。每个网站都有一个 index.php 文件,这些文件的内容是<?php phpinfo(); ?>
。1 个网站已设置为运行 php8.0,另一个网站运行 php8.1,这代表我正在处理的真实情况。这是通过将 apache 配置文件包含到每个网站的主 apache 配置文件中来完成设置的,内容如下:
<IfModule proxy_fcgi_module>
# Enable http authorization headers
<IfModule setenvif_module>
SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
</IfModule>
<FilesMatch ".+\.ph(ar|p|tml)$">
<If "-f %{REQUEST_FILENAME}">
SetHandler "proxy:unix:/run/php/php8.0-fpm.sock|fcgi://localhost"
</If>
</FilesMatch>
<FilesMatch ".+\.(phps|inc)$">
# Deny access to raw php sources by default
# To re-enable it's recommended to enable access to the files
# only in specific virtual host or directory
Require all denied
</FilesMatch>
# Deny access to files without filename (e.g. '.php')
<FilesMatch "^\.ph(ar|p|ps|tml)$">
Require all denied
</FilesMatch>
然后,php8.1 的配置文件使用 php8.1-fpm.sock。ps aux 显示以下内容:
root 114787 0.0 0.3 222780 27312 ? Ss 17:10 0:00 php-fpm: master process (/etc/php/8.0/fpm/php-fpm.conf)
www-data 114788 0.0 0.5 247140 48664 ? S 17:10 0:03 php-fpm: pool www
www-data 114789 0.0 0.5 247128 48592 ? S 17:10 0:03 php-fpm: pool www
www-data 114790 0.0 0.6 247136 48748 ? S 17:10 0:03 php-fpm: pool www
www-data 114791 0.0 0.5 247128 48676 ? S 17:10 0:05 php-fpm: pool www
www-data 114792 0.0 0.5 247132 48548 ? S 17:10 0:04 php-fpm: pool www
root 114802 0.0 0.3 227196 28120 ? Ss 17:10 0:00 php-fpm: master process (/etc/php/8.1/fpm/php-fpm.conf)
www-data 114803 0.0 0.3 227764 26744 ? S 17:10 0:00 php-fpm: pool www
www-data 114804 0.0 0.1 227196 8896 ? S 17:10 0:00 php-fpm: pool www
www-data 114805 0.0 0.1 227196 8896 ? S 17:10 0:00 php-fpm: pool www
www-data 114806 0.0 0.1 227196 8896 ? S 17:10 0:00 php-fpm: pool www
/etc/php/8.0/fpm/pool.d/www.conf 的内容:
[www]
user = www-data
group = www-data
listen = /run/php/php8.0-fpm.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
/etc/php/8.1/fpm/pool.d/www.conf 的内容完全相同,只是 listen = /run/php/php8.1-fpm.sock
/etc/php80/apache-include.conf 的内容(对于 php8.1,请用 81 替换):
Alias /php80 /etc/php80/htdocs
<Directory /etc/php80/htdocs>
<IfModule proxy_fcgi_module>
Include /etc/php80/etc/php-apache2-fpm.conf
</IfModule>
</Directory>
<Location /php80 >
Options FollowSymLinks
<IfModule mod_php7.c>
Include /etc/php80/etc/php-apache2.conf
</IfModule>
SetEnv st_config_filepath /etc/php80/config.ini
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteOptions inherit
# Maintenance for this installation
RewriteCond /etc/php80/maintenance -f
RewriteCond %{HTTP_USER_AGENT} !Maintenance_Override
RewriteRule ^.*$ /maintenance/? [L,R=307]
</IfModule>
</Location>
# Deny access to simplesaml directories
<DirectoryMatch "^/etc/php80/htdocs/libraries/simplesamlphp/(?!(auth|resources|module.php)).+">
Order deny,allow
Deny from all
</DirectoryMatch>
/etc/apache2/sites-enabled/ssl.conf 的内容
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin webmaster@*.*
ServerName ${APACHE_LOCALFQDN}
ServerAlias ${APACHE_HOSTNAME}
DocumentRoot /var/www/html/
<Directory />
Options
AllowOverride None
</Directory>
<Directory /var/www/html/>
Options FollowSymLinks
AllowOverride None
Order allow,deny
allow from all
</Directory>
# Logging
# For proxied requests, log different information:
SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded
# Proxied access log:
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy
CustomLog ${APACHE_LOG_DIR}/${APACHE_LOCALFQDN}-ssl.access-proxy.log proxy env=forwarded
# SSL Configuration
SSLEngine on
SSLOptions StdEnvVars OptRenegotiate
SSLCertificateFile /etc/ssl/private/${APACHE_LOCALFQDN}.crt
SSLCertificateKeyFile /etc/ssl/private/${APACHE_LOCALFQDN}.key
<FilesMatch "\.(php)$">
SSLOptions +StdEnvVars
</FilesMatch>
BrowserMatch "MSIE [2-6]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
BrowserMatch "MSIE [7-9]" ssl-unclean-shutdown
################################################################################
# SSL hardening options
#Probably not relevant to show here
</VirtualHost>
</IfModule>
我在 php80/ 和 php81 目录中有一个 php.sh 文件:
#!/bin/sh -e
. /etc/php80/etc/php-cli.sh
env config_filepath=/etc/php80/config.ini /usr/bin/${PHPVERSION:=php7.3} ${PHPOPTIONS} $*
php-cli.sh的内容为:
PHPOPTIONS="-d magic_quotes_gpc=off -d register_globals=off -d safe_mode=off -d session.use_trans_sid=off -d output_buffering=off -d zlib.output_compression=off -d ignore_user_abort=on -d upload_max_filesize=1500M -d post_max_size=1500M -d memory_limit=-1 -d date.timezone=Europe/Berlin"
PHPVERSION="${FORCE_PHP_VERSION:-php8.0}"
php81 随后已正确设置相关部分。
我真正不明白的以及我的问题所在是,为什么当我不断刷新各个页面时,我有时会看到 8.0 网站显示它正在使用 php8.1,反之亦然。我有时必须刷新页面 10-20 次才能切换,但它总是会很快出现。
我该如何弄清楚为什么会发生这种情况,或者我是否忽略了一些非常明显的事情?
提前谢谢了!
进一步研究/可能的解释:
1.php fpm 主进程均以 root 身份运行,所有子进程均以 www-data 身份运行(如上 ps aux 输出所示)。https://www.binarytides.com/php-fpm-separate-user-uid-linux/这表明尽管使用不同的套接字,但实际上任何池都可以用于请求,因为它们都在 www-data 用户下运行:
“使用自己的 uid/gid 运行每个站点更安全,也更容易处理。如果所有站点都使用同一个用户运行,那么一个站点上的 php 就可以读取/写入其他用户的文件。”
1.1. 经过进一步的实验,我发现更改 php8.0 或 8.1 的池名称不足以将其与任何主进程分离,在我看来,这使之前引用的文章具有可信度,该文章指出还需要设置不同的用户/组。
1.1.1.好吧,最后一项就不提了,我之前没有意识到 ps aux 没有显示进程之间的关系。ps afx 显示子进程分配正确。不幸的是,我以为我已经找到了,但实际上并没有。
161186 ? Ss 0:01 php-fpm: master process (/etc/php/8.0/fpm/php-fpm.conf)
161191 ? S 0:10 \_ php-fpm: pool php80
161192 ? S 0:11 \_ php-fpm: pool php80
161193 ? S 0:07 \_ php-fpm: pool php80
161205 ? Ss 0:01 php-fpm: master process (/etc/php/8.1/fpm/php-fpm.conf)
161206 ? S 0:00 \_ php-fpm: pool www
161207 ? S 0:00 \_ php-fpm: pool www
我现在已经测试设置不同的用户和组,但仍然看到相同的行为
2.看来这个问题实际上之前遇到过。
尝试了 phpinfo() 页面,得到的是 PHP 7.4.15,而不是预期的 5.6.40。我们对 7.3 做了同样的操作,同样使用 php7.3 的 SetHandler 在 phpinfo() 上得到了相同的 7.4。
我已经测试了所提出的解决方案(放弃 Linux 套接字并改用网络通信),并确认它有效。不幸的是,这不是一个理想的解决方案,并且无法解释为什么使用套接字无法正常工作。涉及的解决方案<If "-f %{REQUEST_FILENAME}">
我已经存在,但没有任何效果。
3.我发现我们设置的另外 2 个系统使用 Debian 10.12 和 Apache 2.4.54(而不是上例中的 Apache 2.4.53),以及 Debian 11.4 和 Apache 2.4.54。对于这些系统,我们使用 .htaccess 文件,而不是每个站点使用单独的 Apache 配置,在这些条件下,该问题无法重现