Stručně: PHP-FPM (FastCGI Process Manager) provozuje PHP jako samostatnou službu vedle webového serveru. Hlavní proces (master) spravuje pooly a každý pool spouští workery, které zpracovávají požadavky přes FastCGI. Pooly lze provozovat pro každý web s vlastním uživatelem, vlastními limity a uzamčenými nastaveními PHP. Protože workery zpracovávají postupně mnoho požadavků, je nutné je po aktualizaci PHP všechny restartovat.
Co je PHP-FPM?
Příručka PHP popisuje FPM jako primární implementaci FastCGI v PHP s funkcemi, které jsou užitečné hlavně pro silně zatížené weby. FPM bylo převzato s PHP 5.3.3 jako samostatné SAPI, tedy samostatný provozní režim. Jeho název SAPI je fpm-fcgi.
Rozdíl oproti mod_php: PHP neběží ve webovém serveru, ale jako samostatná služba. Nginx, Apache nebo jiný webový server předává požadavky PHP protokolem FastCGI a dostává zpět hotovou odpověď. Webový server a PHP lze tak nezávisle na sobě restartovat, konfigurovat a zabezpečovat. Jak FastCGI v zásadě funguje, popisuje článek CGI a FastCGI.
Master, pooly a workery: procesní model
PHP-FPM se skládá ze tří úrovní:
- Hlavní proces (master): čte konfiguraci, otevírá sockety a spouští nebo ukončuje workery. Sám nespouští žádný kód aplikace.
- Pooly: Každý pool má název, vlastní socket nebo port, vlastního uživatele Unix a vlastní nastavení PHP. Příručka výslovně uvádí odlišné uid, gid, chroot, prostředí a php.ini pro každý pool.
- Workery: procesy poolu, které přijímají a provádějí požadavky. Worker zpracuje postupně mnoho požadavků, než je nahrazen.
Kolik workerů běží, určuje správce procesů direktivou pm:
| Režim | Chování | Důležité direktivy |
|---|---|---|
static |
pevný počet workerů | pm.max_children |
dynamic |
workery mezi dolní a horní mezí | pm.start_servers, pm.min_spare_servers, pm.max_spare_servers |
ondemand |
workery jen podle potřeby, po nečinnosti se ruší | pm.process_idle_timeout (výchozí 10s) |
pm.max_children omezuje ve všech režimech počet souběžných požadavků. pm.max_requests nahradí worker po pevném počtu požadavků; výchozí hodnota 0 znamená neomezeně.
Který režim se hodí, závisí na zátěži. static drží vždy stejný počet workerů připravených a hodí se pro rovnoměrně silně využívané aplikace s dostatkem paměti. dynamic je kompromis pro většinu webů. ondemand šetří paměť na serverech s mnoha malými weby, protože pooly bez návštěvníků nezabírají žádné workery; první požadavek po pauze ale trvá o něco déle. Příliš vysoké pm.max_children může server při špičkách přivést k nedostatku paměti, příliš nízké vede k čekacím dobám a chybovým hlášením webového serveru.
Pool s bezpečnými základními nastaveními
Příklad samostatného poolu pro každý web s direktivami z příručky PHP. Cesty a hodnoty jsou příklady:
; /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
Podle příručky lze hodnoty nastavené přes php_value a php_flag za běhu měnit pomocí ini_set(), hodnoty přes php_admin_value a php_admin_flag naopak ne. security.limit_extensions je standardně .php .phar a určuje, které přípony souborů FPM provede jako hlavní skript. clear_env = yes je výchozí hodnota a vyprázdní prostředí workerů.
Pro monitorování existuje stavová stránka přes pm.status_path a stránka ping přes ping.path. Obě by měly být dostupné jen interně. Pomalé požadavky FPM zaznamenává s backtrace, pokud jsou nastaveny request_slowlog_timeout a slowlog.
Příručka PHP varuje: Kdo může otevřít spojení FastCGI k PHP-FPM, ovládá konfiguraci požadavku a může tak provést libovolný kód. PHP-FPM nesmí být nikdy dostupné z nedůvěryhodné sítě. Použijte socket Unix nebo listen.allowed_clients.
Jakou roli hraje PHP-FPM u PHP2Shell?
PHP-FPM patří mezi postižené provozní režimy. Procesní model je obzvlášť zřetelný u CVE-2026-109619: vnitřní stav patřící k požadavku může po uvolnění paměti přetrvat a pozdější požadavek ve stejném workeru ho může využít dříve, než se vynuluje. To je možné jen proto, že workery zpracovávají mnoho požadavků za sebou.
Z toho plynou tři povinnosti:
- Nasadit aktualizaci: PHP 8.5.12, 8.4.27, 8.3.36 nebo 8.2.35, případně potvrzený backport distribuce.
- Restartovat všechny workery: Nové soubory na disku nic nemění, dokud běží staré workery. Platí to pro každou nainstalovanou verzi FPM a každý pool. Příkazy najdete v článku Restart PHP-FPM a všech workerů.
- Přechodné hodnoty nastavit jako uzamčené: Opatření z php.net, například
session.upload_progress.enabled=0, patří přesphp_admin_valuenebophp_admin_flagdo poolu, nikoli do.user.ini.
Oddělení do poolů aktualizaci nenahrazuje, ale omezuje škody: pokud každý web běží pod vlastním uživatelem, útočník po průniku automaticky nezíská soubory ostatních. Jak to konkrétně vypadá, popisuje článek Izolace poolů PHP-FPM pro každý web; začlenění do Nginx najdete v článku Zabezpečení Nginx s PHP-FPM.
Jak konkrétně pomáhá PHP SOS?
- Zmapovat pooly: Vypíšeme všechny verze FPM, pooly, uživatele a sockety vašeho serveru.
- Záplatovat a restartovat: Aktualizujeme PHP a podle časů spuštění doložíme, že už neběží žádný starý worker.
- Oddělit pooly: V rámci zpevnění serveru nastavíme pro každý web pool s vlastním uživatelem a uzamčenými nastaveními.
- Zkontrolovat dostupnost: Ověříme, že sockety FastCGI a stavové stránky nejsou dostupné zvenčí.
Časté dotazy
Co znamená FPM?
FPM znamená FastCGI Process Manager. Příručka PHP jej popisuje jako primární implementaci FastCGI v PHP s funkcemi, které jsou užitečné hlavně pro silně zatížené weby. Převzat byl s PHP 5.3.3.
Jaký je rozdíl mezi poolem a workerem?
Pool je skupina procesů workerů se společnou konfigurací: uživatel, socket, limity a nastavení PHP. Worker je jednotlivý proces, který postupně zpracovává požadavky. Server může mít mnoho poolů, například jeden pro každý web.
Má být PHP-FPM dostupné přes TCP, nebo přes socket Unix?
Pokud webový server běží na stejném hostiteli, příručka PHP doporučuje socket Unix. U TCP je nutné nastavit listen.allowed_clients, protože jinak se smí připojit kterákoli adresa. Volně dostupný port FastCGI umožňuje podle příručky libovolné provedení kódu.
Chrání pm.max_requests před zranitelnostmi jako PHP2Shell?
Ne. pm.max_requests nahradí worker po pevném počtu požadavků a pomáhá hlavně proti únikům paměti v rozšířeních. Proti zranitelnosti v interpretu pomůže jen aktualizace s následným restartem všech workerů.