Röviden: A mod_php a PHP modulként az Apache webszerverben. Minden Apache-folyamat ilyenkor egy teljes PHP-értelmezőt tartalmaz, és maga hajtja végre a PHP-kódot; a SAPI neve apache2handler. Egyszerű beállítani, de a PHP-t az Apache-hoz köti, többnyire a prefork MPM-et igényli, és alig engedi a weboldalak szétválasztását. A PHP-kézikönyv új telepítésekhez ellenzi, és a PHP2Shell esetében a PHP-csapat a mod_php kockázatát értékeli a legmagasabbra.
Mi a mod_php?
mod_php esetén az Apache a PHP-t önálló modulként tölti be a folyamataiba. Nincs különálló PHP-szolgáltatás: ha az Apache-nak egy .php fájlt kell kiszolgálnia, ugyanaz a folyamat, amely a kérést fogadta, hajtja végre a PHP-kódot is. Sok éven át ez volt a PHP üzemeltetésének alapértelmezett módja, és régebbi szervereken, valamint egyes Docker-képekben a mai napig elterjedt.
A PHP-kézikönyv szerint a PHP szervermodulként a konfigurációját csak egyszer olvassa be, a webszerver indításakor. A php.ini módosításai és a modul frissítései ezért csak az Apache újraindítása után hatnak.
A megértéshez fontos: az Apache-folyamatok hosszú életűek. Egy folyamat sok kapcsolatot fogad egymás után, mielőtt lecserélik; hányat, azt az Apache MaxConnectionsPerChild direktívája szabályozza. A beágyazott PHP-értelmező ez idő alatt ugyanaz marad. Aki a libphp könyvtárat kicseréli a lemezen, a futó folyamatokon nem változtat.
Ügyvezetők és projektfelelősök számára ez így foglalható össze: mod_php esetén a webszerver és a PHP egységet alkot. Aki az egyikhez nyúl, a másikat is érinti. A PHP-frissítés a webszerver újraindítását jelenti, a PHP hibája a webszerver jogaival fut, és az ugyanazon a szerveren lévő több weboldal szétválasztása alig lehetséges.
Hogyan kapcsolják be a mod_php-t?
A PHP-kézikönyv két lépésben mutatja be a beillesztést: a modul betöltése, és annak meghatározása, mely fájlokat dolgozza fel a PHP.
LoadModule php_module modules/libphp.so
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
A kézikönyv csak az AddType helyett a SetHandler melletti FilesMatch-et ajánlja, hogy a feltöltött fájlokat, például a bild.php.jpg-t, ne hajtsa végre PHP-ként. Debianon és Ubuntun az olyan csomagok, mint a libapache2-mod-php8.3, valamint az a2enmod és a2dismod parancsok végzik ezt a munkát.
Hogy a mod_php aktív-e, az csak olvasva ellenőrizhető:
apachectl -M 2>/dev/null | grep -i php # Debian/Ubuntu
httpd -M 2>/dev/null | grep -i php # RHEL-család
apachectl -V | grep -i mpm # aktív MPM (prefork, worker, event)
Prefork, thread safety és erőforrások
Az Apache a kéréseket egy Multi-Processing-modulon (MPM) keresztül osztja el. A PHP-kézikönyv szerint a mod_php a prefork MPM-et igényli, hacsak a PHP-t nem Zend Thread Safety-vel (--enable-zts) építették. A legtöbb disztribúciós csomag thread safety nélkül készül.
A prefork azt jelenti: egy folyamat egyidejű kapcsolatonként, és minden folyamat egy teljes PHP-értelmezőt hord magával. A képek vagy CSS-fájlok kérései is így egy PHP-val megrakott folyamatot foglalnak le. Ez memóriát emészt, és korlátozza a terhelést, amelyet egy szerver elbír.
| Jellemző | mod_php | PHP-FPM |
|---|---|---|
| Hol fut a PHP? | minden Apache-folyamatban | önálló szolgáltatásban |
| Apache MPM | többnyire prefork |
event lehetséges |
| Felhasználó weboldalanként | nem, minden az Apache-felhasználóként | igen, poolonként |
| PHP újraindítása | csak az Apache-csal együtt | az Apache-tól függetlenül |
| Könyvtárankénti beállítások | php_value a .htaccess-ben |
pool vagy .user.ini |
A kézikönyv ezért minden modern telepítéshez a PHP-FPM-et ajánlja mod_proxy_fcgi-vel: jobb erőforrás-kezelés, folyamatok elkülönítése, a PHP újraindítása az Apache újraindítása nélkül, és kompatibilitás az event MPM-mel, amely az Apache 2.4 óta az alapértelmezett. Az alapokat a PHP-FPM elmagyarázva oldal írja le.
Beállítások a .htaccess, a php_value és a php_admin_value segítségével
A mod_php-vel a PHP-beállítások közvetlenül az Apache-konfigurációban adhatók meg. A kézikönyv itt módosítási módokat különböztet meg: az INI_PERDIR bejegyzések szerepelhetnek a php.ini-ben, a .htaccess-ben vagy a httpd.conf-ban, az INI_SYSTEM bejegyzések csak a php.ini-ben vagy a httpd.conf-ban.
# A VirtualHost-konfigurációban: az alkalmazás számára zárolt
php_admin_flag display_errors off
php_admin_value upload_max_filesize 24M
# A .htaccess-ben lehetséges, de az alkalmazás felülírhatja
php_value max_execution_time 60
A php_admin_value és a php_admin_flag csak a szerverkonfigurációban megengedett, a .htaccess-ben nem. Éppen ez a megkülönböztetés fontos a PHP2Shell átmeneti intézkedéseinél, mert az olyan értékeket, mint a session.upload_progress.enabled, az alkalmazás nem állíthatja vissza.
mod_php és PHP2Shell: miért a legmagasabb a kockázat
A PHP-csapat a PHP2Shell kockázatát a mod_php esetében értékeli a legmagasabbra: ott még azelőtt bemutattak egy exploitot, hogy egyáltalán alkalmazáskód futna. A biztonsági bővítmények vagy a CMS-ben lévő ellenőrzések így későn jönnek. Ehhez jön, hogy mod_php esetén a PHP a webszerver jogaival és memóriájában fut. A részletes besorolás a Miért a legmagasabb a mod_php kockázata oldalon található.
Az üzemeltetők számára ezért ez érvényes:
- A PHP-modult frissíteni kell a 8.5.12, 8.4.27, 8.3.36 vagy 8.2.35 verzióra, illetve egy megerősített backportra.
- Az Apache-ot teljesen újra kell indítani, nem csak újratölteni, és ellenőrizni kell a folyamatok indítási idejét.
- Az átmeneti értékeket
php_admin_valueútján kell megadni a szerverkonfigurációban, ha a frissítés még nem lehetséges. - Ezután meg kell tervezni az átállást PHP-FPM-re, ahogy az Apache védelme mod_php esetén oldalon le van írva.
Hogyan segít konkrétan a PHP SOS?
- Felismerés: Megvizsgáljuk, mely szervereken fut mod_php, milyen MPM-mel és melyik csomagforrásból.
- Javítás: Frissítjük a PHP-modult, teljesen újraindítjuk az Apache-ot, és igazoljuk az állapotot.
- Az átmenet biztosítása: Ahol a frissítés blokkolt, a php.net intézkedéseit zárolva adjuk meg a szerverkonfigurációban.
- Átállítás: A szerver-megerősítés keretében tesztelten migrálunk PHP-FPM-re, saját poolokkal.
Gyakori kérdések
Miért mod_php a neve, ha a modul php_module?
A mod_php a PHP Apache-modulként való futtatásának köznyelvi neve. A konfigurációban a LoadModule tölti be; a PHP-kézikönyv példaként a LoadModule php_module modules/libphp.so sort mutatja. Régebbi verziók olyan neveket használtak, mint a php7_module vagy a php5_module.
Miért kell a mod_php-nek a prefork MPM?
A PHP-kézikönyv szerint a mod_php a prefork MPM-et igényli, hacsak a PHP-t nem Zend Thread Safety-vel építették. A legtöbb disztribúciós csomag thread safety nélkül készül. A prefork minden egyidejű kapcsolathoz külön folyamatot indít, ami több memóriát igényel.
Működnek a .htaccess-beli php_value sorok PHP-FPM-mel is?
Nem. A .htaccess-ben lévő php_value és php_flag a PHP-modul Apache-direktívái, és csak a mod_php-vel hatnak. PHP-FPM alatt az ilyen beállítások a poolba tartoznak, vagy az engedélyezett értékeknél egy .user.ini-be.
Azonnal meg kell szüntetnem a mod_php-t?
Először a PHP frissítése jön az Apache teljes újraindításával. A PHP-FPM-re váltás ezután értelmes, de tervezni és tesztelni kell. A PHP2Shellt nem zárja be, mert a PHP-FPM-et is érinti.