Накратко: mod_php е PHP като модул в уеб сървъра Apache. Всеки процес на Apache тогава съдържа пълен интерпретатор на PHP и сам изпълнява PHP кода; SAPI се нарича apache2handler. Това е лесно за настройване, но свързва PHP с Apache, най-често изисква prefork MPM и почти не позволява разделяне между уебсайтовете. Ръководството на PHP не препоръчва това за нови инсталации, а при PHP2Shell екипът на PHP оценява риска при mod_php като най-висок.
Какво е mod_php?
При mod_php Apache зарежда PHP като самостоятелен модул в своите процеси. Няма отделна PHP услуга: когато Apache трябва да предостави .php файл, същият процес, който е приел заявката, изпълнява и PHP кода. В продължение на много години това беше стандартният начин за работа с PHP и до днес е разпространен на по-стари сървъри и в някои Docker образи.
Според ръководството на PHP като сървърен модул PHP чете конфигурацията си само веднъж, при стартирането на уеб сървъра. Промените в php.ini и актуализациите на модула затова действат едва след рестартиране на Apache.
Важно за разбирането: процесите на Apache живеят дълго. Един процес приема последователно много връзки, преди да бъде заменен; колко, се определя от директивата на Apache MaxConnectionsPerChild. Вграденият интерпретатор на PHP през това време остава същият. Който замени библиотеката libphp на диска, не променя нищо в работещите процеси.
За управителите и отговорниците по проекти това може да се обобщи така: при mod_php уеб сървърът и PHP са едно цяло. Който пипне едното, засяга другото. Актуализацията на PHP означава рестартиране на уеб сървъра, грешка в PHP се изпълнява с правата на уеб сървъра, а разделяне между няколко уебсайта на един и същ сървър е почти невъзможно.
Как се включва mod_php?
Ръководството на PHP показва включването в две стъпки: зареждане на модула и определяне кои файлове PHP да обработва.
LoadModule php_module modules/libphp.so
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
Ръководството препоръчва FilesMatch със SetHandler вместо само AddType, за да не се изпълняват като PHP качени файлове като bild.php.jpg. При Debian и Ubuntu тази работа поемат пакети като libapache2-mod-php8.3 и командите a2enmod и a2dismod.
Дали mod_php е активен, може да се провери само с четене:
apachectl -M 2>/dev/null | grep -i php # Debian/Ubuntu
httpd -M 2>/dev/null | grep -i php # семейство RHEL
apachectl -V | grep -i mpm # активен MPM (prefork, worker, event)
Prefork, Thread Safety и ресурси
Apache разпределя заявките чрез модул за мултипроцесна обработка (MPM). Според ръководството на PHP mod_php изисква MPM prefork, освен ако PHP не е компилиран със Zend Thread Safety (--enable-zts). Повечето пакети на дистрибуциите са компилирани без Thread Safety.
Prefork означава: един процес за всяка едновременна връзка и всеки процес носи пълен интерпретатор на PHP. Дори заявките за изображения или CSS файлове заемат процес с PHP в багажа. Това струва памет и ограничава натоварването, което един сървър може да понесе.
| Характеристика | mod_php | PHP-FPM |
|---|---|---|
| Къде работи PHP? | във всеки процес на Apache | в собствена услуга |
| MPM на Apache | най-често prefork |
възможен е event |
| Потребител за всеки уебсайт | не, всичко като потребител на Apache | да, за всеки пул |
| Рестартиране на PHP | само с Apache | независимо от Apache |
| Настройки за всяка директория | php_value в .htaccess |
пул или .user.ini |
Ръководството затова препоръчва за всички съвременни инсталации PHP-FPM с mod_proxy_fcgi: по-добро управление на ресурсите, разделяне на процесите, рестартиране на PHP без рестартиране на Apache и съвместимост с event MPM, който е стандарт от Apache 2.4. Основите са описани в PHP-FPM, обяснен.
Настройки с .htaccess, php_value и php_admin_value
С mod_php настройките на PHP могат да се задават директно в конфигурацията на Apache. Ръководството различава при това режими на промяна: записи с INI_PERDIR могат да стоят в php.ini, .htaccess или httpd.conf, записи с INI_SYSTEM само в php.ini или httpd.conf.
# В конфигурацията на VirtualHost: заключено за приложението
php_admin_flag display_errors off
php_admin_value upload_max_filesize 24M
# Възможно в .htaccess, но може да бъде презаписано от приложението
php_value max_execution_time 60
php_admin_value и php_admin_flag са разрешени само в конфигурацията на сървъра, а не в .htaccess. Именно това разграничение е важно при временните мерки за PHP2Shell, защото стойности като session.upload_progress.enabled не бива да могат да бъдат нулирани от приложението.
mod_php и PHP2Shell: защо рискът е най-висок
Екипът на PHP оценява риска от PHP2Shell при mod_php като най-висок: там е показан експлойт, преди изобщо да се изпълни код на приложението. Защитните добавки или проверките в CMS така идват твърде късно. Към това се добавя, че при mod_php PHP работи с правата и в паметта на уеб сървъра. Подробната класификация е в Защо mod_php носи най-високия риск.
За операторите затова важи:
- Актуализирайте PHP модула до 8.5.12, 8.4.27, 8.3.36 или 8.2.35, респективно до потвърден backport.
- Рестартирайте Apache напълно, а не само го презареждайте, и проверете времето на стартиране на процесите.
- Задайте временните стойности чрез
php_admin_valueв конфигурацията на сървъра, ако актуализацията още не е възможна. - След това планирайте прехода към PHP-FPM, както е описано в Защита на Apache с mod_php.
Как помага PHP SOS конкретно?
- Разпознаване: Проверяваме на кои сървъри работи mod_php, с кой MPM и от кой източник на пакети.
- Корекция: Актуализираме PHP модула, рестартираме Apache напълно и доказваме състоянието.
- Защита на прехода: Където актуализацията е блокирана, задаваме мерките от php.net заключено в конфигурацията на сървъра.
- Преминаване: В рамките на заздравяването на сървъра мигрираме тествано към PHP-FPM със собствени пулове.
Често задавани въпроси
Защо се казва mod_php, щом модулът се казва php_module?
mod_php е разговорното име за PHP като модул на Apache. В конфигурацията се зарежда с LoadModule; ръководството на PHP дава като пример LoadModule php_module modules/libphp.so. По-старите версии ползваха имена като php7_module или php5_module.
Защо mod_php изисква prefork MPM?
Според ръководството на PHP mod_php изисква prefork MPM, освен ако PHP не е компилиран със Zend Thread Safety. Повечето пакети на дистрибуциите са компилирани без Thread Safety. Prefork стартира отделен процес за всяка едновременна връзка, което изисква повече памет.
Работят ли редовете php_value в .htaccess и с PHP-FPM?
Не. php_value и php_flag в .htaccess са директиви на Apache от модула на PHP и действат само с mod_php. При PHP-FPM такива настройки принадлежат в пула или, за разрешените стойности, във файл .user.ini.
Трябва ли веднага да се откажа от mod_php?
Първо идва актуализацията на PHP с пълно рестартиране на Apache. Преходът към PHP-FPM след това е смислен, но трябва да бъде планиран и тестван. Той не затваря PHP2Shell, защото PHP-FPM също е засегнат.