Kurz gesagt: Für Admins ohne Entwicklerhintergrund reichen fünf Grundlagen, um PHP sicher zu betreiben: PHP besteht aus mehreren Programmen (Kommandozeile, PHP-FPM, Apache-Modul) mit jeweils eigener Version; Einstellungen wirken in Ebenen von der php.ini bis zur Anwendung; PHP-FPM verteilt Anfragen auf Worker in Pools; ein Update wirkt erst nach dem Neustart aller Prozesse; und Logs sind der wichtigste Hinweis, wenn etwas nicht stimmt. Wer diese Punkte kennt, kann Lücken wie PHP2Shell zügig und nachweisbar schliessen.
Woraus PHP auf einem Server besteht
PHP ist kein einzelnes Programm. Auf einem typischen Linux-Server finden sich mehrere Varianten, die jeweils über eine Server-Schnittstelle (SAPI) angebunden sind:
| Variante | Typischer Name | Wofür |
|---|---|---|
| Kommandozeile (CLI) | php, php8.3 |
Cronjobs, Composer, Wartungsskripte |
| PHP-FPM | php-fpm, php-fpm8.3 |
Webanfragen hinter Nginx oder Apache |
| Apache-Modul | mod_php, libphp |
Webanfragen direkt im Apache-Prozess |
| CGI | php-cgi |
ältere Aufbauten |
Jede Variante kann eine andere Version und eine andere php.ini haben. Auf vielen Servern laufen zudem mehrere PHP-Versionen parallel, etwa 8.2 und 8.4. Bei einem Update muss jede einzeln betrachtet werden. Wie die Schnittstellen arbeiten, erklärt PHP-FPM erklärt.
Welche Variante Ihre Websites tatsächlich bedient, finden Sie über die laufenden Prozesse und die Webserver-Konfiguration heraus:
ps -eo pid,user,lstart,cmd | grep -E "php|httpd|apache2" | grep -v grep
apachectl -M 2>/dev/null | grep -i php # lädt Apache ein PHP-Modul?
ls /run/php/ 2>/dev/null # FPM-Sockets, oft je Version und Pool
Die Spalte mit der Startzeit ist später beim Neustart wichtig: Alle PHP-Prozesse müssen nach dem Zeitpunkt des Updates gestartet worden sein. Laufen Prozesse unter verschiedenen Benutzern, deutet das auf getrennte Pools hin, was gut ist. Taucht ein PHP-Modul im Apache auf, obwohl alle Websites über FPM laufen sollen, ist das ein Hinweis auf eine Altlast, die entfernt gehört. Für Hosting-Oberflächen wie Plesk oder cPanel gilt dasselbe Prinzip, nur dass die Oberfläche die Versionen und Handler je Website anzeigt; massgeblich bleibt aber, was tatsächlich als Prozess läuft.
Die wichtigsten Befehle für Admins
php -v # Version der Kommandozeile
php --ini # geladene php.ini und zusätzlich gelesene Verzeichnisse
php --ini=diff # ab PHP 8.5: Abweichungen vom Standard
php -m # einkompilierte und geladene Module
php --ri session # Einstellungen einer Erweiterung
php -l datei.php # Syntaxprüfung ohne Ausführung
php-fpm8.3 -v # Version der FPM-Binary (Name je Distribution)
php-fpm8.3 -t # FPM-Konfiguration testen, ohne neu zu starten
systemctl status php8.3-fpm
Zwei Hinweise aus dem Handbuch: php -l findet Syntaxfehler, aber keine Fehler, die erst bei der Ausführung auftreten. Und php -i ruft phpinfo() auf; die Ausgabe gehört nicht in öffentliche Dateien im Webverzeichnis.
Wie PHP-Einstellungen wirken
Eine Einstellung kann an mehreren Stellen gesetzt werden. Wer wo was ändern darf, regelt der Änderungsmodus jeder Direktive:
- php.ini und conf.d: Grundkonfiguration je Variante, gelesen beim Start.
- FPM-Pool:
php_valueundphp_admin_valueje Pool. Mitphp_admin_valuegesetzte Werte kann die Anwendung laut Handbuch nicht perini_set()überschreiben. - Verzeichnisebene:
.user.inibei FPM oder.htaccessbei mod_php, nur für Direktiven im ModusINI_PERDIRoderINI_ALL. - Anwendung:
ini_set()zur Laufzeit, nur für Direktiven im ModusINI_ALL.
Ein Beispiel: memory_limit hat den Modus INI_ALL, kann also von der Anwendung geändert werden. post_max_size hat INI_PERDIR und lässt sich nicht per ini_set() ändern. Deshalb verlangt php.net bei den PHP2Shell-Übergangsmassnahmen, Werte so zu setzen, dass Anwendungen sie nicht überschreiben können. Details zu den Ebenen erklärt Die php.ini erklärt.
PHP-FPM-Pools in Kürze
Ein Pool ist eine Gruppe von Workern mit eigenem Benutzer, eigenem Socket und eigenen Einstellungen. Die wichtigsten Direktiven laut Handbuch:
[shop]
user = shop
group = shop
listen = /run/php/shop.sock
pm = dynamic ; static, dynamic oder ondemand
pm.max_children = 20 ; höchstens 20 gleichzeitige Anfragen
pm.max_requests = 500 ; Worker nach 500 Anfragen erneuern
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
Ein eigener Pool je Website mit eigenem Benutzer trennt Websites voneinander. security.limit_extensions steht standardmässig auf .php .phar und verhindert, dass FPM andere Dateiendungen als PHP ausführt. clear_env ist standardmässig eingeschaltet und hält Umgebungsvariablen vom Worker fern.
Logs: wo Admins hinschauen
PHP schreibt Fehler in das mit error_log festgelegte Ziel, PHP-FPM zusätzlich in sein eigenes Log und bei langsamen Anfragen in das Slowlog mit Backtrace. Dazu kommen die Zugriffs- und Fehlerlogs des Webservers. Achten Sie darauf, dass display_errors in der Produktion ausgeschaltet und log_errors eingeschaltet ist: Fehler gehören ins Log, nicht auf die Webseite. Logs sollten ausserdem rotiert und für einen festgelegten Zeitraum aufbewahrt werden, damit sie im Ernstfall noch da sind. Nach PHP2Shell empfiehlt die Fachpresse, Server-Logs ab dem 20.10.2026 aufzubewahren. Ein starkes Warnsignal ist ein PHP-FPM- oder Webserver-Prozess, der eine Shell startet; wie Sie das erkennen, steht unter Warnsignal: Der Webserver startet eine Shell.
Prüfliste für Admins nach PHP2Shell
- Alle PHP-Varianten und Versionen auf dem Server auflisten, auch die nicht genutzten.
- Paketstand prüfen; bei Backports der Distribution den Changelog nach CVE-2026-109618 und CVE-2026-109619 durchsuchen.
- Aktualisieren auf 8.5.12, 8.4.27, 8.3.36 oder 8.2.35 beziehungsweise den bestätigten Backport.
- PHP-FPM, Apache und LiteSpeed neu starten und Startzeiten der Prozesse kontrollieren.
- Gegenprobe mit
php -r 'var_dump(ini_get("memory_hard_limit_percent"));';bool(false)bedeutet laut Handbuch eine betroffene Version. - Logs sichern und auf Auffälligkeiten prüfen.
Wie Sie Version und Patchstand belastbar nachweisen, beschreibt PHP-Version und Patchstand richtig prüfen.
Wie hilft PHP SOS konkret?
Im Security-Wartungsvertrag übernehmen wir die PHP-Grundpflege mit Ihrem Team:
- Inventar: alle PHP-Varianten, Versionen, Pools und Konfigurationsorte je Server.
- Konfiguration: sicherheitsrelevante Werte mit
php_admin_valuegesetzt, Pools je Website getrennt. - Updates: Einspielen, Neustart, Kontrolle und Dokumentation bei jedem Sicherheitsrelease.
- Wissen weitergeben: Wir erklären Ihren Admins, was wir geändert haben und warum.
Häufige Fragen
Warum zeigt php -v eine andere Version als die Website?
Kommandozeile, PHP-FPM und Apache-Modul sind getrennte Programme mit eigener Version und eigener php.ini. php -v zeigt nur die Kommandozeile. Für die Website zählt die Version der Binary, die tatsächlich Anfragen bearbeitet.
Welche php.ini gilt auf meinem Server?
Das zeigt php --ini für die Kommandozeile. Für PHP-FPM gibt es meist eine eigene php.ini und zusätzliche Pool-Dateien. Seit PHP 8.5 zeigt php --ini=diff, welche Werte vom Standard abweichen.
Was ist der Unterschied zwischen php_value und php_admin_value?
Beide setzen Einstellungen in einem FPM-Pool. Werte mit php_admin_value kann die Anwendung laut Handbuch nicht mit ini_set() überschreiben. Für sicherheitsrelevante Einstellungen ist php_admin_value daher die richtige Wahl.
Reicht ein Update ohne Neustart?
Nein. Laufende PHP-Prozesse behalten den alten Code im Speicher. Nach einem Update müssen PHP-FPM, Apache mit mod_php oder LiteSpeed neu gestartet werden, sonst läuft die verwundbare Version weiter.