Ihr eigener RPM-Mirror, und den Fix bauen, bevor die Distribution ihn ausliefert
Wie Sie einen konsistenten lokalen RPM-Mirror betreiben und, wenn ein Fix upstream veröffentlicht, aber noch nicht paketiert ist, ihn sauber bauen, sodass das offizielle Paket später übernimmt.

Wenn eine ernste Schwachstelle veröffentlicht wird, entscheiden zwei Dinge darüber, wie lange Ihre Server exponiert bleiben: wie schnell Sie Pakete beziehen können, und ob das korrigierte Paket überhaupt schon existiert. Ein lokaler Mirror löst das Erste. Die Fähigkeit, selbst ein sauberes Paket zu bauen, aus der eigenen Spezifikation des Maintainers, löst das Zweite. So machen wir beides auf Enterprise Linux, und so machen Sie es, ohne selbstgebaute Pakete herumliegen zu lassen, nachdem die offiziellen angekommen sind.
Warum überhaupt einen eigenen Mirror betreiben
Öffentliche Mirrors werden von großzügigen Menschen und Organisationen betrieben, und an einem gewöhnlichen Tag sind sie schnell. An dem Tag, an dem ein kritischer Fix erscheint, fragt jeder Server der Welt gleichzeitig nach denselben Paketen. Ein lokaler Mirror in Ihrem eigenen Netzwerk macht daraus einen lokalen Kopiervorgang. Er erlaubt Ihnen außerdem, Server zu patchen, die bewusst vom Internet getrennt sind, etwa Backup- und Managementsysteme, ohne sie zu öffnen.
Es gibt einen stilleren Vorteil: Ein Mirror, der die vollständige Pakethistorie behält, erlaubt Ihnen, einen Server in einen bekannten Zustand neu aufzubauen oder ein Paket zurückzurollen, aus Ihrer eigenen Kopie.
Spiegeln, ohne je ein halb synchronisiertes Repository auszuliefern
Der naive Mirror ist ein rsync oder reposync direkt in das Verzeichnis, das Ihr Webserver veröffentlicht. Wenn ein Client dnf ausführt, während die Synchronisation halb durch ist, kann er neue Metadaten sehen, die auf Pakete verweisen, die noch nicht angekommen sind, oder alte Metadaten, die auf Pakete zeigen, die gerade entfernt wurden. Das Ergebnis sind verwirrende Fehler genau im falschen Moment.
Synchronisieren Sie stattdessen in zwei Phasen:
- Zuerst die Pakete. Holen Sie die Pakete in das veröffentlichte Verzeichnis. Die alten Metadaten beschreiben weiterhin einen konsistenten Satz, weil nichts, worauf sie verweisen, bisher entfernt wurde.
dnf reposync --repoid=os-baseos --arch=x86_64 --arch=noarch \
--delete --norepopath -p /srv/repo/os/baseos
- Dann die Metadaten, auf einen Schlag getauscht. Laden Sie das upstream
repodata/in ein Geschwisterverzeichnis herunter (jede Datei, auf dierepomd.xmlverweist), verifizieren Sie es, und ersetzen Sie dann die veröffentlichten Metadaten mit einer einzigen Umbenennung. Clients sehen das alte Repository oder das neue, nie eine Mischung.
mv /srv/repo/os/baseos/repodata /srv/repo/os/baseos/repodata.old
mv /srv/repo/os/baseos/repodata.new /srv/repo/os/baseos/repodata
Die upstream Metadaten zu verwenden, statt eigene mit createrepo_c neu zu erzeugen, hält das Repository genau so, wie der Herausgeber es gebaut hat.
Geben Sie jedem Sync-Job einen Lock, damit sich zwei Läufe nie überlappen, schreiben Sie eine kleine Statusdatei mit Ergebnis und Uhrzeit, und alarmieren Sie jemanden, wenn ein Job fehlschlägt. Ein Mirror, der letzten Monat still aufgehört hat zu synchronisieren, ist schlimmer als kein Mirror, weil alle ihm vertrauen.
Die Clients verwenden dann eine einfache Repository-Datei, die auf Ihren Mirror zeigt:
[local-baseos]
name=Local mirror: BaseOS
baseurl=https://mirror.example.internal/os/baseos/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-oracle
Wenn der Fix existiert, das Paket aber nicht
Manchmal liefert das Upstream-Projekt ein korrigiertes Release aus, und der Maintainer der Distribution oder des Repositorys hat es noch nicht paketiert. Oft beträgt diese Lücke Stunden. Manchmal sind es Tage.
Die Regel, der wir folgen: Bauen Sie das Upstream-Release aus dem eigenen Packaging des Maintainers, ändern Sie sonst nichts, und stellen Sie sicher, dass das offizielle Paket Ihres automatisch ersetzt.
In einem sauberen Raum bauen
Verwenden Sie einen frischen Container desselben Distributions-Releases wie die Zielserver, damit die Build-Umgebung bekannt und wegwerfbar ist:
podman run --rm -it -v ./build:/build:Z oraclelinux:<release> bash
dnf install -y rpm-build rpmdevtools dnf-plugins-core
rpmdev-setuptree
Beginnen Sie mit dem neuesten Quellpaket (SRPM) des Maintainers für den Branch, den Sie betreiben, installieren Sie es, und installieren Sie seine Build-Abhängigkeiten:
rpm -ivh php-<current>.src.rpm
dnf builddep -y ~/rpmbuild/SPECS/php.spec
Nur die Version ändern, und die Quelle verifizieren
Laden Sie das korrigierte Upstream-Tarball von der offiziellen Site des Projekts herunter und verifizieren Sie es gegen die Prüfsumme, die das Projekt veröffentlicht.
sha256sum php-<fixed>.tar.xz
Aktualisieren Sie in der Spec-Datei Version auf das korrigierte Release und ersetzen Sie die Quelle. Lassen Sie Patches, Configure-Optionen und Dateilisten so, wie der Maintainer sie geschrieben hat. Wenn ein Patch des Maintainers auf das neue Release nicht mehr passt, halten Sie an und verstehen Sie, warum, bevor Sie weitergehen.
Ein Release wählen, das zur Seite tritt
Das ist der Schritt, den die Leute vergessen. Ihr Paket muss niedriger sortieren als das spätere offizielle Paket des Maintainers mit derselben Version, damit ein normales dnf upgrade Ihres ersetzt. Ein Release, das mit 0. beginnt, tut das zuverlässig:
Release: 0.1.local%{?dist}
Prüfen Sie es, bevor Sie irgendetwas bauen, mit demselben Vergleich, den rpm verwendet:
rpmdev-vercmp 0:X.Y.Z-0.1.local.elN 0:X.Y.Z-1.elN.maint
Das offizielle Release sollte als neuer herauskommen. Wenn nicht, ändern Sie Ihren Release-String, bis es so ist.
Bauen, testen, die Belege aufbewahren
rpmbuild -ba ~/rpmbuild/SPECS/php.spec
Bewahren Sie die gebauten Pakete mit ihren Prüfsummen und einer Notiz zur Prüfsumme des Quell-Tarballs auf, damit jeder später genau sagen kann, was installiert wurde und woher es kam.
Veröffentlichen Sie Ihre Builds in einem separaten Repository auf Ihrem Mirror, nicht vermischt mit der Kopie des Hersteller-Repositorys. Wenn das offizielle Paket im gespiegelten Repository landet, ersetzt das nächste normale Update Ihres, und Ihr separates Repository kann geleert werden.
Anerkennung, wo sie hingehört
Nichts davon ersetzt die Menschen, die die Pakete pflegen. Repository-Maintainer wie Remi Collet, auf dessen PHP-Repositories ein großer Teil der Enterprise-Linux-Welt angewiesen ist, liefern Fixes oft bemerkenswert schnell aus. Aus ihrer Spezifikation zu bauen ist ein Weg, die letzten paar Stunden zu überbrücken, kein Ersatz für ihre Arbeit. Während der PHP2Shell-Fixes haben wir über beide Seiten davon geschrieben: PHP2Shell: patched PHP packages und Respect to Remi.
Eine Checkliste für Ihre eigene Plattform
- Woher beziehen Ihre Server Pakete, und was passiert, wenn dieser Ort langsam ist?
- Können Ihre isolierten Server gepatcht werden, ohne sie zum Internet zu öffnen?
- Könnte ein Client auf Ihrem Mirror je ein halb synchronisiertes Repository sehen?
- Erfährt jemand davon, wenn eine Mirror-Synchronisation fehlschlägt?
- Wenn Sie heute Nacht ein Paket bauen müssten, erlaubt Ihr Release-String dem offiziellen, es zu ersetzen?
Wenn Sie Hilfe beim Aufsetzen eines Mirrors oder eines Prozesses für Notfall-Builds möchten, teilen unsere Ingenieure gern, was funktioniert. Mit einem Ingenieur sprechen
Related
- /what-we-do/operations/package-builds-mirror/
- /what-we-do/operations/emergency-vulnerability-response/
- /what-we-do/data-web/php-upgrades-security-patching/
Veröffentlicht am 8. September 2026.
Alle Notizen aus der Praxis