PHP2Shell auf Ubuntu patchen: Wenn das Ondřej-PPA nach dem Release-Upgrade still abgeschaltet ist
Beim Einspielen des kritischen PHP2Shell-Fixes stellte sich heraus, dass ein Ubuntu-24.04-Server seit dem Release-Upgrade keine PHP-Updates mehr bekam: Das Ondřej-PPA war still deaktiviert. Hier der Weg von der Diagnose über die Reparatur bis zur Prüfung, welches PHP Apache wirklich nutzt.
$ git log --graph Der Weg zur Lösung
-
Problem
Kritisches PHP-Update kommt nicht an
Für PHP2Shell sollte PHP auf einem Ubuntu-24.04-Server aktualisiert werden, apt bot aber keine neuen Versionen an.
-
Erkenntnis
Ondřej-PPA seit dem Release-Upgrade abgeschaltet
apt policy zeigte jammy-Builds mit dpkg/status als einziger Quelle; in sources.list.d lag eine .distUpgrade-Datei.
-
Versuch
PPA für noble neu eingerichtet und PHP gezielt aktualisiert
Alte Quelldateien weggeräumt, add-apt-repository ppa:ondrej/php, dann apt install --only-upgrade für alle installierten PHP-Pakete. 8.4 kam auf 8.4.27, 7.4 und 8.1 auf Pakete mit zurückportiertem Fix.
-
Irrweg
grep -r in /etc/apache2 fand nur conf-available
grep -r folgt keinen Symlinks, daher blieben conf-enabled und mods-enabled unsichtbar und es sah nach FPM aus.
-
Erkenntnis
Apache nutzt mod_php, nicht FPM
apache2ctl -M zeigte php_module ohne proxy_fcgi; die drei laufenden FPM-Dienste waren ungenutzt.
-
Lösung
mod_php 8.4.27 gepatcht und geprüft
Changelog-Prüfung per zgrep auf die CVE-Nummern und needrestart bestätigten, dass gepatchter Code läuft.
Nach den Notfall-Releases für PHP2Shell (CVE-2026-109618 und CVE-2026-109619, gefixt in PHP 8.5.12, 8.4.27, 8.3.36 und 8.2.35) wollte ich einen Wiki-Server mit Ubuntu 24.04 patchen. Darauf waren PHP 7.4, 8.1 und 8.4 aus dem PPA von Ondřej Surý installiert. Ein apt upgrade hätte schlicht nichts gefunden – und zwar nicht, weil schon alles aktuell war.
Das Problem
Der erste Blick mit apt policy zeigte das eigentliche Problem:
apt policy php*-fpm
php8.4-fpm:
Installiert: 8.4.10-1+ubuntu22.04.1+deb.sury.org+1
Installationskandidat: 8.4.10-1+ubuntu22.04.1+deb.sury.org+1
Versionstabelle:
*** 8.4.10-1+ubuntu22.04.1+deb.sury.org+1 100
100 /var/lib/dpkg/status
php8.3-fpm:
Installiert: (keine)
Installationskandidat: 8.3.6-0ubuntu0.24.04.13
Versionstabelle:
8.3.6-0ubuntu0.24.04.13 500
500 http://de.archive.ubuntu.com/ubuntu noble-updates/universe amd64 Packages
Zwei Dinge fallen auf:
- Die installierten Pakete sind Builds für 22.04 (
+ubuntu22.04.1), obwohl das System längst auf 24.04 (noble) läuft. - Als einzige Quelle steht
100 /var/lib/dpkg/statusda. Es gibt also kein Repository mehr, aus dem ein Update kommen könnte. 8.4.10 bleibt für immer 8.4.10.
Die Ursache steht in /etc/apt/sources.list.d/:
ls /etc/apt/sources.list.d/
ondrej-ubuntu-php-jammy.list.distUpgrade ondrej-ubuntu-php-jammy.sources ubuntu.sources
do-release-upgrade deaktiviert Fremdquellen. Die übrig gebliebene Datei zeigt noch auf jammy – und niemand hat das PPA danach wieder eingeschaltet.
Die Lösung
1. Das PPA für die aktuelle Ubuntu-Version neu einrichten
Statt die alte Datei umzubiegen, habe ich die Altlasten weggeräumt und das PPA neu angelegt:
sudo mkdir -p /root/apt-backup
sudo mv /etc/apt/sources.list.d/ondrej-ubuntu-php-jammy.* /root/apt-backup/
sudo add-apt-repository ppa:ondrej/php
sudo apt update
apt policy php8.4-fpm php8.1-fpm php7.4-fpm
php8.4-fpm:
Installiert: 8.4.10-1+ubuntu22.04.1+deb.sury.org+1
Installationskandidat: 8.4.27-1+ubuntu24.04.1+deb.sury.org+1
Versionstabelle:
8.4.27-1+ubuntu24.04.1+deb.sury.org+1 500
500 https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble/main amd64 Packages
*** 8.4.10-1+ubuntu22.04.1+deb.sury.org+1 100
100 /var/lib/dpkg/status
php8.1-fpm:
Installiert: 8.1.33-1+ubuntu22.04.1+deb.sury.org+1
Installationskandidat: 8.1.34-9+ubuntu24.04.1+deb.sury.org+1
php7.4-fpm:
Installiert: 1:7.4.33-21+ubuntu22.04.1+deb.sury.org+1
Installationskandidat: 1:7.4.33-31+ubuntu24.04.1+deb.sury.org+1
Jetzt gibt es wieder Kandidaten aus noble, bei 8.4 genau die gefixte 8.4.27.
2. Alle PHP-Pakete gezielt aktualisieren
Ich wollte nur PHP anfassen, nicht das ganze System. Deshalb die Paketliste aus dpkg holen, erst simulieren und dann ausführen:
PKGS=$(dpkg -l 'php*' 'libapache2-mod-php*' | awk '/^ii/{print $2}')
sudo apt install --only-upgrade -s $PKGS | grep -E '^(Inst|Remv)'
sudo apt install --only-upgrade $PKGS
3. Prüfen, ob der Fix wirklich drin ist
php-fpm8.4 -v
PHP 8.4.27 (fpm-fcgi) (built: Oct 21 2026 14:35:21) (NTS)
Für die Altversionen 7.4 und 8.1 gibt es upstream gar kein Release mit dem Fix. Die Versionsnummer hilft hier also nicht weiter. Das Changelog des Pakets verrät aber, ob der Fix zurückportiert wurde:
zgrep -lE 'CVE-2026-10961[89]' /usr/share/doc/php8.1*/changelog.Debian.gz /usr/share/doc/php7.4*/changelog.Debian.gz
/usr/share/doc/php8.1-cli/changelog.Debian.gz
/usr/share/doc/php8.1-common/changelog.Debian.gz
/usr/share/doc/php8.1-fpm/changelog.Debian.gz
…
/usr/share/doc/php7.4-cli/changelog.Debian.gz
/usr/share/doc/php7.4-common/changelog.Debian.gz
/usr/share/doc/php7.4-fpm/changelog.Debian.gz
…
Beide Versionen enthalten den Fix. Eine leere Ausgabe hätte bedeutet: nicht gepatcht.
4. Prüfen, dass nichts Altes mehr läuft
Ein Update hilft nur, wenn die laufenden Prozesse die neuen Bibliotheken auch geladen haben:
sudo needrestart -r l
No services need to be restarted.
No containers need to be restarted.
No user sessions are running outdated binaries.
5. Herausfinden, welches PHP Apache tatsächlich nutzt
Es liefen drei FPM-Dienste (7.4, 8.1, 8.4). Welcher davon bedient das Wiki? Die Antwort war: keiner.
ls -l /etc/apache2/conf-enabled/ | grep php
apache2ctl -M 2>/dev/null | grep -iE 'php|proxy_fcgi'
ls /etc/apache2/mods-enabled/ | grep php
dpkg -l 'libapache2-mod-php*' | grep ^ii
lrwxrwxrwx 1 root root 33 Jul 25 2025 php8.4-fpm.conf -> ../conf-available/php8.4-fpm.conf
php_module (shared)
php8.4.conf
php8.4.load
ii libapache2-mod-php8.1 8.1.34-9+ubuntu24.04.1+deb.sury.org+1 amd64 …
ii libapache2-mod-php8.4 8.4.27-1+ubuntu24.04.1+deb.sury.org+1 amd64 …
php_module ist geladen, proxy_fcgi nicht. Die eingebundene php8.4-fpm.conf greift laut eigenem Kommentar nur „if mod_php is not available“ – sie ist also wirkungslos. Das Wiki läuft über mod_php 8.4. Zum Glück war das Apache-Modul in der Paketliste aus Schritt 2 enthalten und damit ebenfalls auf 8.4.27:
zgrep -lE 'CVE-2026-10961[89]' /usr/share/doc/libapache2-mod-php*/changelog.Debian.gz
/usr/share/doc/libapache2-mod-php8.1/changelog.Debian.gz
/usr/share/doc/libapache2-mod-php8.4/changelog.Debian.gz
6. Aufräumen
Die drei FPM-Dienste laufen ungenutzt mit. Als Nächstes stehen deshalb an (noch nicht ausgeführt, als Plan):
sudo systemctl disable --now php7.4-fpm php8.1-fpm php8.4-fpm
sudo a2disconf php8.4-fpm
sudo apache2ctl configtest && sudo systemctl reload apache2
Und später, wenn sicher ist, dass kein Cronjob mehr php7.4 oder php8.1 direkt aufruft, die Altversionen ganz entfernen (vorher mit -s simulieren).
Warum das funktioniert
Ein Release-Upgrade setzt Fremdquellen bewusst außer Betrieb, weil ihre Pakete für die alte Version gebaut sind. Die installierten Pakete bleiben aber da und funktionieren weiter – nur bekommen sie nie wieder ein Update. apt meldet das nicht als Fehler: Ein Paket ohne Quelle ist für apt einfach „aktuell“. Erst die Versionstabelle in apt policy zeigt, dass nur noch /var/lib/dpkg/status als Quelle übrig ist.
Mit dem neu eingerichteten PPA liefert Ondřej Builds für noble aus, und --only-upgrade ersetzt die alten jammy-Pakete gezielt, ohne neue Pakete zu installieren.
Stolperfallen
php -vist auf Ubuntu-Paketen kein Beweis. Ubuntus eigene Pakete portieren den Fix zurück, ohne die Versionsnummer zu ändern: Ein gepatchtes 24.04 zeigt weiter 8.3.6. Dort zählt die Paketversion (für 24.04:8.3.6-0ubuntu0.24.04.13) oder derzgrepim Changelog. Bei den Sury-Paketen zeigtphp -vdagegen die echte Upstream-Version.grep -rfolgt keinen Symlinks. Mein erster Versuch, mitgrep -r … /etc/apache2/die aktive PHP-Anbindung zu finden, lieferte nur Treffer inconf-available/.conf-enabled/undmods-enabled/bestehen aus Symlinks und wurden übersprungen.grep -Roder gleichapache2ctl -Mzeigen, was wirklich aktiv ist.- Laufende FPM-Dienste heißen nicht, dass sie genutzt werden. Hier liefen drei FPM-Versionen, das Wiki hing aber an mod_php – laut PHP-Sicherheitsteam der riskanteste Betriebsmodus bei dieser Lücke. Hätte ich nur
php8.4-fpmaktualisiert, wäre das eigentliche Einfallstor offen geblieben. - Nach jedem Release-Upgrade lohnt ein
ls /etc/apt/sources.list.d/: Jede.distUpgrade-Datei ist eine abgeschaltete Quelle.