Aktuálna situácia: PHP2Shell. Dve kritické zraniteľnosti PHP (CVSS 9.2) umožňujú spustenie škodlivého kódu bez prihlásenia. Záplaty od 21. 10. 2026.Čo treba urobiť teraz →

Izolácia poolov PHP-FPM pre každý web

Vlastný pool pre každý web je začiatok, nie koniec. Takto skontrolujete existujúce pooly a sprísnite sockety, prípony, stavové stránky, zdroje a protokoly.

Stav 5 min čítaniaHardening a konfigurácia

Stručne: Každý web na serveri by mal mať vlastný pool PHP-FPM s vlastným systémovým používateľom a vlastným socketom. Oddelenie je však účinné až s podrobnosťami: práva k socketu len pre webový server, security.limit_extensions na .php, žiadne verejne dostupné stavové stránky, vlastné limity pre procesy a dobu behu a oddelené protokoly. Pred samotným PHP2Shell chráni iba aktualizácia; pooly obmedzujú, ako ďaleko siahne útok.

Jeden server, veľa webov, spoločné riziko

Na mnohých serveroch sa za roky nahromadilo to, čo nikto takto neplánoval. Firemný web, e-shop, kampaňová stránka z roku 2019 a testovací systém bežia vedľa seba, často pod tým istým používateľom a v tom istom poole. Ak sa kompromituje zabudnutá kampaňová stránka, sú otvorené aj údaje zákazníkov e-shopu.

PHP-FPM, FastCGI správca procesov PHP, to rieši pomocou poolov: skupín procesov workerov s vlastnými nastaveniami. Ako základný princíp funguje, vysvetľuje PHP-FPM vysvetlený: správca procesov, pooly a workeri. Zostavenie oddelených poolov s vlastným používateľom, vlastným dočasným priečinkom a open_basedir opisuje sprievodca open_basedir a izolácia pre každý web. Tento príspevok ide o krok ďalej: ako skontrolujete existujúce pooly a ktoré nastavenia robia oddelenie spoľahlivým?

Dôležité pre zaradenie: pri PHP2Shell sú zraniteľnosti CVE-2026-109618 a CVE-2026-109619 v interpreteri PHP, ktorý zdieľajú všetky pooly jednej verzie PHP. Vlastný pool zneužitiu nezabráni. Rozhoduje však o tom, či útočník potom dosiahne jeden web, alebo všetky.

Pooly PHP-FPM s vlastným používateľom: kontrola stavu

Skôr než niečo zmeníte, urobte si prehľad. Nasledujúce príkazy len čítajú. Cesty a čísla verzií sa podľa distribúcie líšia:

# Všetky pooly s používateľom a socketom
grep -HE '^\s*(\[|user|group|listen)\s*' /etc/php/*/fpm/pool.d/*.conf

# Bežiace pooly a ich používatelia
ps -eo user,pid,cmd | grep '[p]hp-fpm: pool'

# Sockety a ich práva
ls -l /run/php/

# Skontrolovať konfiguráciu na chyby (nič nemení)
sudo php-fpm8.3 -t

Všímajte si tri vzory: viacero webov v tom istom poole, pooly, ktoré bežia ako www-data alebo dokonca ako root, a sockety, do ktorých smú zapisovať všetci používatelia. Každý z nich oslabuje oddelenie.

Ak na serveri beží viacero verzií PHP, každá má vlastnú službu FPM s vlastnými adresármi poolov. Skontrolujte všetky, nielen verziu, ktorú ste nastavovali naposledy. Práve staré verzie so zabudnutými poolmi sú riziko, pretože sa často neudržiavajú ani po aktualizáciách nereštartujú. Pokyny nájdete v článku Viacero verzií PHP na jednom serveri. Výsledok zapíšte do malej tabuľky: web, pool, používateľ, socket, verzia PHP. Tento prehľad je zároveň základom pre každú neskoršiu zmenu.

Najdôležitejšie nastavenia pre každý pool

Nasledujúci prehľad vychádza z konfigurácie FPM v príručke PHP. Hodnoty pre procesy a časy sa riadia vaším zaťažením a aplikáciou:

Nastavenie Účel Odporúčanie
user, group používateľ workerov vlastný používateľ pre každý web, nikdy root
listen.owner, listen.group, listen.mode práva k socketu len skupina webového servera, režim 0660
listen.acl_users prístup cez ACL namiesto vlastníka zapísať len používateľa webového servera
security.limit_extensions vykonateľné prípony obmedziť na .php (štandardne .php .phar)
clear_env vyprázdnenie premenných prostredia nechať na štandardnom yes
pm.max_children maximálny počet workerov obmedziť tak, aby jeden web server nevyťažil
request_terminate_timeout zrušenie visiacich požiadaviek nastaviť podľa najdlhšej legitímnej požiadavky
pm.status_path, ping.path stavová a ping stránka nastaviť len ak je potrebné a zabezpečiť interne
slowlog, request_slowlog_timeout protokol pomalých požiadaviek pre každý pool do vlastného súboru

Výňatok pre sprísnený pool vyzerá takto:

; /etc/php/8.3/fpm/pool.d/shop.conf (výňatok)
[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

Nastavenia ako memory_limit alebo session.upload_progress.enabled určujete pre každý pool pomocou php_admin_value a php_admin_flag. Podľa príručky sa tieto hodnoty nedajú prepísať cez ini_set(). Viac v článku php_admin_value: zablokovanie nastavení proti prepísaniu.

Stavové stránky a výmena workerov správne zaradiť

pm.status_path a ping.path sú aktívne len vtedy, ak sú nastavené. Stavová stránka ukazuje bežiace požiadavky, procesy a vyťaženie. Pre monitoring je to užitočné, verejne dostupná je však zbytočným zdrojom informácií pre útočníkov. Tieto cesty presmerúvajte vo webovom serveri len pre interné adresy. Ako Nginx a PHP-FPM bezpečne spolupracujú, opisuje Zabezpečenie Nginx s PHP-FPM.

pm.max_requests určuje, po koľkých požiadavkách sa worker znova spustí; štandard je 0, teda nikdy. Hodnota väčšia ako nula pomáha proti pomaly rastúcej spotrebe pamäte. Ako ochrana pred PHP2Shell nie je určená: php.net ju neuvádza medzi prechodnými opatreniami a zdôrazňuje, že úplne chráni len aktualizácia. Po aktualizácii navyše platí: všetci workeri všetkých poolov sa musia reštartovať, pretože staré procesy inak bežia ďalej so zraniteľným kódom.

Tip

Udržiavajte šablónu pre nové pooly a každý nový web vytvárajte s ňou. Oddelenie tak vznikne automaticky, namiesto toho, aby sa dodatočne dobiehalo o roky neskôr.

Typické chyby pri prechode

Najčastejšou chybou je nový pool, ktorý síce beží pod vlastným používateľom, ale jeho súbory naďalej patria www-data. Potom pool nesmie zapisovať tam, kde musí, a niekto nastaví práva príliš voľne. Vopred si ujasnite, ktoré priečinky musia byť zapisovateľné. Druhou chybou sú plánované úlohy, ktoré bežia ďalej pod starým používateľom a vytvárajú súbory so zlým vlastníkom. Treťou je spoločný priečinok relácií pre všetky pooly, ktorý oddelenie opäť ruší.

Po každom prechode otestujte prihlásenie, uploady, cache a plánované úlohy webu a sledujte chybový protokol poolu.

Ako konkrétne pomáha PHP SOS?

  • Zachytíme všetky pooly, používateľov, sockety a nastavenia a ukážeme, kde si weby dnes zdieľajú procesy alebo práva.
  • Pre každý web vytvoríme sprísnený pool s právami k socketu, hranicou prípon, limitmi zdrojov a vlastnými protokolmi.
  • Zabezpečíme stavové stránky, riadene reštartujeme všetkých workerov a otestujeme každý web.
  • V rámci sprísnenia servera zdokumentujeme oddelenie ako šablónu pre budúce projekty.

Časté otázky

Prečo by mal mať každý web vlastný pool PHP-FPM?

Vlastný pool s vlastným systémovým používateľom oddeľuje weby na úrovni procesov a práv k súborom. Ak sa jeden web kompromituje, kód nemôže bez ďalšieho čítať súbory ostatných. Okrem toho sa dajú limity a nastavenia určiť pre každý web osobitne.

Chráni vlastný pool pred PHP2Shell?

Nie. Zraniteľnosti sú v samotnom interpreteri PHP, ktorý spoločne používajú všetky pooly. Ochranu poskytuje len aktualizácia na opravenú verziu s reštartom všetkých workerov. Oddelené pooly však obmedzujú, ako ďaleko siahne úspešný útok.

Čo spôsobuje security.limit_extensions?

Podľa príručky PHP nastavenie obmedzuje, ktoré prípony súborov PHP-FPM vykoná ako hlavný skript. Štandardne je to .php a .phar. Kto ich obmedzí na .php, zabráni tomu, aby sa napríklad nahrané obrazové súbory vykonávali ako PHP, ak je webový server nesprávne nakonfigurovaný.

Je stavová stránka PHP-FPM nebezpečná?

Prezrádza podrobnosti o bežiacich procesoch a požiadavkách. Ak je bez ochrany verejne dostupná, uľahčuje útočníkom orientáciu. Podľa príručky je aktívna len vtedy, ak je nastavené pm.status_path. Potom by mal webový server obmedziť cestu na interné adresy.

Zdroje

Okamžitý kontakt

Každá hodina sa počíta. Napíšte nám hneď.

Stručne opíšte systém, verziu PHP a svoje pozorovanie. Ozveme sa, vyjasníme situáciu a budeme pracovať na diaľku, kým nebude incident uzavretý a zdokumentovaný.

Okamžitá pomoc