Röviden: A CGI (Common Gateway Interface) egy régi felület, amelynél a webszerver minden kéréshez új programot indít, a PHP esetében a php-cgi programot. A FastCGI a továbbfejlesztése: a PHP-folyamatok tartósan futnak, és sok kérést fogadnak egy socketen keresztül. A PHP-FPM a PHP legfontosabb FastCGI-megvalósítása. Biztonság szempontjából főként a cgi.* beállítások számítanak, és az a szabály, hogy egy FastCGI-hozzáférés soha nem lehet nyilvánosan elérhető.
Mi a CGI?
A CGI az egyik legrégebbi módszer, amellyel a webszerverek dinamikus tartalmat állítanak elő. A PHP-kézikönyv a cgi.rfc2616_headers beállításnál az RFC 3875-re utal, a Common Gateway Interface specifikációjára. A PHP kezdetei is CGI-programok voltak: Rasmus Lerdorf 1994-ben az első „Personal Home Page Tools” eszközöket C nyelvű CGI-bináris fájlokként írta meg.
Az elv: minden kéréshez a webszerver új folyamatot indít, a kérés adatait környezeti változókon és a standard bemeneten adja át, és a választ a standard kimenetről olvassa. Utána a folyamat véget ér. A PHP-kézikönyv szerint a PHP CGI és CLI esetén minden híváskor újra beolvassa a php.ini-jét, szervermodulok esetén csak induláskor.
Ez robusztussá teszi a CGI-t, mert minden kérés friss folyamattal kezdődik. Lassúvá is teszi: a folyamat indítása, a konfiguráció betöltése és a bővítmények inicializálása minden kérésnél időt vesz igénybe.
Mi a FastCGI?
A FastCGI a teljesítményproblémát úgy oldja meg, hogy a folyamatok életben maradnak. A webszerver Unix-socketen vagy TCP-porton keresztül csatlakozik egy futó folyamathoz, és a FastCGI protokollban elküldi neki a kérést. A folyamat feldolgozza, és várja a következőt.
| Jellemző | CGI | FastCGI php-cgi-vel | FastCGI PHP-FPM-mel |
|---|---|---|---|
| Folyamat kérésenként | igen | nem | nem |
| SAPI-név | cgi-fcgi |
cgi-fcgi |
fpm-fcgi |
| Poolok saját felhasználóval | nem | nem | igen |
| Folyamatvezérlés | webszerver | webszerver-modul, pl. mod_fcgid | saját master folyamat |
A .user.ini olvasása |
igen | igen | igen |
A PHP-FPM a kézikönyv szerint a PHP elsődleges FastCGI-megvalósítása. A protokollt folyamatkezeléssel, poolokkal, állapotoldalakkal és slowloggal egészíti ki. A részleteket a PHP-FPM elmagyarázva oldal tartalmazza.
A cgi-beállítások a php.ini-ben
CGI-üzemhez a PHP saját beállításokat ismer. A következő értékek és leírások a PHP-kézikönyvből származnak:
cgi.force_redirect(alapérték 1,INI_SYSTEM): a kézikönyv szerint szükséges ahhoz, hogy a PHP-t CGI-ként a legtöbb webszerver alatt biztonságosan lehessen üzemeltetni. Kikapcsolni csak „saját felelősségre”; IIS alatt ki kell kapcsolni.cgi.fix_pathinfo(alapérték 1,INI_SYSTEM): gondoskodik a helyesPATH_INFOésPATH_TRANSLATEDértékekről. A szkripteknek aPATH_TRANSLATEDhelyett aSCRIPT_FILENAMEértéket kell használniuk.cgi.discard_path(alapérték 0,INI_SYSTEM): lehetővé teszi, hogy a CGI-bináris fájlt biztonságosan a webkönyvtáron kívül helyezzék el úgy, hogy a.htaccess-védelem ne kerülhető meg.fastcgi.impersonate(alapérték 0,INI_SYSTEM): csak Windows alatt, IIS esetén releváns.user_ini.filenameésuser_ini.cache_ttl(alapérték.user.iniés 300 másodperc): azt szabályozzák, hogy a PHP olvassa-e a.user.inifájlokat, és milyen gyakran.
Nginx esetén ide tartozik a szkript útvonalának tiszta átadása. Egy olvasható alapminta, nem minden környezetre szóló garanciával:
location ~ \.php$ {
try_files $uri =404; # csak létező fájlokat adjon át a PHP-nek
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
A try_files $uri =404; sor megakadályozza, hogy a nem létező .php útvonalakra érkező kéréseket továbbadják a PHP-nek.
Miért veszélyes egy nyitott FastCGI-hozzáférés
A PHP-kézikönyv kifejezetten figyelmeztet: aki meg tud nyitni egy FastCGI-kapcsolatot a PHP-hoz, az irányítja a kérés konfigurációját, például az auto_prepend_file beállítást, és ezzel tetszőleges kódot hajthat végre. Az ok az, hogy a webszerverek a PHP-beállításokat FastCGI-paraméterekkel, például a PHP_VALUE és a PHP_ADMIN_VALUE útján is elküldhetik.
Ebből egyértelmű szabályok következnek:
- A PHP-FPM-et vagy a FastCGI módú php-cgi-t csak Unix-socketen keresztül kell csatlakoztatni, ha a webszerver ugyanazon a gépen fut.
- TCP esetén be kell állítani a
listen.allowed_clientsértékét, és a portot le kell tiltani a tűzfalban; ehhez útmutatás a Tűzfal webszerverekhez cikkben található. - A socket jogait a
listen.owner,listen.groupéslisten.modebeállításokkal szűken kell tartani.
Az ss -lntp | grep -i php paranccsal ellenőrizze, hogy egy PHP-folyamat figyel-e TCP-címen. A 0.0.0.0-hoz vagy nyilvános címhez való kötés sürgős cselekvést igénylő eset.
CGI, FastCGI és PHP2Shell
A PHP2Shell a php-cgi-t és a PHP-FPM-et egyaránt érinti. Mindkettőre érvényes: frissítés a 8.5.12, 8.4.27, 8.3.36 vagy 8.2.35 verzióra, illetve egy megerősített backportra, majd az összes futó PHP-folyamat leállítása és újraindítása. A php-cgi-t használó FastCGI-beállításoknál a folyamatok gyakran észrevétlenül tovább futnak, mert nincs önálló szolgáltatás, amely kezelné őket. Hogyan találhatja meg és válthatja le ezt az örökölt terhet, azt a php-cgi: örökölt teher kockázattal oldal írja le. A Pleskben a változatok más néven szerepelnek; segít a Plesk: a PHP-kezelők megértése.
Hogyan segít konkrétan a PHP SOS?
- Kezelők felmérése: Megállapítjuk, hogy a weboldalai CGI-n, php-cgi-vel működő FastCGI-n vagy PHP-FPM-en futnak-e.
- Hozzáférések lezárása: Ellenőrizzük a socketeket, a portokat és a tűzfalszabályokat, hogy semmilyen FastCGI-hozzáférés ne legyen kívülről elérhető.
- Javítás és takarítás: Frissítjük a PHP-t, és leállítjuk az összes régi folyamatot, az elárvult php-cgi példányokat is.
- Leváltás: A szerver-megerősítés keretében a CGI-örökségeket PHP-FPM-mel váltjuk le, saját poolokkal.
Gyakori kérdések
A FastCGI ugyanaz, mint a PHP-FPM?
Nem. A FastCGI egy protokoll, amelyen a webszerver egy alkalmazásfolyamattal beszél. A PHP-FPM egy program, amely ezt a protokollt valósítja meg a PHP-hoz, és kezeli a folyamatokat. A php-cgi is tud FastCGI-t beszélni, de poolokat nem kínál.
Miért számít a tiszta CGI elavultnak?
CGI esetén a webszerver minden kéréshez új folyamatot indít, és a PHP minden alkalommal újra beolvassa a konfigurációját. Ez időt és erőforrást emészt. A FastCGI és a PHP-FPM tartósan készenlétben tartja a folyamatokat, ezért jóval hatékonyabbak.
Mi az a .user.ini?
A .user.ini egy kis konfigurációs fájl egy webkönyvtárban. A PHP-kézikönyv szerint csak a CGI és a FastCGI SAPI-k olvassák, tehát a PHP-FPM is. Csak INI_PERDIR, INI_USER vagy INI_ALL módú beállításokat tartalmazhat.
Honnan tudom, hogy a szerveremen php-cgi fut?
Olvasó parancsokkal, például a ps-sel vagy a pgrep-pel keressen php-cgi nevű folyamatokat, és nézze meg a webszerver-konfigurációban az olyan bejegyzéseket, mint a mod_fcgid, az Action vagy a ScriptAlias php-cgi-vel. A tárhelyvezérlő paneleken az üzemmód neve gyakran CGI vagy FastCGI-alkalmazás.