Почему мои 2 сайта на одном сервере (случайно?) переключают версии PHP с PHP-FPM

Моя проблема заключается в следующем:

1 сервер с Debian 11 на виртуальной машине (хотя я тестировал 9 и 10, и они оба показывают одинаковое поведение)

с двумя веб-сайтами, настроенными для работы с php-fpm и apache. Каждый сайт имеет один файл index.php, и содержимое этих файлов <?php phpinfo(); ?>. Один сайт настроен на работу с 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 (замените на 81 для php8.1):

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>

У меня есть файл php.sh в каталогах php80/ и php81:

#!/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 недостаточно, чтобы отделить его от любого из основных процессов, что, на мой взгляд, придает достоверность ранее упомянутой статье, в которой говорится, что разные пользователи /groups также необходимо установить.скриншот ps aux |  grep php

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 и получили те же 7.4 на phpinfo(), используя также SetHandler php7.3.

Представленное решение (отойти от сокетов 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 для каждого сайта. проблема проблема не воспроизводится в этих условиях

Apache-2.4 PHP-FPM

Oceanic_Panda

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *