Krótko: Aby bezpiecznie skonfigurować Apache dla PHP, podłączają Państwo PHP przez PHP-FPM i mod_proxy_fcgi, wyłączają .htaccess za pomocą AllowOverride None i ustawiają ServerTokens Prod, ServerSignature Off, TraceEnable Off oraz Options -Indexes. LimitRequestBody dopasowują Państwo do limitów PHP, a niepotrzebne moduły wyłączają. Konfiguracja nie zastępuje aktualizacji PHP, ale wyraźnie zmniejsza powierzchnię ataku.
Apache po PHP2Shell: więcej niż restart
Operatorzy Apache byli w październiku 2026 pod szczególną presją. Zespół PHP ocenia ryzyko przy mod_php najwyżej, ponieważ pokazano tam exploit, zanim w ogóle zacznie działać kod aplikacji. Kroki doraźne, czyli łatanie i pełny restart, opisuje strona Dlaczego mod_php niesie najwyższe ryzyko.
Po załataniu pozostaje pytanie, jak dobra jest sama konfiguracja Apache. Serwery rozbudowywane latami często noszą ustawienia sprzed wielu lat: listy katalogów, otwarte uprawnienia .htaccess, moduły, których nikt już nie potrzebuje. Każde z nich może sprawić, że późniejszy błąd będzie większy, niż musiałby być.
Ten artykuł opisuje szczupłą, bezpieczną konfigurację podstawową dla Apache 2.4 z PHP-FPM. Przykłady używają ścieżek Debiana i Ubuntu; w rodzinie RHEL pliki leżą w /etc/httpd/.
Podłączanie PHP przez PHP-FPM zamiast mod_php
Z PHP-FPM PHP działa we własnych procesach, oddzielnie od serwera WWW. Apache przekazuje żądania przez mod_proxy_fcgi. Według dokumentacji Apache podłączenie przez SetHandler ma przewagę nad ProxyPassMatch: Apache najpierw sam przypisuje żądanie do pliku w systemie plików i dopiero potem przekazuje do PHP-FPM.
<FilesMatch "\.php$">
SetHandler "proxy:unix:/run/php/seite1.sock|fcgi://localhost/"
</FilesMatch>
Moduły włącza się w Debianie i Ubuntu poleceniem a2enmod proxy_fcgi. Kto przechodzi z mod_php, dezaktywuje moduł PHP i następnie przechodzi z MPM Prefork na MPM Event. Tło dotyczące starego trybu pracy wyjaśnia artykuł mod_php wyjaśniony: PHP w procesie Apache.
Po stronie PHP-FPM security.limit_extensions = .php należy do każdej puli. Według podręcznika PHP FPM w przeciwnym razie wykonuje też pliki .phar.
Bezpieczna konfiguracja Apache dla PHP: opcje podstawowe
Niektóre ustawienia obowiązują dla całego serwera i należą do osobnego pliku konfiguracyjnego, na przykład /etc/apache2/conf-available/haertung.conf, aktywowanego przez a2enconf haertung.
# Skrócić informacje o wersji (możliwe tylko dla całego serwera)
ServerTokens Prod
ServerSignature Off
# Wyłączyć metodę TRACE
TraceEnable Off
# Zasadniczo niczego nie udostępniać, strony zezwalać celowo
<Directory />
Options None
AllowOverride None
Require all denied
</Directory>
Poniższa tabela porządkuje najważniejsze opcje. Wartości domyślne i działanie pochodzą z dokumentacji Apache.
| Dyrektywa | Domyślnie | Zalecenie | Dlaczego |
|---|---|---|---|
ServerTokens |
Full |
Prod |
nagłówek Server podaje tylko „Apache” |
ServerSignature |
Off |
Off |
brak wiersza z wersją pod stronami błędów |
TraceEnable |
on |
Off |
TRACE jest odrzucane z kodem 405 |
Options |
FollowSymlinks |
-Indexes, dowiązania symboliczne tylko według właściciela |
brak list katalogów |
AllowOverride |
None |
None |
.htaccess nie jest analizowany |
LimitRequestBody |
1 GiB (od 2.4.54) | dopasowane do post_max_size |
wcześnie odrzucać duże żądania |
Ważne przy AllowOverride: wiele dystrybucji i instrukcji CMS ustawia dla katalogu głównego strony AllowOverride All. Wtedy każdy plik .htaccess może zmieniać reguły przepisywania, handlery, a przy mod_php nawet ustawienia PHP. Atakujący z prawami zapisu w katalogu uploadu może tam umieścić własny .htaccess. Przy AllowOverride None ta droga jest zamknięta.
VirtualHost jako wzorzec
Poniższy VirtualHost łączy punkty dla pojedynczej strony. Ścieżki certyfikatów, gniazdo i katalogi należy dopasować. mod_ssl i mod_headers muszą być aktywne.
<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>
# Zablokować system kontroli wersji i pliki środowiskowe
<DirectoryMatch "/\.(git|svn|hg)">
Require all denied
</DirectoryMatch>
<FilesMatch "^\.env">
Require all denied
</FilesMatch>
# 32 MiB, odpowiednio do post_max_size = 32M
LimitRequestBody 33554432
Header unset X-Powered-By
Header always unset X-Powered-By
</VirtualHost>
Podwójne Header unset nie jest przeoczeniem. Według dokumentacji Apache nagłówki z mod_proxy_fcgi trafiają do innej tabeli wewnętrznej niż nagłówki samego serwera; obydwoma wariantami obejmują Państwo oba przypadki. Dalsze nagłówki, które aktywnie chronią odwiedzających, opisuje poradnik Nagłówki bezpieczeństwa dla stron WWW.
Katalogi uploadu i pamięci podręcznej wymagają dodatkowo blokady wykonywania. Jak znaleźć i zablokować wszystkie zapisywalne katalogi, opisuje artykuł Zakazywanie wykonywania PHP w katalogach uploadu.
Przerzedzanie modułów i sprawdzanie wyniku
Każdy załadowany moduł to kod reagujący na żądania. Proszę sprawdzić, które moduły są aktywne, i wyłączyć te, których Państwo nie potrzebują. Typowi kandydaci to autoindex, status bez ograniczenia dostępu, cgi i userdir.
# Pokazać aktywne moduły
apachectl -M | sort
# Przykład Debian/Ubuntu: wyłączyć moduł list katalogów
sudo a2dismod autoindex
# Sprawdzić konfigurację i dopiero potem przeładować
sudo apachectl configtest && sudo systemctl reload apache2
# Test z zewnątrz: TRACE ma zwrócić 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
Szczególną uwagę zasługuje mod_status. Strona statusu pokazuje działające żądania z adresami i wywoływanymi ścieżkami. Jeśli jest potrzebna, proszę ograniczyć dostęp za pomocą Require ip do Państwa sieci administracyjnych. To samo dotyczy stron statusu PHP-FPM udostępnionych przez Apache.
Proszę nie przestawiać AllowOverride bez przygotowania. Najpierw przenieść reguły ze wszystkich plików .htaccess do VirtualHost i przetestować stronę na kopii. W przeciwnym razie przekierowania i przyjazne adresy URL przestaną działać po przeładowaniu.
Jako dodatkowa warstwa przed aplikacją może mieć sens własna Web Application Firewall; wprowadzenie opisuje artykuł Stosowanie ModSecurity i OWASP Core Rule Set.
Wniosek: porządek wygrywa z pojedynczym środkiem
Bezpieczna konfiguracja Apache dla PHP składa się z kilku dobrze zrozumianych elementów. PHP działa przez PHP-FPM oddzielnie od serwera WWW, .htaccess nie jest analizowany, informacje o wersji i TRACE są wyłączone, limity rozmiaru pasują do PHP, a zapisywalne katalogi nie wykonują skryptów. Żaden z tych punktów sam w sobie nie jest spektakularny. Razem sprawiają, że błąd w jednym miejscu nie prowadzi od razu do przejęcia serwera.
Dla zarządu i osób odpowiedzialnych za projekty druga cecha jest niemal ważniejsza: uporządkowana konfiguracja jest zrozumiała. Jeśli wszystkie reguły stoją w VirtualHost, a nie są rozproszone w dziesiątkach plików .htaccess, przy następnej krytycznej luce można szybko sprawdzić, która strona jest jak podłączona. W sytuacji takiej jak w październiku 2026 oszczędza to właśnie ten czas, na którym najbardziej zależy.
Przestawienie proszę mimo to planować spokojnie i ze środowiskiem testowym. Pochopna zmiana z mod_php na PHP-FPM tuż przed weekendem tworzy raczej nowe problemy, niż rozwiązuje.
Jak konkretnie pomaga PHP SOS?
- Sprawdzenie stanu: odczytujemy całą konfigurację Apache, wszystkie aktywne moduły i wszystkie pliki
.htaccess. - Planowanie przejścia: tam, gdzie nadal działa mod_php, przygotowujemy przejście na PHP-FPM z osobnymi pulami dla każdej strony.
- Utwardzanie konfiguracji: ustawiamy opcje podstawowe, przenosimy reguły
.htaccessdo VirtualHost i blokujemy zapisywalne katalogi. - Testowanie i dokumentowanie: po każdej zmianie sprawdzamy strony z zewnątrz i utrwalamy stan w ramach utwardzania serwerów.
Częste pytania
Czy nadal powinienem używać mod_php?
Dla nowych instalacji zalecamy PHP-FPM przez mod_proxy_fcgi. Zespół PHP ocenia ryzyko związane z PHP2Shell przy mod_php najwyżej. Z PHP-FPM PHP działa oddzielnie od serwera WWW, z własnymi użytkownikami dla każdej strony i własnymi limitami.
Dlaczego AllowOverride None, skoro mój CMS potrzebuje .htaccess?
.htaccess może założyć każdy, kto ma prawo zapisu w katalogu głównym strony, także wstrzyknięty kod. Przy AllowOverride None Apache nie analizuje takich plików. Reguły Państwa CMS przenoszą Państwo wtedy jednorazowo do VirtualHost. Wymaga to trochę pracy, ale czyni konfigurację zrozumiałą i szybszą.
Czy mogę ustawić ServerTokens inaczej dla każdej strony?
Nie. Według dokumentacji Apache ServerTokens obowiązuje dla całego serwera i nie można go zmienić dla pojedynczego VirtualHost. Steruje jednocześnie informacją o wersji pod stronami błędów, którą wyświetla ServerSignature.
Jaką wartość domyślną ma LimitRequestBody?
Od Apache 2.4.54 wartość domyślna to 1 GiB, w wersji 2.4.53 i starszych była nieograniczona. Proszę ustawić wartość odpowiednio do post_max_size w konfiguracji PHP, aby zbyt duże żądania były odrzucane już w serwerze WWW.