Trenutno stanje: PHP2Shell. Dve kritični ranljivosti PHP (CVSS 9,2) omogočata izvedbo škodljive kode brez prijave. Popravki od 21. 10. 2026.Kaj je zdaj treba storiti →

Izolacija poolov PHP-FPM po spletnih straneh

Lasten pool za vsako spletno stran je začetek, ne konec. Tako preverite obstoječe poole in utrdite sockete, končnice, statusne strani, vire in dnevnike.

Stanje 5 min branjaUtrjevanje in konfiguracija

Na kratko: Vsaka spletna stran na strežniku naj ima lasten pool PHP-FPM z lastnim sistemskim uporabnikom in lastnim socketom. Ločitev postane učinkovita šele s podrobnostmi: pravice socketa samo za spletni strežnik, security.limit_extensions na .php, brez javno dosegljivih statusnih strani, lastne meje za procese in čas izvajanja ter ločeni dnevniki. Pred samim PHP2Shell varuje samo posodobitev; pooli omejijo, kako daleč seže napad.

En strežnik, veliko spletnih strani, skupno tveganje

Na številnih strežnikih je skozi leta zraslo, česar nihče ni tako načrtoval. Podjetniška spletna stran, trgovina, kampanjska stran iz leta 2019 in testni sistem tečejo drug ob drugem, pogosto pod istim uporabnikom in v istem poolu. Če je pozabljena kampanjska stran ogrožena, so odprti tudi podatki strank trgovine.

PHP-FPM, upravljalnik procesov FastCGI za PHP, to rešuje s pooli: skupinami procesov delavcev z lastnimi nastavitvami. Kako deluje osnovno načelo, pojasnjuje PHP-FPM razloženo: upravljalnik procesov, pooli in delavci. Zgradbo ločenih poolov z lastnim uporabnikom, lastno začasno mapo in open_basedir opisuje vodnik open_basedir in izolacija po spletnih straneh. Ta prispevek gre korak dlje: kako preverite obstoječe poole in katere nastavitve naredijo ločitev vzdržljivo?

Pomembna umestitev: pri PHP2Shell ranljivosti CVE-2026-109618 in CVE-2026-109619 ležita v interpreterju PHP, ki si ga delijo vsi pooli ene različice PHP. Lasten pool izkoriščanja ne prepreči. Odloča pa, ali napadalec potem doseže eno spletno stran ali vse.

Pooli PHP-FPM z lastnim uporabnikom: preverite stanje

Preden karkoli spremenite, si ustvarite pregled. Naslednji ukazi samo berejo. Poti in številke različic se po distribuciji razlikujejo:

# Vsi pooli z uporabnikom in socketom
grep -HE '^\s*(\[|user|group|listen)\s*' /etc/php/*/fpm/pool.d/*.conf

# Tekoči pooli in njihovi uporabniki
ps -eo user,pid,cmd | grep '[p]hp-fpm: pool'

# Socketi in njihove pravice
ls -l /run/php/

# Preverite konfiguracijo za napake (ničesar ne spremeni)
sudo php-fpm8.3 -t

Bodite pozorni na tri vzorce: več spletnih strani v istem poolu, poole, ki tečejo kot www-data ali celo kot root, in socketi, v katere lahko piše vsak uporabnik. Vsak od njih spodkopava ločitev.

Če na strežniku teče več različic PHP, ima vsaka lastno storitev FPM z lastnimi imeniki poolov. Preverite vse, ne samo različice, ki ste jo nazadnje nastavili. Prav stare različice s pozabljenimi pooli so tveganje, ker se pogosto ne vzdržujejo in se po posodobitvah ne zaženejo znova. Namigi so pod Več različic PHP na enem strežniku. Rezultat zabeležite v majhno tabelo: spletna stran, pool, uporabnik, socket, različica PHP. Ta pregled je hkrati podlaga za vsako poznejšo spremembo.

Najpomembnejše nastavitve za vsak pool

Naslednji pregled temelji na konfiguraciji FPM v priročniku PHP. Vrednosti za procese in čase se ravnajo po vaši obremenitvi in aplikaciji:

Nastavitev Namen Priporočilo
user, group uporabnik delavcev lasten uporabnik za vsako spletno stran, nikoli root
listen.owner, listen.group, listen.mode pravice na socketu samo skupina spletnega strežnika, način 0660
listen.acl_users dostop prek ACL namesto lastnika vnesite samo uporabnika spletnega strežnika
security.limit_extensions izvršljive končnice omejite na .php (privzeto .php .phar)
clear_env praznjenje okoljskih spremenljivk pustite na privzetem yes
pm.max_children največje število delavcev omejite tako, da ena spletna stran ne obremeni strežnika
request_terminate_timeout prekinitev obtičanih zahtev nastavite glede na najdaljšo legitimno zahtevo
pm.status_path, ping.path statusna stran in stran ping nastavite samo, če je potrebno, in zaščitite notranje
slowlog, request_slowlog_timeout zapisnik počasnih zahtev za vsak pool v svojo datoteko

Izsek za utrjen pool je videti takole:

; /etc/php/8.3/fpm/pool.d/shop.conf (izsek)
[shop]
user = shop
group = shop
listen = /run/php/shop.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
request_terminate_timeout = 60s

security.limit_extensions = .php
clear_env = yes

slowlog = /var/log/php/shop.slow.log
request_slowlog_timeout = 10s
php_admin_value[error_log] = /var/log/php/shop.error.log

Nastavitve, kot sta memory_limit ali session.upload_progress.enabled, določite za vsak pool z php_admin_value in php_admin_flag. Po priročniku teh vrednosti ni mogoče prepisati z ini_set(). Več o tem pod php_admin_value: zaklepanje nastavitev pred prepisovanjem.

Pravilna umestitev statusnih strani in menjave delavcev

pm.status_path in ping.path sta aktivna samo, če sta nastavljena. Statusna stran prikazuje tekoče zahteve, procese in obremenitev. Za spremljanje je to koristno, javno dosegljiva pa je nepotreben vir informacij za napadalce. Te poti v spletnem strežniku posredujte samo za notranje naslove. Kako Nginx in PHP-FPM varno sodelujeta, opisuje Zavarovanje Nginx s PHP-FPM.

pm.max_requests določa, po koliko zahtevah se delavec znova zažene; privzeto je 0, torej nikoli. Vrednost nad nič pomaga proti počasi naraščajoči porabi pomnilnika. Kot zaščita pred PHP2Shell ni mišljena: php.net je ne navaja med prehodnimi ukrepi in poudarja, da popolno zaščito daje samo posodobitev. Po posodobitvi velja tudi: vse delavce vseh poolov je treba znova zagnati, ker sicer stari procesi tečejo naprej z ranljivo kodo.

Nasvet

Vzdržujte predlogo za nove poole in z njo ustvarite vsako novo spletno stran. Tako ločitev nastane samodejno, namesto da bi jo čez leta dodatno vgrajevali.

Tipične napake pri prehodu

Najpogostejša napaka je nov pool, ki sicer teče pod lastnim uporabnikom, a njegove datoteke še vedno pripadajo www-data. Takrat pool ne sme pisati tam, kjer mora, nekdo pa pravice nastavi preveč radodarno. Vnaprej razjasnite, katere mape morajo biti zapisljive. Druga napaka so načrtovana opravila, ki tečejo naprej pod starim uporabnikom in ustvarjajo datoteke z napačnim lastnikom. Tretja je skupna mapa sej za vse poole, ki ločitev spet odpravi.

Po vsakem prehodu preizkusite prijavo, nalaganja, predpomnilnike in načrtovana opravila spletne strani ter spremljajte dnevnik napak poola.

Kako PHP SOS pomaga konkretno?

  • Zajamemo vse poole, uporabnike, sockete in nastavitve ter pokažemo, kje si spletne strani danes delijo procese ali pravice.
  • Za vsako spletno stran vzpostavimo utrjen pool, s pravicami socketa, mejo končnic, mejami virov in lastnimi dnevniki.
  • Statusne strani zavarujemo, vse delavce nadzorovano znova zaženemo in preizkusimo vsako spletno stran.
  • V okviru utrjevanja strežnikov ločitev dokumentiramo kot predlogo za prihodnje projekte.

Pogosta vprašanja

Zakaj naj ima vsaka spletna stran lasten pool PHP-FPM?

Lasten pool z lastnim sistemskim uporabnikom spletne strani loči na ravni procesov in pravic do datotek. Če je ena spletna stran ogrožena, koda datotek drugih ne more kar brati. Poleg tega je mogoče meje in nastavitve določiti ločeno za vsako spletno stran.

Ali lasten pool ščiti pred PHP2Shell?

Ne. Ranljivosti so v samem interpreterju PHP, ki ga vsi pooli uporabljajo skupaj. Zaščita je samo posodobitev na popravljeno različico s ponovnim zagonom vseh delavcev. Ločeni pooli pa omejijo, kako daleč seže uspešen napad.

Kaj povzroči security.limit_extensions?

Po priročniku PHP nastavitev omejuje, katere končnice datotek PHP-FPM izvede kot glavni skript. Privzeto sta .php in .phar. Kdor jo omeji na .php, prepreči, da bi se na primer naložene slikovne datoteke izvedle kot PHP, če je spletni strežnik napačno konfiguriran.

Ali je statusna stran PHP-FPM nevarna?

Razkriva podrobnosti o tekočih procesih in zahtevah. Če je javno dosegljiva brez zaščite, napadalcem olajša orientacijo. Po priročniku je aktivna samo, če je nastavljen pm.status_path. Takrat naj spletni strežnik pot omeji na notranje naslove.

Viri

Takojšnji stik

Vsaka ura šteje. Pišite nam zdaj.

Na kratko opišite sistem, različico PHP in opažanje. Odzovemo se, razjasnimo stanje in delamo na daljavo, dokler incident ni zaključen in dokumentiran.

Takojšnja pomoč