Lyhyesti: CGI (Common Gateway Interface) on vanha rajapinta, jossa verkkopalvelin käynnistää jokaiselle pyynnölle uuden ohjelman, PHP:llä ohjelman php-cgi. FastCGI on sen jatkokehitys: PHP-prosessit toimivat pysyvästi ja ottavat vastaan monta pyyntöä socketin kautta. PHP-FPM on PHP:n tärkein FastCGI-toteutus. Tietoturvan kannalta olennaisia ovat ennen kaikkea cgi.*-asetukset ja sääntö, että FastCGI-yhteys ei saa koskaan olla julkisesti tavoitettavissa.
Mikä CGI on?
CGI on yksi vanhimmista tavoista, joilla verkkopalvelimet tuottavat dynaamista sisältöä. PHP-käsikirja viittaa asetuksen cgi.rfc2616_headers kohdalla RFC 3875:een, Common Gateway Interfacen määrittelyyn. Myös PHP:n alkuvaiheet olivat CGI-ohjelmia: Rasmus Lerdorf kirjoitti vuonna 1994 ensimmäiset ”Personal Home Page Tools” -työkalut CGI-binaareina C-kielellä.
Periaate: Jokaista pyyntöä varten verkkopalvelin käynnistää uuden prosessin, välittää pyyntötiedot ympäristömuuttujien ja vakiosyötteen kautta ja lukee vastauksen vakiotulosteesta. Sen jälkeen prosessi päättyy. PHP-käsikirjan mukaan PHP lukee CGI:ssä ja CLI:ssä php.ini-tiedostonsa uudelleen jokaisella kutsulla, palvelinmoduuleissa vain käynnistyksessä.
Tämä tekee CGI:stä kestävän, koska jokainen pyyntö alkaa tuoreesta prosessista. Se tekee CGI:stä myös hitaan: prosessin käynnistys, konfiguraation lataus ja laajennusten alustus vievät aikaa jokaisella pyynnöllä.
Mikä FastCGI on?
FastCGI ratkaisee suorituskykyongelman pitämällä prosessit hengissä. Verkkopalvelin yhdistää käynnissä olevaan prosessiin Unix-socketin tai TCP-portin kautta ja lähettää sille pyynnön FastCGI-protokollalla. Prosessi käsittelee sen ja odottaa seuraavaa.
| Ominaisuus | CGI | FastCGI ja php-cgi | FastCGI ja PHP-FPM |
|---|---|---|---|
| Prosessi pyyntöä kohden | kyllä | ei | ei |
| SAPI-nimi | cgi-fcgi |
cgi-fcgi |
fpm-fcgi |
| Poolit omalla käyttäjällä | ei | ei | kyllä |
| Prosessien ohjaus | verkkopalvelin | verkkopalvelinmoduuli, esim. mod_fcgid | oma master-prosessi |
.user.ini luetaan |
kyllä | kyllä | kyllä |
PHP-FPM on käsikirjan mukaan PHP:n ensisijainen FastCGI-toteutus. Se täydentää protokollaa prosessinhallinnalla, pooleilla, tilasivuilla ja slowlogilla. Yksityiskohdat ovat sivulla PHP-FPM selitettynä.
php.ini-tiedoston cgi-asetukset
CGI-käyttöä varten PHP:ssä on omat asetuksensa. Seuraavat arvot ja kuvaukset ovat PHP-käsikirjasta:
cgi.force_redirect(oletus 1,INI_SYSTEM): käsikirjan mukaan tarpeen, jotta PHP:tä voi ajaa CGI:nä turvallisesti useimmilla verkkopalvelimilla. Pois päältä vain ”omalla vastuulla”; IIS:ssä sen on oltava pois päältä.cgi.fix_pathinfo(oletus 1,INI_SYSTEM): huolehtii oikeistaPATH_INFO- jaPATH_TRANSLATED-arvoista. Komentosarjojen tulisi käyttääSCRIPT_FILENAME-arvoaPATH_TRANSLATED-arvon sijaan.cgi.discard_path(oletus 0,INI_SYSTEM): mahdollistaa CGI-binaarin turvallisen sijoittamisen verkkohakemiston ulkopuolelle ilman, että.htaccess-suojaus voidaan ohittaa.fastcgi.impersonate(oletus 0,INI_SYSTEM): merkitystä vain IIS:llä Windowsissa.user_ini.filenamejauser_ini.cache_ttl(oletus.user.inija 300 sekuntia): ohjaavat, lukeeko PHP.user.ini-tiedostoja ja kuinka usein.
Nginxin kanssa kuuluu asiaan komentosarjan polun puhdas välitys. Luettava perusmalli, ilman takuuta jokaiseen ympäristöön:
location ~ \.php$ {
try_files $uri =404; # anna PHP:lle vain olemassa olevat tiedostot
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
Rivi try_files $uri =404; estää sen, että pyynnöt olemattomiin .php-polkuihin välitetään PHP:lle.
Miksi avoin FastCGI-yhteys on vaarallinen
PHP-käsikirja varoittaa nimenomaisesti: Se, joka voi avata FastCGI-yhteyden PHP:hen, hallitsee pyynnön konfiguraatiota, esimerkiksi auto_prepend_file-asetusta, ja voi siten suorittaa mielivaltaista koodia. Syynä on, että verkkopalvelimet saavat lähettää PHP-asetuksia mukana FastCGI-parametreilla kuten PHP_VALUE ja PHP_ADMIN_VALUE.
Tästä seuraa selkeät säännöt:
- Liittäkää PHP-FPM tai FastCGI-tilassa toimiva php-cgi vain Unix-socketilla, jos verkkopalvelin toimii samalla isännällä.
- TCP:n kanssa asettakaa
listen.allowed_clientsja sulkekaa portti palomuurissa; vinkkejä artikkelissa Verkkopalvelimen palomuuri. - Pitäkää socketin oikeudet tiukkoina asetuksilla
listen.owner,listen.groupjalisten.mode.
Tarkistakaa komennolla ss -lntp | grep -i php, kuunteleeko jokin PHP-prosessi TCP-osoitteessa. Sidonta osoitteeseen 0.0.0.0 tai julkiseen osoitteeseen on kiireellistä toimintaa vaativa tilanne.
CGI, FastCGI ja PHP2Shell
PHP2Shell koskee sekä php-cgi:tä että PHP-FPM:ää. Molemmille pätee: päivitys versioon 8.5.12, 8.4.27, 8.3.36 tai 8.2.35 tai vahvistettuun backportiin, ja sen jälkeen kaikkien käynnissä olevien PHP-prosessien lopetus ja uudelleenkäynnistys. FastCGI-ympäristöissä, joissa on php-cgi, prosessit jäävät usein huomaamatta käyntiin, koska mikään oma palvelu ei hallinnoi niitä. Miten tämän perinnön löytää ja korvaa, kerrotaan sivulla php-cgi: riskialtis perintö. Pleskissä variantit ovat nimetty eri tavoin; apua antaa Plesk: PHP-käsittelijöiden ymmärtäminen.
Miten PHP SOS auttaa konkreettisesti?
- Käsittelijöiden kartoitus: Selvitämme, toimivatko verkkosivustonne CGI:llä, FastCGI:llä ja php-cgi:llä vai PHP-FPM:llä.
- Yhteyksien sulkeminen: Tarkistamme socketit, portit ja palomuurisäännöt, jotta mikään FastCGI-yhteys ei ole tavoitettavissa ulkopuolelta.
- Päivitys ja siivous: Päivitämme PHP:n ja lopetamme kaikki vanhat prosessit, myös orvoiksi jääneet php-cgi-instanssit.
- Korvaaminen: Palvelimen koventamisen puitteissa korvaamme CGI-perinnön PHP-FPM:llä ja omilla pooleilla.
Usein kysytyt kysymykset
Onko FastCGI sama asia kuin PHP-FPM?
Ei. FastCGI on protokolla, jonka kautta verkkopalvelin keskustelee sovellusprosessin kanssa. PHP-FPM on ohjelma, joka toteuttaa tämän protokollan PHP:lle ja hallinnoi prosesseja. Myös php-cgi osaa FastCGI:tä, mutta siinä ei ole pooleja.
Miksi pelkkää CGI:tä pidetään vanhentuneena?
CGI:ssä verkkopalvelin käynnistää jokaiselle pyynnölle uuden prosessin, ja PHP lukee silloin joka kerta konfiguraationsa. Se vie aikaa ja resursseja. FastCGI ja PHP-FPM pitävät prosessit pysyvästi valmiina ja ovat siksi selvästi tehokkaampia.
Mikä on .user.ini?
Tiedosto .user.ini on pieni konfiguraatiotiedosto verkkohakemistossa. PHP-käsikirjan mukaan vain CGI- ja FastCGI-SAPI:t lukevat sen, siis myös PHP-FPM. Siinä saa olla vain asetuksia, joiden tila on INI_PERDIR, INI_USER tai INI_ALL.
Mistä tiedän, toimiiko palvelimellani php-cgi?
Etsikää vain lukevilla komennoilla, kuten ps tai pgrep, prosesseja nimeltä php-cgi ja katsokaa verkkopalvelimen konfiguraatiosta merkintöjä kuten mod_fcgid, Action tai ScriptAlias php-cgi:n kanssa. Hosting-paneeleissa ajotapaa kutsutaan usein nimellä CGI tai FastCGI-sovellus.