# Izolace poolů PHP-FPM pro každý web

> Izolace poolů PHP-FPM pro každý web: kontrola stávajících poolů, ochrana socketů, omezení přípon, skrytí stavových stránek a limity pro každý pool.

Zdroj: https://phpsos.de/cs/blog/php-fpm-pools-isolieren/  
Stav: 25.10.2026  
Poskytovatel: PHP SOS, Nouzová pomoc pro PHP a bezpečnost serverů. Okamžitá pomoc přes WhatsApp: https://wa.me/491736494914?text=Dobr%C3%BD%20den%2C%20PHP%20SOS%2C%20pot%C5%99ebujeme%20pomoc%20s%20na%C5%A1%C3%ADm%20PHP%20serverem.%20Firma%3A%20%E2%80%A6%20Web%3A%20%E2%80%A6

**Stručně:** Každý web na serveru by měl mít vlastní pool PHP-FPM s vlastním systémovým uživatelem a vlastním socketem. Oddělení se však stane účinným až s detaily: oprávnění k socketu jen pro webový server, `security.limit_extensions` na `.php`, žádné veřejně dostupné stavové stránky, vlastní limity pro procesy a dobu běhu a oddělené logy. Před samotným PHP2Shell chrání jen aktualizace; pooly omezují, jak daleko útok sáhne.

## Jeden server, mnoho webů, společné riziko

Na mnoha serverech se za léta nashromáždilo to, co nikdo takto neplánoval. Firemní web, e-shop, kampaňová stránka z roku 2019 a testovací systém běží vedle sebe, často pod stejným uživatelem a ve stejném poolu. Pokud je napadena zapomenutá kampaňová stránka, jsou odkryta i data zákazníků e-shopu.

PHP-FPM, správce procesů FastCGI pro PHP, to řeší pooly: skupinami procesů worker s vlastním nastavením. Jak základní princip funguje, vysvětluje stránka [PHP-FPM vysvětleno: správce procesů, pooly a workeři](https://phpsos.de/cs/php/php-fpm-erklaert/). Sestavení oddělených poolů s vlastním uživatelem, vlastní dočasnou složkou a `open_basedir` popisuje průvodce [open_basedir a izolace pro každý web](https://phpsos.de/cs/ratgeber/open-basedir/). Tento článek jde o krok dál: Jak zkontrolovat stávající pooly a která nastavení činí oddělení odolným?

Důležité zařazení: u PHP2Shell leží zranitelnosti CVE-2026-109618 a CVE-2026-109619 v interpretu PHP, který sdílejí všechny pooly dané verze PHP. Vlastní pool zneužití nezabrání. Rozhodne ale o tom, zda útočník poté dosáhne jednoho webu, nebo všech.

## Pooly PHP-FPM s vlastním uživatelem: zkontrolujte stav

Než cokoli změníte, udělejte si přehled. Následující příkazy jen čtou. Cesty a čísla verzí se podle distribuce liší:

```bash
# Všechny pooly s uživatelem a socketem
grep -HE '^\s*(\[|user|group|listen)\s*' /etc/php/*/fpm/pool.d/*.conf

# Běžící pooly a jejich uživatelé
ps -eo user,pid,cmd | grep '[p]hp-fpm: pool'

# Sockety a jejich oprávnění
ls -l /run/php/

# Zkontrolovat konfiguraci na chyby (nic nemění)
sudo php-fpm8.3 -t
```

Všímejte si tří vzorců: několik webů ve stejném poolu, pooly běžící jako `www-data` nebo dokonce jako `root` a sockety zapisovatelné pro všechny uživatele. Každý z nich oddělení podkopává.

Pokud na serveru běží několik verzí PHP, má každá vlastní službu FPM s vlastními adresáři poolů. Zkontrolujte všechny, nejen verzi, kterou jste nastavovali naposledy. Právě staré verze se zapomenutými pooly jsou riziko, protože se často neudržují ani po aktualizacích nerestartují. Upozornění najdete v článku [Více verzí PHP na jednom serveru](https://phpsos.de/cs/blog/mehrere-php-versionen-server/). Výsledek zaznamenejte do malé tabulky: web, pool, uživatel, socket, verze PHP. Tento přehled je zároveň základem každé pozdější změny.

## Nejdůležitější nastavení pro každý pool

Následující přehled vychází z konfigurace FPM v příručce PHP. Hodnoty pro procesy a časy se řídí vaší zátěží a aplikací:

| Nastavení | Účel | Doporučení |
|---|---|---|
| `user`, `group` | uživatel workerů | vlastní uživatel pro každý web, nikdy `root` |
| `listen.owner`, `listen.group`, `listen.mode` | oprávnění k socketu | jen skupina webového serveru, režim `0660` |
| `listen.acl_users` | přístup přes ACL místo vlastníka | zapsat jen uživatele webového serveru |
| `security.limit_extensions` | spustitelné přípony | omezit na `.php` (výchozí `.php .phar`) |
| `clear_env` | vyprázdnění proměnných prostředí | ponechat na výchozím `yes` |
| `pm.max_children` | nejvyšší počet workerů | omezit tak, aby jeden web nezatížil server |
| `request_terminate_timeout` | ukončení zaseknutých požadavků | nastavit podle nejdelšího legitimního požadavku |
| `pm.status_path`, `ping.path` | stavová a ping stránka | nastavit jen v případě potřeby a zabezpečit interně |
| `slowlog`, `request_slowlog_timeout` | protokol pomalých požadavků | pro každý pool do vlastního souboru |

Výňatek pro zpevněný pool vypadá takto:

```ini
; /etc/php/8.3/fpm/pool.d/shop.conf (výňatek)
[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
```

Nastavení jako `memory_limit` nebo `session.upload_progress.enabled` zadáváte pro každý pool pomocí `php_admin_value` a `php_admin_flag`. Podle příručky nelze tyto hodnoty přepsat pomocí `ini_set()`. Více v článku [php_admin_value: uzamknutí nastavení proti přepsání](https://phpsos.de/cs/blog/php-admin-value-sperren/).

## Správně zařadit stavové stránky a obměnu workerů

`pm.status_path` a `ping.path` jsou aktivní jen tehdy, když jsou nastaveny. Stavová stránka ukazuje běžící požadavky, procesy a vytížení. Pro monitoring je to užitečné, veřejně dostupná je však zbytečným zdrojem informací pro útočníky. Tyto cesty ve webovém serveru předávejte jen interním adresám. Jak bezpečně spolupracují Nginx a PHP-FPM, popisuje [Zabezpečení Nginx s PHP-FPM](https://phpsos.de/cs/server/nginx-php-fpm/).

`pm.max_requests` určuje, po kolika požadavcích se worker restartuje; výchozí hodnota je `0`, tedy nikdy. Hodnota větší než nula pomáhá proti pomalu rostoucí spotřebě paměti. Jako ochrana proti PHP2Shell není určena: php.net ji mezi přechodnými opatřeními neuvádí a zdůrazňuje, že plně chrání jen aktualizace. Po aktualizaci navíc platí: všichni workeři všech poolů se musí restartovat, protože staré procesy by jinak běžely dál se zranitelným kódem.

> **Tip:**
> Udržujte šablonu pro nové pooly a každý nový web zakládejte podle ní. Oddělení pak vzniká automaticky, místo aby se po létech dodatečně dopracovávalo.

## Typické chyby při přechodu

Nejčastější chybou je nový pool, který sice běží pod vlastním uživatelem, ale jeho soubory dál patří `www-data`. Pool pak nesmí zapisovat tam, kde musí, a někdo nastaví oprávnění příliš velkoryse. Předem vyjasněte, které složky musí být zapisovatelné. Druhou chybou jsou plánované úlohy, které dál běží pod starým uživatelem a vytvářejí soubory se špatným vlastníkem. Třetí je společná složka session pro všechny pooly, která oddělení opět ruší.

Po každém přechodu otestujte přihlášení, nahrávání, cache a plánované úlohy webu a sledujte chybový log poolu.

## Jak konkrétně pomáhá PHP SOS?

- Zmapujeme všechny pooly, uživatele, sockety a nastavení a ukážeme, kde si weby dnes sdílejí procesy nebo oprávnění.
- Pro každý web nastavíme zpevněný pool s oprávněními k socketu, omezením přípon, limity zdrojů a vlastními logy.
- Zabezpečíme stavové stránky, kontrolovaně restartujeme všechny workery a otestujeme každý web.
- V rámci [zpevnění serveru](https://phpsos.de/cs/leistungen/server-haertung/) oddělení zdokumentujeme jako šablonu pro budoucí projekty.


## Časté dotazy

**Proč by měl mít každý web vlastní pool PHP-FPM?**  
Vlastní pool s vlastním systémovým uživatelem odděluje weby na úrovni procesů a oprávnění k souborům. Když je jeden web napaden, kód nemůže bez dalšího číst soubory ostatních. Navíc lze limity a nastavení určit pro každý web zvlášť.

**Chrání vlastní pool před PHP2Shell?**  
Ne. Zranitelnosti jsou v samotném interpretu PHP, který sdílejí všechny pooly. Ochranu poskytuje jen aktualizace na opravenou verzi s restartem všech workerů. Oddělené pooly ale omezují, jak daleko úspěšný útok sáhne.

**Co způsobuje security.limit_extensions?**  
Podle příručky PHP nastavení omezuje, které přípony souborů PHP-FPM spouští jako hlavní skript. Výchozí jsou .php a .phar. Kdo je omezí na .php, zabrání tomu, aby se například nahrané obrazové soubory spouštěly jako PHP, pokud je webový server nesprávně nakonfigurován.

**Je stavová stránka PHP-FPM nebezpečná?**  
Prozrazuje podrobnosti o běžících procesech a požadavcích. Pokud je veřejně dostupná bez ochrany, usnadňuje útočníkům orientaci. Podle příručky je aktivní jen tehdy, když je nastaveno pm.status_path. Webový server by pak měl cestu omezit na interní adresy.

## Zdroje

- [Příručka PHP: konfigurace FPM](https://www.php.net/manual/en/install.fpm.configuration.php)
- [Dokumentace Nginx](https://nginx.org/en/docs/)
- [BSI IT-Grundschutz](https://www.bsi.bund.de/DE/Themen/Unternehmen-und-Organisationen/Standards-und-Zertifizierung/IT-Grundschutz/it-grundschutz_node.html)
