Lyhyesti: mod_php on PHP moduulina Apache-verkkopalvelimessa. Jokainen Apache-prosessi sisältää silloin täydellisen PHP-tulkin ja suorittaa PHP-koodin itse; SAPI:n nimi on apache2handler. Se on helppo ottaa käyttöön, mutta sitoo PHP:n Apacheen, vaatii yleensä prefork-MPM:n ja mahdollistaa verkkosivustojen erottelun vain heikosti. PHP-käsikirja neuvoo välttämään sitä uusissa asennuksissa, ja PHP2Shellin kohdalla PHP-tiimi arvioi riskin korkeimmaksi juuri mod_php:ssä.
Mikä mod_php on?
mod_php:ssä Apache lataa PHP:n omana moduulinaan prosesseihinsa. Erillistä PHP-palvelua ei ole: kun Apachen pitää toimittaa .php-tiedosto, sama prosessi, joka otti pyynnön vastaan, suorittaa myös PHP-koodin. Monta vuotta tämä oli vakiotapa ajaa PHP:tä, ja se on yhä yleinen vanhoilla palvelimilla ja joissakin Docker-levykuvissa.
PHP-käsikirjan mukaan PHP lukee palvelinmoduulina konfiguraationsa vain kerran, verkkopalvelimen käynnistyessä. Muutokset php.ini-tiedostoon ja moduulin päivitykset tulevat siksi voimaan vasta Apachen uudelleenkäynnistyksen jälkeen.
Ymmärtämisen kannalta tärkeää: Apache-prosessit elävät pitkään. Yksi prosessi ottaa vastaan peräkkäin monta yhteyttä, ennen kuin se korvataan; kuinka monta, säätelee Apache-direktiivi MaxConnectionsPerChild. Upotettu PHP-tulkki pysyy tänä aikana samana. Jos levyllä oleva libphp-kirjasto vaihdetaan, käynnissä oleviin prosesseihin se ei vaikuta.
Johdolle ja projektivastaaville tämän voi tiivistää näin: mod_php:ssä verkkopalvelin ja PHP ovat yksi kokonaisuus. Kun koskee toiseen, vaikuttaa toiseenkin. PHP-päivitys tarkoittaa verkkopalvelimen uudelleenkäynnistystä, PHP:n virhe toimii verkkopalvelimen oikeuksilla, ja usean verkkosivuston erottelu samalla palvelimella on käytännössä mahdotonta.
Miten mod_php liitetään mukaan?
PHP-käsikirja näyttää liittämisen kahdessa vaiheessa: moduulin lataus ja sen määrittäminen, mitkä tiedostot PHP:n tulee käsitellä.
LoadModule php_module modules/libphp.so
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
Käsikirja suosittelee FilesMatch-lohkoa ja SetHandler-direktiiviä pelkän AddType-direktiivin sijaan, jotta ladatut tiedostot kuten bild.php.jpg eivät suoriudu PHP:nä. Debianissa ja Ubuntussa tämän hoitavat paketit kuten libapache2-mod-php8.3 sekä komennot a2enmod ja a2dismod.
Sen, onko mod_php aktiivinen, voi tarkistaa vain lukemalla:
apachectl -M 2>/dev/null | grep -i php # Debian/Ubuntu
httpd -M 2>/dev/null | grep -i php # RHEL-perhe
apachectl -V | grep -i mpm # aktiivinen MPM (prefork, worker, event)
Prefork, Thread Safety ja resurssit
Apache jakaa pyynnöt monikäsittelymoduulin (MPM) kautta. PHP-käsikirjan mukaan mod_php tarvitsee prefork-MPM:n, ellei PHP:tä ole käännetty Zend Thread Safetyn (--enable-zts) kanssa. Useimmat jakelupaketit on käännetty ilman Thread Safetya.
Prefork tarkoittaa: yksi prosessi samanaikaista yhteyttä kohden, ja jokainen prosessi kantaa mukanaan täydellistä PHP-tulkkia. Myös kuvien tai CSS-tiedostojen pyynnöt varaavat siis prosessin, jolla on PHP mukanaan. Se maksaa muistia ja rajoittaa kuormaa, jonka palvelin kestää.
| Ominaisuus | mod_php | PHP-FPM |
|---|---|---|
| Missä PHP toimii? | jokaisessa Apache-prosessissa | omassa palvelussa |
| Apachen MPM | yleensä prefork |
event mahdollinen |
| Käyttäjä verkkosivustoa kohden | ei, kaikki Apache-käyttäjänä | kyllä, poolia kohden |
| PHP:n uudelleenkäynnistys | vain Apachen mukana | Apachesta riippumatta |
| Asetukset hakemistoa kohden | php_value .htaccess-tiedostossa |
pooli tai .user.ini |
Käsikirja suosittelee siksi kaikkiin moderneihin asennuksiin PHP-FPM:ää ja mod_proxy_fcgi-moduulia: parempi resurssienhallinta, prosessien erottelu, PHP:n uudelleenkäynnistys ilman Apachen uudelleenkäynnistystä ja yhteensopivuus event-MPM:n kanssa, joka on ollut Apache 2.4:stä lähtien vakio. Perusteet ovat sivulla PHP-FPM selitettynä.
Asetukset: .htaccess, php_value ja php_admin_value
mod_php:n kanssa PHP-asetukset voi asettaa suoraan Apachen konfiguraatiossa. Käsikirja erottaa tässä muutostilat: INI_PERDIR-merkinnät saavat olla php.ini-tiedostossa, .htaccess-tiedostossa tai httpd.conf-tiedostossa, INI_SYSTEM-merkinnät vain php.ini-tiedostossa tai httpd.conf-tiedostossa.
# VirtualHost-konfiguraatiossa: sovellukselta lukittu
php_admin_flag display_errors off
php_admin_value upload_max_filesize 24M
# .htaccess-tiedostossa mahdollinen, mutta sovellus voi ohittaa
php_value max_execution_time 60
php_admin_value ja php_admin_flag ovat sallittuja vain palvelinkonfiguraatiossa, eivät .htaccess-tiedostossa. Juuri tämä ero on tärkeä PHP2Shellin väliaikaistoimissa, koska arvoja kuten session.upload_progress.enabled sovellus ei saa pystyä palauttamaan.
mod_php ja PHP2Shell: miksi riski on suurin
PHP-tiimi arvioi PHP2Shellin riskin korkeimmaksi mod_php:ssä: siinä on esitetty hyökkäys, joka toimii jo ennen kuin sovelluskoodia ajetaan. Tietoturvalisäosat tai CMS:n tarkistukset tulevat silloin liian myöhään. Lisäksi mod_php:ssä PHP toimii verkkopalvelimen oikeuksilla ja sen muistissa. Perusteellinen arvio on sivulla Miksi mod_php:n riski on suurin.
Ylläpitäjille pätee siksi:
- Päivittäkää PHP-moduuli versioon 8.5.12, 8.4.27, 8.3.36 tai 8.2.35 tai vahvistettuun backportiin.
- Käynnistäkää Apache kokonaan uudelleen, ei pelkkä reload, ja tarkistakaa prosessien käynnistysaika.
- Asettakaa väliaikaisarvot
php_admin_value-direktiivillä palvelinkonfiguraatiossa, jos päivitys ei vielä ole mahdollinen. - Suunnitelkaa sen jälkeen siirtymä PHP-FPM:ään sivulla Apache ja mod_php: suojaus kuvatulla tavalla.
Miten PHP SOS auttaa konkreettisesti?
- Tunnistus: Tarkistamme, millä palvelimilla mod_php on käytössä, millä MPM:llä ja mistä pakettilähteestä.
- Päivitys: Päivitämme PHP-moduulin, käynnistämme Apachen täysin uudelleen ja osoitamme tilan.
- Välivaiheen turvaaminen: Missä päivitys on estynyt, asetamme php.netin toimet lukittuina palvelinkonfiguraatioon.
- Siirtymä: Palvelimen koventamisen puitteissa siirrämme testatusti PHP-FPM:ään omilla pooleilla.
Usein kysytyt kysymykset
Miksi se on mod_php, vaikka moduulin nimi on php_module?
mod_php on puhekielinen nimi PHP:lle Apache-moduulina. Konfiguraatiossa se ladataan LoadModule-direktiivillä; PHP-käsikirja mainitsee esimerkkinä LoadModule php_module modules/libphp.so. Vanhemmat versiot käyttivät nimiä kuten php7_module tai php5_module.
Miksi mod_php tarvitsee prefork-MPM:n?
PHP-käsikirjan mukaan mod_php tarvitsee prefork-MPM:n, ellei PHP:tä ole käännetty Zend Thread Safetyn kanssa. Useimmat jakelupaketit on käännetty ilman Thread Safetya. Prefork käynnistää jokaiselle samanaikaiselle yhteydelle oman prosessin, mikä vaatii enemmän muistia.
Toimivatko .htaccess-tiedoston php_value-rivit myös PHP-FPM:n kanssa?
Eivät. php_value ja php_flag .htaccess-tiedostossa ovat PHP-moduulin Apache-direktiivejä ja toimivat vain mod_php:n kanssa. PHP-FPM:ssä tällaiset asetukset kuuluvat pooliin tai, sallittujen arvojen osalta, .user.ini-tiedostoon.
Pitääkö mod_php poistaa heti käytöstä?
Ensin tulee PHP:n päivitys ja Apachen täydellinen uudelleenkäynnistys. Siirtyminen PHP-FPM:ään on sen jälkeen järkevää, mutta se on suunniteltava ja testattava. Se ei sulje PHP2Shelliä, koska myös PHP-FPM on vaarassa.