Stručně: Chcete-li Apache pro PHP nastavit bezpečně, připojte PHP přes PHP-FPM a mod_proxy_fcgi, vypněte .htaccess pomocí AllowOverride None a nastavte ServerTokens Prod, ServerSignature Off, TraceEnable Off a Options -Indexes. LimitRequestBody přizpůsobte limitům PHP, nepotřebné moduly vypněte. Konfigurace nenahrazuje aktualizaci PHP, plochu pro útok ale výrazně zmenšuje.
Apache po PHP2Shell: víc než restart
Provozovatelé Apache byli v říjnu 2026 pod zvláštním tlakem. Tým PHP hodnotí riziko u mod_php jako nejvyšší, protože tam byl předveden exploit ještě předtím, než vůbec běží kód aplikace. Akutní kroky, tedy záplatování a úplný restart, popisuje stránka Proč nese mod_php nejvyšší riziko.
Po záplatě zůstává otázka, jak dobrá je samotná konfigurace Apache. Vyrostlé servery často nesou nastavení z mnoha let: výpisy adresářů, otevřená práva .htaccess, moduly, které už nikdo nepotřebuje. Každé z nich může pozdější chybu učinit větší, než by musela být.
Tento článek popisuje štíhlou, bezpečnou základní konfiguraci Apache 2.4 s PHP-FPM. Příklady používají cesty Debianu a Ubuntu; v rodině RHEL leží soubory pod /etc/httpd/.
Připojit PHP přes PHP-FPM místo mod_php
S PHP-FPM běží PHP ve vlastních procesech, odděleně od webového serveru. Apache předává požadavky přes mod_proxy_fcgi. Podle dokumentace Apache má připojení pomocí SetHandler oproti ProxyPassMatch výhodu: Apache nejprve sám přiřadí požadavek souboru v souborovém systému a teprve poté jej předá PHP-FPM.
<FilesMatch "\.php$">
SetHandler "proxy:unix:/run/php/seite1.sock|fcgi://localhost/"
</FilesMatch>
Moduly aktivujete v Debianu a Ubuntu pomocí a2enmod proxy_fcgi. Kdo přechází z mod_php, deaktivuje modul PHP a poté přepne z MPM prefork na MPM event. Pozadí starého provozního režimu vysvětluje mod_php vysvětleno: PHP v procesu Apache.
Na straně PHP-FPM patří security.limit_extensions = .php do každého poolu. Podle příručky PHP FPM jinak spouští i soubory .phar.
Bezpečná konfigurace Apache pro PHP: základní volby
Některá nastavení platí pro celý server a patří do vlastního konfiguračního souboru, například /etc/apache2/conf-available/haertung.conf, aktivovaného pomocí a2enconf haertung.
# Zkrátit údaje o verzi (možné jen pro celý server)
ServerTokens Prod
ServerSignature Off
# Vypnout metodu TRACE
TraceEnable Off
# Zásadně nic nepovolovat, weby povolovat cíleně
<Directory />
Options None
AllowOverride None
Require all denied
</Directory>
Následující tabulka zařazuje nejdůležitější volby. Výchozí hodnoty a účinek pocházejí z dokumentace Apache.
| Direktiva | Výchozí | Doporučení | Proč |
|---|---|---|---|
ServerTokens |
Full |
Prod |
hlavička Server uvádí jen „Apache“ |
ServerSignature |
Off |
Off |
žádný řádek s verzí pod chybovými stránkami |
TraceEnable |
on |
Off |
TRACE je odmítnuto kódem 405 |
Options |
FollowSymlinks |
-Indexes, symlinky jen podle vlastníka |
žádné výpisy adresářů |
AllowOverride |
None |
None |
.htaccess se nevyhodnocuje |
LimitRequestBody |
1 GiB (od 2.4.54) | v souladu s post_max_size |
velké požadavky odmítat brzy |
Důležité u AllowOverride: Mnoho distribucí a návodů pro CMS nastavuje pro webroot AllowOverride All. Každý soubor .htaccess pak může měnit pravidla přepisování, handlery a u mod_php dokonce nastavení PHP. Útočník s právem zápisu ve složce s nahranými soubory tam může umístit vlastní .htaccess. S AllowOverride None je tato cesta uzavřena.
VirtualHost jako šablona
Následující VirtualHost spojuje body pro jeden web. Cesty k certifikátům, socket a adresáře si upravte. mod_ssl a mod_headers musí být aktivní.
<VirtualHost *:443>
ServerName www.example.de
DocumentRoot /var/www/seite1/public
SSLEngine on
SSLCertificateFile /etc/ssl/seite1/fullchain.pem
SSLCertificateKeyFile /etc/ssl/seite1/privkey.pem
<Directory /var/www/seite1/public>
Options -Indexes +SymLinksIfOwnerMatch
AllowOverride None
Require all granted
</Directory>
<FilesMatch "\.php$">
SetHandler "proxy:unix:/run/php/seite1.sock|fcgi://localhost/"
</FilesMatch>
# Zablokovat správu verzí a soubory prostředí
<DirectoryMatch "/\.(git|svn|hg)">
Require all denied
</DirectoryMatch>
<FilesMatch "^\.env">
Require all denied
</FilesMatch>
# 32 MiB, v souladu s post_max_size = 32M
LimitRequestBody 33554432
Header unset X-Powered-By
Header always unset X-Powered-By
</VirtualHost>
Dvojí Header unset není omyl. Podle dokumentace Apache končí hlavičky z mod_proxy_fcgi v jiné interní tabulce než hlavičky samotného serveru; s oběma variantami zachytíte oba případy. Další hlavičky, které aktivně chrání návštěvníky, popisuje průvodce Bezpečnostní hlavičky pro weby.
Složky pro nahrávání a cache potřebují navíc zákaz spouštění. Jak najít všechny zapisovatelné složky a zablokovat je, je v článku Zákaz spouštění PHP ve složkách s nahranými soubory.
Vyčistit moduly a ověřit výsledek
Každý načtený modul je kód, který reaguje na požadavky. Zkontrolujte, které moduly jsou aktivní, a vypněte, co nepotřebujete. Typickými kandidáty jsou autoindex, status bez omezení přístupu, cgi a userdir.
# Zobrazit aktivní moduly
apachectl -M | sort
# Příklad Debian/Ubuntu: vypnout modul výpisů adresářů
sudo a2dismod autoindex
# Zkontrolovat konfiguraci a teprve poté znovu načíst
sudo apachectl configtest && sudo systemctl reload apache2
# Test zvenčí: TRACE má vrátit 405, .git 403
curl -s -o /dev/null -w "%{http_code}\n" -X TRACE https://www.example.de/
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.git/HEAD
Zvláštní pozornost zaslouží mod_status. Stavová stránka ukazuje běžící požadavky s adresami a voláními cest. Pokud ji potřebujete, omezte přístup pomocí Require ip na své správcovské sítě. Totéž platí pro stavové stránky PHP-FPM zpřístupněné přes Apache.
AllowOverride nepřepínejte bez přípravy. Nejprve převezměte pravidla ze všech souborů .htaccess do VirtualHost a web otestujte na kopii. Jinak po opětovném načtení přestanou fungovat přesměrování a hezké adresy URL.
Jako další vrstva před aplikací může být užitečný vlastní webový aplikační firewall; úvod popisuje Nasazení ModSecurity a OWASP Core Rule Set.
Závěr: pořádek poráží jednotlivé opatření
Bezpečná konfigurace Apache pro PHP se skládá z několika dobře pochopených stavebních kamenů. PHP běží přes PHP-FPM odděleně od webového serveru, .htaccess se nevyhodnocuje, údaje o verzi a TRACE jsou vypnuty, limity velikosti odpovídají PHP a zapisovatelné složky nespouštějí skripty. Žádný z těchto bodů sám o sobě není pozoruhodný. Dohromady zajišťují, že chyba na jednom místě nevede hned k převzetí serveru.
Pro vedení a odpovědné osoby projektů je téměř důležitější druhá vlastnost: uklizená konfigurace je srozumitelná. Pokud jsou všechna pravidla ve VirtualHost místo roztroušených v desítkách souborů .htaccess, lze při příští kritické zranitelnosti rychle zkontrolovat, který web je jak připojen. V situaci jako v říjnu 2026 to ušetří právě ten čas, na kterém záleží.
Přechod přesto plánujte v klidu a s testovacím prostředím. Uspěchaná změna z mod_php na PHP-FPM krátce před víkendem spíše vytvoří nové problémy, než jaké vyřeší.
Jak konkrétně pomáhá PHP SOS?
- Zkontrolovat stav: Načteme celou konfiguraci Apache, všechny aktivní moduly a všechny soubory
.htaccess. - Naplánovat přechod: Kde ještě běží mod_php, připravíme přechod na PHP-FPM s vlastními pooly pro každý web.
- Zpevnit konfiguraci: Nastavíme základní volby, pravidla z
.htaccesspřevedeme do VirtualHost a zapisovatelné složky zablokujeme. - Otestovat a zdokumentovat: Po každé změně zkontrolujeme weby zvenčí a stav zaznamenáme v rámci zpevnění serveru.
Časté dotazy
Měl bych ještě používat mod_php?
Pro nové instalace doporučujeme PHP-FPM přes mod_proxy_fcgi. Tým PHP hodnotí riziko PHP2Shell u mod_php jako nejvyšší. S PHP-FPM běží PHP odděleně od webového serveru, s vlastními uživateli pro každý web a vlastními limity.
Proč AllowOverride None, když moje CMS potřebuje .htaccess?
Soubor .htaccess může vytvořit každý, kdo smí zapisovat do webrootu, i vložený kód. S AllowOverride None Apache takové soubory nevyhodnocuje. Pravidla svého CMS pak jednorázově převezmete do VirtualHost. Je to trochu práce, konfiguraci to ale činí srozumitelnou a rychlejší.
Mohu ServerTokens nastavit pro každý web jinak?
Ne. Podle dokumentace Apache platí ServerTokens pro celý server a nelze je měnit pro jednotlivý VirtualHost. Řídí zároveň údaj o verzi pod chybovými stránkami, který zobrazuje ServerSignature.
Jakou hodnotu má LimitRequestBody ve výchozím stavu?
Od Apache 2.4.54 je výchozí hodnota 1 GiB, ve verzi 2.4.53 a starších byla neomezená. Nastavte hodnotu v souladu s post_max_size ve své konfiguraci PHP, aby se příliš velké požadavky odmítaly už ve webovém serveru.