Ukratko: PHP-FPM (FastCGI Process Manager) pokreće PHP kao zasebnu uslugu uz web-poslužitelj. Master proces upravlja poolovima, a svaki pool pokreće workere koji zahtjeve obrađuju putem FastCGI-ja. Poolovi se mogu voditi po web-stranici s vlastitim korisnikom, vlastitim ograničenjima i zaključanim PHP postavkama. Budući da workeri redom obrađuju mnogo zahtjeva, nakon PHP ažuriranja svi se moraju ponovno pokrenuti.
Što je PHP-FPM?
PHP priručnik opisuje FPM kao primarnu FastCGI implementaciju PHP-a s funkcijama koje su korisne ponajprije za jako opterećene web-stranice. FPM je uključen s PHP-om 5.3.3 kao zaseban SAPI, dakle kao zaseban način rada. Njegov SAPI naziv je fpm-fcgi.
Razlika u odnosu na mod_php: PHP ne radi u web-poslužitelju, nego kao zasebna usluga. Nginx, Apache ili neki drugi web-poslužitelj PHP zahtjeve prosljeđuje putem FastCGI protokola i dobiva natrag gotov odgovor. Web-poslužitelj i PHP tako se mogu neovisno jedan o drugome ponovno pokretati, konfigurirati i osiguravati. Kako FastCGI u načelu radi, piše u članku CGI i FastCGI.
Master, poolovi i workeri: model procesa
PHP-FPM sastoji se od triju razina:
- Master proces: čita konfiguraciju, otvara socketove i pokreće ili završava workere. Sam ne izvršava kod aplikacije.
- Poolovi: Svaki pool ima naziv, vlastiti socket ili port, vlastitog Unix korisnika i vlastite PHP postavke. Priručnik izričito navodi različite uid, gid, chroot, okolinu i php.ini po poolu.
- Workeri: procesi poola koji primaju i izvršavaju zahtjeve. Worker redom obrađuje mnogo zahtjeva prije nego što se zamijeni.
Koliko workera radi, određuje upravitelj procesa direktivom pm:
| Način | Ponašanje | Važne direktive |
|---|---|---|
static |
stalan broj workera | pm.max_children |
dynamic |
workeri između donje i gornje granice | pm.start_servers, pm.min_spare_servers, pm.max_spare_servers |
ondemand |
workeri tek po potrebi, uklanjanje nakon mirovanja | pm.process_idle_timeout (zadano 10s) |
pm.max_children u svim načinima ograničava broj istodobnih zahtjeva. pm.max_requests zamjenjuje worker nakon utvrđenog broja zahtjeva; zadano 0 znači neograničeno.
Koji način odgovara, ovisi o opterećenju. static uvijek drži spreman jednak broj workera i prikladan je za ravnomjerno jako korištene aplikacije s dovoljno radne memorije. dynamic je kompromis za većinu web-stranica. ondemand štedi memoriju na poslužiteljima s mnogo malih web-stranica jer poolovi bez posjetitelja ne zauzimaju workere; zato prvi zahtjev nakon stanke traje nešto dulje. Previsoko postavljen pm.max_children može poslužitelj pri vršnom opterećenju dovesti do nestašice memorije, a prenizak vodi do čekanja i poruka o pogrešci web-poslužitelja.
Pool sa sigurnim osnovnim postavkama
Primjer zasebnog poola po web-stranici, s direktivama iz PHP priručnika. Putanje i vrijednosti su primjeri:
; /etc/php/8.3/fpm/pool.d/kunde-a.conf
[kunde-a]
user = kunde-a
group = kunde-a
listen = /run/php/kunde-a.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 10s
request_terminate_timeout = 60s
security.limit_extensions = .php
clear_env = yes
php_admin_value[open_basedir] = /var/www/kunde-a:/tmp
php_admin_flag[session.upload_progress.enabled] = off
php_admin_value[error_log] = /var/log/php/kunde-a.error.log
Prema priručniku vrijednosti postavljene putem php_value i php_flag mogu se tijekom rada mijenjati funkcijom ini_set(), a vrijednosti putem php_admin_value i php_admin_flag ne mogu. security.limit_extensions prema zadanim postavkama iznosi .php .phar i određuje koje nastavke datoteka FPM izvršava kao glavnu skriptu. clear_env = yes je zadano i prazni okolinu workera.
Za nadzor postoji stranica statusa putem pm.status_path i ping stranica putem ping.path. Obje bi trebale biti dostupne samo interno. Spore zahtjeve FPM bilježi s backtraceom ako su postavljeni request_slowlog_timeout i slowlog.
PHP priručnik upozorava: tko može otvoriti FastCGI vezu prema PHP-FPM-u, kontrolira konfiguraciju zahtjeva i time može izvršiti proizvoljan kod. PHP-FPM nikad ne smije biti dostupan iz nepouzdane mreže. Koristite Unix socket ili listen.allowed_clients.
Kakvu ulogu PHP-FPM ima kod PHP2Shella?
PHP-FPM spada među pogođene načine rada. Model procesa osobito je jasan kod CVE-2026-109619: unutarnje stanje koje pripada zahtjevu može ostati sačuvano nakon oslobađanja memorije, a kasniji zahtjev u istom workeru može ga iskoristiti prije nego što se vrati na početno stanje. To je moguće samo zato što workeri redom obrađuju mnogo zahtjeva.
Iz toga proizlaze tri obveze:
- Instalirati ažuriranje: PHP 8.5.12, 8.4.27, 8.3.36 ili 8.2.35 odnosno potvrđeni backport distribucije.
- Ponovno pokrenuti sve workere: Nove datoteke na disku ništa ne mijenjaju dok rade stari workeri. To vrijedi za svaku instaliranu FPM verziju i svaki pool. Naredbe su na stranici Ponovno pokretanje PHP-FPM-a i svih workera.
- Privremene vrijednosti postaviti zaključano: Mjere s php.net-a, na primjer
session.upload_progress.enabled=0, pripadaju u pool putemphp_admin_valueiliphp_admin_flag, a ne u.user.ini.
Razdvajanje u poolove ne zamjenjuje ažuriranje, ali ograničava štetu: ako svaka web-stranica radi pod vlastitim korisnikom, napadač nakon provale ne dolazi automatski do datoteka ostalih. Kako to konkretno izgleda, opisuje članak Izolacija PHP-FPM poolova po web-stranici; uključivanje u Nginx opisano je u članku Osiguravanje Nginxa s PHP-FPM-om.
Kako PHP SOS konkretno pomaže?
- Evidentirati poolove: Popisujemo sve FPM verzije, poolove, korisnike i socketove Vašeg poslužitelja.
- Zakrpati i ponovno pokrenuti: Ažuriramo PHP i putem vremena pokretanja dokazujemo da više ne radi nijedan stari worker.
- Razdvojiti poolove: U okviru ojačavanja poslužitelja postavljamo po web-stranici jedan pool s vlastitim korisnikom i zaključanim postavkama.
- Provjeriti dostupnost: Kontroliramo da FastCGI socketovi i stranice statusa nisu dostupni izvana.
Česta pitanja
Što znači FPM?
FPM znači FastCGI Process Manager. PHP priručnik opisuje ga kao primarnu FastCGI implementaciju PHP-a s funkcijama koje su korisne ponajprije za jako opterećene web-stranice. Uključen je s PHP-om 5.3.3.
Koja je razlika između poola i workera?
Pool je skupina worker procesa sa zajedničkom konfiguracijom: korisnik, socket, ograničenja i PHP postavke. Worker je pojedinačan proces koji redom obrađuje zahtjeve. Poslužitelj može imati mnogo poolova, na primjer po jedan za svaku web-stranicu.
Treba li PHP-FPM biti dostupan putem TCP-a ili Unix socketa?
Ako web-poslužitelj radi na istom hostu, PHP priručnik preporučuje Unix socket. Kod TCP-a mora se postaviti listen.allowed_clients jer se inače smije povezati svaka adresa. Otvoreno dostupan FastCGI port prema priručniku omogućuje proizvoljno izvršavanje koda.
Štiti li pm.max_requests od ranjivosti poput PHP2Shella?
Ne. pm.max_requests zamjenjuje worker nakon utvrđenog broja zahtjeva i pomaže ponajprije protiv curenja memorije u ekstenzijama. Protiv ranjivosti u interpreteru pomaže samo ažuriranje uz naknadno ponovno pokretanje svih workera.