Stručně: Administrátorům bez vývojářského zázemí stačí pět základů k bezpečnému provozu PHP: PHP se skládá z několika programů (příkazová řádka, PHP-FPM, modul Apache), každý s vlastní verzí; nastavení působí v úrovních od php.ini až po aplikaci; PHP-FPM rozděluje požadavky mezi workery v poolech; aktualizace se projeví až po restartu všech procesů; a logy jsou nejdůležitějším vodítkem, když něco nesedí. Kdo tyto body zná, může zranitelnosti jako PHP2Shell uzavřít rychle a prokazatelně.
Z čeho se PHP na serveru skládá
PHP není jediný program. Na typickém serveru s Linuxem se najde několik variant, z nichž každá je připojena přes serverové rozhraní (SAPI):
| Varianta | Typický název | K čemu |
|---|---|---|
| Příkazová řádka (CLI) | php, php8.3 |
cron úlohy, Composer, údržbové skripty |
| PHP-FPM | php-fpm, php-fpm8.3 |
webové požadavky za Nginx nebo Apache |
| Modul Apache | mod_php, libphp |
webové požadavky přímo v procesu Apache |
| CGI | php-cgi |
starší sestavení |
Každá varianta může mít jinou verzi a jinou php.ini. Na mnoha serverech navíc paralelně běží několik verzí PHP, například 8.2 a 8.4. U aktualizace je třeba posuzovat každou zvlášť. Jak rozhraní fungují, vysvětluje PHP-FPM vysvětleno.
Kterou variantu vaše weby skutečně obsluhuje, zjistíte z běžících procesů a konfigurace webového serveru:
ps -eo pid,user,lstart,cmd | grep -E "php|httpd|apache2" | grep -v grep
apachectl -M 2>/dev/null | grep -i php # načítá Apache modul PHP?
ls /run/php/ 2>/dev/null # sockety FPM, často na verzi a pool
Sloupec s časem startu je později při restartu důležitý: všechny procesy PHP musely být spuštěny po okamžiku aktualizace. Pokud procesy běží pod různými uživateli, ukazuje to na oddělené pooly, což je dobře. Pokud se v Apache objeví modul PHP, ačkoli mají všechny weby běžet přes FPM, je to znamení starého nánosu, který je třeba odstranit. U hostingových rozhraní jako Plesk nebo cPanel platí stejný princip, jen rozhraní zobrazuje verze a handlery pro každý web; rozhodující ale zůstává to, co skutečně běží jako proces.
Nejdůležitější příkazy pro administrátory
php -v # verze příkazové řádky
php --ini # načtená php.ini a dodatečně čtené adresáře
php --ini=diff # od PHP 8.5: odchylky od výchozích hodnot
php -m # zkompilované a načtené moduly
php --ri session # nastavení rozšíření
php -l datei.php # kontrola syntaxe bez spuštění
php-fpm8.3 -v # verze binárky FPM (název podle distribuce)
php-fpm8.3 -t # otestovat konfiguraci FPM bez restartu
systemctl status php8.3-fpm
Dvě poznámky z příručky: php -l najde syntaktické chyby, ale ne chyby, které nastanou až při spuštění. A php -i volá phpinfo(); výstup nepatří do veřejných souborů ve webovém adresáři.
Jak působí nastavení PHP
Nastavení lze určit na několika místech. Kdo kde co smí měnit, upravuje režim změny každé direktivy:
- php.ini a conf.d: základní konfigurace pro každou variantu, čtená při startu.
- Pool FPM:
php_valueaphp_admin_valuepro každý pool. Hodnoty nastavené pomocíphp_admin_valueaplikace podle příručky nemůže přepsat pomocíini_set(). - Úroveň adresáře:
.user.iniu FPM nebo.htaccessu mod_php, jen pro direktivy v režimuINI_PERDIRneboINI_ALL. - Aplikace:
ini_set()za běhu, jen pro direktivy v režimuINI_ALL.
Příklad: memory_limit má režim INI_ALL, takže ho může aplikace změnit. post_max_size má INI_PERDIR a pomocí ini_set() ho změnit nelze. Proto php.net u přechodných opatření PHP2Shell vyžaduje nastavit hodnoty tak, aby je aplikace nemohly přepsat. Podrobnosti o úrovních vysvětluje článek Vysvětlení php.ini.
Pooly PHP-FPM ve stručnosti
Pool je skupina workerů s vlastním uživatelem, vlastním socketem a vlastním nastavením. Nejdůležitější direktivy podle příručky:
[shop]
user = shop
group = shop
listen = /run/php/shop.sock
pm = dynamic ; static, dynamic nebo ondemand
pm.max_children = 20 ; nejvýše 20 současných požadavků
pm.max_requests = 500 ; obnovit worker po 500 požadavcích
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/shop-slow.log
php_admin_value[error_log] = /var/log/php-fpm/shop-error.log
php_admin_flag[log_errors] = on
Vlastní pool pro každý web s vlastním uživatelem odděluje weby od sebe. security.limit_extensions je standardně nastaveno na .php .phar a brání tomu, aby FPM spouštělo jiné přípony souborů než PHP. clear_env je standardně zapnuto a drží proměnné prostředí mimo workera.
Logy: kam se administrátoři dívají
PHP zapisuje chyby do cíle určeného pomocí error_log, PHP-FPM navíc do vlastního logu a u pomalých požadavků do slowlogu s backtrace. K tomu přistupují přístupové a chybové logy webového serveru. Dbejte na to, aby bylo display_errors v produkci vypnuto a log_errors zapnuto: chyby patří do logu, ne na webovou stránku. Logy by se navíc měly rotovat a uchovávat po stanovenou dobu, aby v ostrém případě ještě existovaly. Po PHP2Shell odborný tisk doporučuje uchovávat logy serveru od 20. 10. 2026. Silným varovným signálem je proces PHP-FPM nebo webového serveru, který spouští shell; jak to rozpoznat, najdete v článku Varovný signál: webový server spouští shell.
Kontrolní seznam pro administrátory po PHP2Shell
- Vypsat všechny varianty a verze PHP na serveru, i ty nepoužívané.
- Zkontrolovat stav balíčků; u backportů distribuce prohledat changelog na CVE-2026-109618 a CVE-2026-109619.
- Aktualizovat na 8.5.12, 8.4.27, 8.3.36 nebo 8.2.35, resp. potvrzený backport.
- Restartovat PHP-FPM, Apache a LiteSpeed a zkontrolovat časy startu procesů.
- Protizkouška pomocí
php -r 'var_dump(ini_get("memory_hard_limit_percent"));';bool(false)podle příručky znamená dotčenou verzi. - Zajistit logy a zkontrolovat je na nápadnosti.
Jak spolehlivě doložit verzi a stav záplat, popisuje článek Správná kontrola verze PHP a stavu záplat.
Jak konkrétně pomáhá PHP SOS?
V bezpečnostní servisní smlouvě přebíráme základní péči o PHP spolu s vaším týmem:
- Inventář: všechny varianty PHP, verze, pooly a místa konfigurace pro každý server.
- Konfigurace: bezpečnostně relevantní hodnoty nastavené pomocí
php_admin_value, pooly oddělené pro každý web. - Aktualizace: nasazení, restart, kontrola a dokumentace při každém bezpečnostním vydání.
- Předání znalostí: vysvětlíme vašim administrátorům, co jsme změnili a proč.
Časté dotazy
Proč php -v ukazuje jinou verzi než web?
Příkazová řádka, PHP-FPM a modul Apache jsou samostatné programy s vlastní verzí a vlastní php.ini. php -v ukazuje jen příkazovou řádku. Pro web platí verze binárky, která skutečně vyřizuje požadavky.
Která php.ini platí na mém serveru?
To ukáže php --ini pro příkazovou řádku. Pro PHP-FPM existuje většinou vlastní php.ini a další soubory poolů. Od PHP 8.5 ukazuje php --ini=diff, které hodnoty se liší od výchozích.
Jaký je rozdíl mezi php_value a php_admin_value?
Obě nastavují hodnoty v poolu FPM. Hodnoty nastavené pomocí php_admin_value aplikace podle příručky nemůže přepsat pomocí ini_set(). Pro bezpečnostně relevantní nastavení je proto php_admin_value správnou volbou.
Stačí aktualizace bez restartu?
Ne. Běžící procesy PHP si ponechávají starý kód v paměti. Po aktualizaci je nutné restartovat PHP-FPM, Apache s mod_php nebo LiteSpeed, jinak dál běží zranitelná verze.