Trumpai: CGI (Common Gateway Interface) yra sena sąsaja, kai žiniatinklio serveris kiekvienai užklausai paleidžia naują programą, PHP atveju programą php-cgi. FastCGI yra tolesnis vystymas: PHP procesai veikia nuolat ir per lizdą (socket) priima daug užklausų. PHP-FPM yra svarbiausias PHP FastCGI įgyvendinimas. Saugumui svarbiausi yra cgi.* nustatymai ir taisyklė, kad FastCGI prieiga niekada neturi būti pasiekiama viešai.
Kas yra CGI?
CGI yra vienas seniausių būdų, kuriais žiniatinklio serveriai kuria dinaminį turinį. PHP vadovas nustatymo cgi.rfc2616_headers aprašyme nurodo RFC 3875, Common Gateway Interface specifikaciją. Ir PHP pradžia buvo CGI programos: Rasmus Lerdorf 1994 m. pirmuosius „Personal Home Page Tools“ parašė C kalba kaip CGI dvejetainius failus.
Principas: kiekvienai užklausai žiniatinklio serveris paleidžia naują procesą, perduoda užklausos duomenis per aplinkos kintamuosius ir standartinį įvestį ir skaito atsakymą iš standartinės išvesties. Po to procesas baigiasi. Pasak PHP vadovo, CGI ir CLI atveju PHP savo php.ini nuskaito iš naujo per kiekvieną iškvietimą, serverio moduliams tik paleidžiant.
Dėl to CGI patikimas, nes kiekviena užklausa prasideda su šviežiu procesu. Bet dėl to jis ir lėtas: proceso paleidimas, konfigūracijos įkėlimas ir plėtinių inicializavimas kiekvienai užklausai kainuoja laiko.
Kas yra FastCGI?
FastCGI sprendžia našumo problemą tuo, kad procesai lieka gyvi. Žiniatinklio serveris per Unix lizdą arba TCP prievadą prisijungia prie veikiančio proceso ir siunčia jam užklausą FastCGI protokolu. Procesas ją apdoroja ir laukia kitos.
| Požymis | CGI | FastCGI su php-cgi | FastCGI su PHP-FPM |
|---|---|---|---|
| Procesas kiekvienai užklausai | taip | ne | ne |
| SAPI pavadinimas | cgi-fcgi |
cgi-fcgi |
fpm-fcgi |
| Baseinai su atskiru naudotoju | ne | ne | taip |
| Procesų valdymas | žiniatinklio serveris | žiniatinklio serverio modulis, pvz., mod_fcgid | atskiras master procesas |
.user.ini skaitomas |
taip | taip | taip |
Pasak vadovo, PHP-FPM yra pagrindinis PHP FastCGI įgyvendinimas. Jis protokolą papildo procesų valdymu, baseinais, būsenos puslapiais ir lėtų užklausų žurnalu (slowlog). Smulkmenos aprašytos skyriuje PHP-FPM paaiškinta.
cgi nustatymai php.ini
CGI veikimui PHP turi savus nustatymus. Toliau pateiktos reikšmės ir aprašymai paimti iš PHP vadovo:
cgi.force_redirect(numatytoji 1,INI_SYSTEM): pasak vadovo, reikalingas, kad PHP kaip CGI būtų saugiai eksploatuojamas daugumoje žiniatinklio serverių. Išjungti tik „savo rizika“; IIS jis turi būti išjungtas.cgi.fix_pathinfo(numatytoji 1,INI_SYSTEM): užtikrina teisingasPATH_INFOirPATH_TRANSLATEDreikšmes. Skriptai turėtų naudotiSCRIPT_FILENAME, o nePATH_TRANSLATED.cgi.discard_path(numatytoji 0,INI_SYSTEM): leidžia CGI dvejetainį failą saugiai laikyti už žiniatinklio katalogo ribų, neapeinant.htaccessapsaugos.fastcgi.impersonate(numatytoji 0,INI_SYSTEM): aktualus tik IIS sistemoje Windows.user_ini.filenameiruser_ini.cache_ttl(numatytosios.user.iniir 300 sekundžių): nustato, ar ir kaip dažnai PHP skaito.user.inifailus.
Nginx atveju prie to priklauso tvarkingas skripto kelio perdavimas. Skaitomas pagrindinis šablonas, be garantijos kiekvienai aplinkai:
location ~ \.php$ {
try_files $uri =404; # PHP perduoti tik esamus failus
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
Eilutė try_files $uri =404; neleidžia užklausų į neegzistuojančius .php kelius perduoti PHP.
Kodėl atvira FastCGI prieiga pavojinga
PHP vadovas aiškiai įspėja: kas gali atidaryti FastCGI ryšį su PHP, tas valdo užklausos konfigūraciją, pavyzdžiui, auto_prepend_file, ir taip gali vykdyti bet kokį kodą. Priežastis ta, kad žiniatinklio serveriai per FastCGI parametrus, tokius kaip PHP_VALUE ir PHP_ADMIN_VALUE, gali kartu siųsti PHP nustatymus.
Iš to kyla aiškios taisyklės:
- PHP-FPM ar php-cgi FastCGI režimu jungti tik per Unix lizdą, jei žiniatinklio serveris veikia tame pačiame kompiuteryje.
- Naudojant TCP, nustatyti
listen.allowed_clientsir užblokuoti prievadą ugniasienėje; nuorodos straipsnyje Ugniasienė žiniatinklio serveriams. - Lizdo teises su
listen.owner,listen.groupirlisten.modelaikyti kuo siauresnes.
Su ss -lntp | grep -i php patikrinkite, ar kuris nors PHP procesas klauso TCP adreso. Susiejimas su 0.0.0.0 ar viešu adresu yra skubaus veiksmo atvejis.
CGI, FastCGI ir PHP2Shell
PHP2Shell paveikti ir php-cgi, ir PHP-FPM. Abiem galioja: atnaujinti iki 8.5.12, 8.4.27, 8.3.36 ar 8.2.35 arba patvirtinto backport, po to nutraukti ir iš naujo paleisti visus veikiančius PHP procesus. FastCGI sąrankose su php-cgi procesai dažnai nepastebimai veikia toliau, nes jų nevaldo atskira tarnyba. Kaip šį palikimą rasti ir pašalinti, aprašyta skyriuje php-cgi: palikimas su rizika. Plesk variantai vadinasi kitaip; padeda Plesk: PHP tvarkyklių supratimas.
Kaip PHP SOS padeda konkrečiai?
- Tvarkyklių surinkimas: nustatome, ar jūsų svetainės veikia per CGI, FastCGI su php-cgi ar PHP-FPM.
- Prieigų uždarymas: tikriname lizdus, prievadus ir ugniasienės taisykles, kad jokia FastCGI prieiga nebūtų pasiekiama iš išorės.
- Pataisyti ir sutvarkyti: atnaujiname PHP ir nutraukiame visus senus procesus, taip pat apleistus php-cgi egzempliorius.
- Pakeitimas: serverio sutvirtinimo rėmuose CGI palikimą keičiame PHP-FPM su atskirais baseinais.
Dažni klausimai
Ar FastCGI yra tas pats, kas PHP-FPM?
Ne. FastCGI yra protokolas, kuriuo žiniatinklio serveris kalbasi su programos procesu. PHP-FPM yra programa, kuri šį protokolą įgyvendina PHP ir valdo procesus. Ir php-cgi gali kalbėti FastCGI, bet baseinų (pool) nesiūlo.
Kodėl grynas CGI laikomas pasenusiu?
Esant CGI, žiniatinklio serveris kiekvienai užklausai paleidžia naują procesą, o PHP kiekvieną kartą iš naujo skaito konfigūraciją. Tai kainuoja laiką ir išteklius. FastCGI ir PHP-FPM procesus laiko nuolat paruoštus, todėl yra gerokai efektyvesni.
Kas yra .user.ini?
Failas .user.ini yra mažas konfigūracijos failas žiniatinklio kataloge. Pasak PHP vadovo, jį skaito tik CGI ir FastCGI SAPI, taigi ir PHP-FPM. Jame gali būti tik nustatymai su režimais INI_PERDIR, INI_USER ar INI_ALL.
Kaip atpažinti, ar mano serveryje veikia php-cgi?
Tik skaitančiomis komandomis, tokiomis kaip ps ar pgrep, ieškoti procesų, vadinamų php-cgi, ir žiniatinklio serverio konfigūracijoje žiūrėti įrašų, tokių kaip mod_fcgid, Action ar ScriptAlias su php-cgi. Hostingo skydeliuose veikimo režimas dažnai vadinamas CGI arba FastCGI programa.