# CGI ja FastCGI: perusteet

> CGI ja FastCGI PHP:n kanssa selitettynä: prosessi pyyntöä kohden vai pysyvät workerit, php-cgi:n ja PHP-FPM:n rooli, cgi-asetukset ja tietoturvasäännöt.

Lähde: https://phpsos.de/fi/php/cgi-und-fastcgi/  
Tilanne: 25.10.2026  
Palveluntarjoaja: PHP SOS, PHP-hätäapu ja palvelimen tietoturva. Pikaapu WhatsAppilla: https://wa.me/491736494914?text=Hei%20PHP%20SOS%2C%20tarvitsemme%20apua%20PHP-palvelimemme%20kanssa.%20Yritys%3A%20%E2%80%A6%20Verkkosivusto%3A%20%E2%80%A6

**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ä](https://phpsos.de/fi/php/php-fpm-erklaert/).

## php.ini-tiedoston cgi-asetukset

CGI-käyttöä varten PHP:ssä on omat asetuksensa. Seuraavat arvot ja kuvaukset ovat PHP-käsikirjasta:

1. **`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ä.
2. **`cgi.fix_pathinfo`** (oletus 1, `INI_SYSTEM`): huolehtii oikeista `PATH_INFO`- ja `PATH_TRANSLATED`-arvoista. Komentosarjojen tulisi käyttää `SCRIPT_FILENAME`-arvoa `PATH_TRANSLATED`-arvon sijaan.
3. **`cgi.discard_path`** (oletus 0, `INI_SYSTEM`): mahdollistaa CGI-binaarin turvallisen sijoittamisen verkkohakemiston ulkopuolelle ilman, että `.htaccess`-suojaus voidaan ohittaa.
4. **`fastcgi.impersonate`** (oletus 0, `INI_SYSTEM`): merkitystä vain IIS:llä Windowsissa.
5. **`user_ini.filename`** ja **`user_ini.cache_ttl`** (oletus `.user.ini` ja 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:

```nginx
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_clients` ja sulkekaa portti palomuurissa; vinkkejä artikkelissa [Verkkopalvelimen palomuuri](https://phpsos.de/fi/blog/firewall-fuer-webserver/).
- Pitäkää socketin oikeudet tiukkoina asetuksilla `listen.owner`, `listen.group` ja `listen.mode`.

> **Tärkeää:**
> 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ö](https://phpsos.de/fi/server/php-cgi/). Pleskissä variantit ovat nimetty eri tavoin; apua antaa [Plesk: PHP-käsittelijöiden ymmärtäminen](https://phpsos.de/fi/blog/plesk-php-handler/).

## 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](https://phpsos.de/fi/leistungen/server-haertung/) 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.

## Lähteet

- [PHP-käsikirja: ydinasetukset (cgi.*)](https://www.php.net/manual/en/ini.core.php)
- [PHP-käsikirja: .user.ini-tiedostot](https://www.php.net/manual/en/configuration.file.per-user.php)
- [PHP-käsikirja: FPM-konfiguraatio](https://www.php.net/manual/en/install.fpm.configuration.php)
- [Nginxin dokumentaatio](https://nginx.org/en/docs/)
