Zum Inhalt springen

← Alle Notizen

Ein Spiegel, der nur so tat — von apt-mirror zu aptly

Der eigene Paketspiegel meldete jede Nacht Erfolg und lieferte trotzdem kaputte Daten. Wie ich die Fehler gefunden habe und warum am Ende aptly übernommen hat.

  • Debian
  • apt-mirror
  • aptly
  • Icinga

Alle Maschinen meiner Umgebung holen ihre Pakete nicht aus dem Internet, sondern von mirror00: Debian, die Sicherheitsupdates und rund dreißig weitere Quellen von GitLab über Grafana bis Bareos. Das spart Bandbreite, macht Installationen reproduzierbar und lässt Hosts ohne Internetzugang trotzdem aktualisieren. Signiert wird mit einem eigenen Schlüssel, den jeder Host kennt.

Gespiegelt hat lange apt-mirror, gesteuert von einem eigenen Puppet-Modul. Der Cronjob lief jede Nacht durch, ohne Fehler. Im August 2026 habe ich genauer hingesehen.

Was alles nicht stimmte

Ein Lauf, der zu schnell fertig war. Am 21. August kündigte apt-mirror mehrere hundert GiB zum Herunterladen an — und war nach Sekunden fertig. Kein Fehler, kein Abbruch, einfach nichts getan. Seitdem bricht der Lauf mit Fehler ab, wenn er weniger als zwei Minuten braucht, obwohl Hunderte GiB angekündigt waren. Eine Laufzeit kann ein Symptom sein.

Ein Index, der frisch aussah und alt war. Bei InfluxDB passten Suite und Komponente im Spiegel nicht mehr zu dem, was die Hosts in ihren Paketquellen erwarteten. Die Hosts lasen weiter einen Index, der nicht mehr aktualisiert, aber jede Nacht neu signiert wurde. Für apt sah alles gültig aus. Es kamen nur keine Updates mehr.

Dateien, die nie heil wurden. apt-mirror lädt mit wget --continue. Antwortet der Server mit 416 Range Not Satisfiable, hält wget die Datei für vollständig und lässt das Bruchstück liegen. Dieselben fünf Dateien hatten vor und nach einem vollen Lauf über 400 GiB dieselbe falsche Größe.

Ein Wettlauf mit dem Upstream. Veröffentlicht ein Anbieter neue Indizes genau zwischen dem Abruf von Release und Packages, signierte der Spiegel eine Release-Datei, deren Prüfsummen nicht zu den Indizes passten. Die Hosts brachen ab mit unerwartete Größe. Am 25. August traf das 37 Indizes, in der Nacht darauf 14 andere. Seitdem rechnet der Spiegel die Prüfsummen selbst, nur für Dateien, die tatsächlich auf der Platte liegen.

Eine Prüfung, die das Falsche prüfte. Die Kontrolle nach dem Lauf meldete 158 204 Pakete vollständig — während apt update auf jedem Host scheiterte. Sie verglich Indizes mit Paketen, aber nicht Release mit den Indizes. Genau dort lag der Fehler.

GitLab und ein Dateiname für zwei Dateien. GitLab baut sein Paket für Debian 12 und 13 getrennt, legt aber beide unter denselben Pfad mit demselben Namen. Auf einer Platte kann nur eine der beiden liegen. apt-mirror stellte jede Nacht gut 325 Pakete erneut in die Warteschlange, und für eine der beiden Debian-Versionen passten die Prüfsummen nie.

Eine Vorabversion, die verschwand. Bei Bareos zeigt die Quelle current immer genau eine Vorabversion. Am 25. August sprang sie von pre20 auf pre28 — und jeder Host, der noch pre20 erwartete, bekam sein Paket nicht mehr. Ein reiner Spiegel kann nichts festhalten, was der Anbieter gelöscht hat.

Warum aptly

Mehrere der Fehler ließen sich in apt-mirror flicken, zwei nicht:

  • Der Pool von aptly ist inhaltsadressiert. Zwei Dateien mit gleichem Namen und verschiedenem Inhalt liegen nebeneinander. Damit kann GitLab für beide Debian-Versionen gespiegelt werden.
  • aptly arbeitet mit Snapshots. Ein Stand bleibt erhalten, bis ich umschalte — auch wenn der Anbieter ihn längst ersetzt hat. Fünf Snapshots je Quelle halte ich rollierend vor; zurück geht es mit einem Befehl.

Dazu kam: apt-mirror prüft die Signaturen der Quellen nicht. Ein manipulierter Index wäre mit meinem eigenen Schlüssel neu signiert an die Flotte gegangen. aptly kann das prüfen — bei den meisten Quellen fehlt mir dafür allerdings noch der Schlüssel des Anbieters. Das ist ein offener Punkt, kein gelöster.

Die Umstellung

aptly bekam eine eigene Platte mit 1 TB. Beide Spiegel liefen eine Weile parallel; mit knapp 950 GB im alten und gut 950 GB frei im neuen Spiegel ging das nur, solange die großen Quellen nicht doppelt lagen. Die Reihenfolge war deshalb: erst die kleinen, Debian zuletzt.

Wichtig war, dass sich für die Hosts nichts ändert. Die Veröffentlichungspfade in aptly entsprechen den alten Pfaden, der Signaturschlüssel ist derselbe. Am 3. September hat aptly den Webserver des Spiegels übernommen; seitdem zeigt er auf die Veröffentlichungen von aptly, und die Adressen sind dieselben wie vorher. Angepasst werden mussten nur drei Quellen, bei denen sich die Struktur geändert hat — Bareos, die Debian-Sicherheitsupdates und die Quellen von GitLab und Docker, die jetzt je Debian-Version getrennt liegen.

Unterwegs gab es die üblichen Überraschungen:

  • architectures: all heißt bei aptly nicht „alle Architekturen", sondern die Architektur all — 22 von 32 Quellen brachen damit ab.
  • aptly schreibt ein eigenes Label in die Release-Datei. Ändert es sich, verweigert apt das Update. Jede Quelle trägt deshalb Label und Origin des Anbieters.
  • Die Inhaltsverzeichnisse (Contents) zu erzeugen, dauerte rund sechs Stunden je Lauf. Sie sind abgeschaltet; apt-file funktioniert gegen den Spiegel dafür nicht.

Seit dem 9. Oktober liegt auch der Netzinstaller für Debian im Spiegel. Neue Maschinen installiert Foreman damit vollständig aus der eigenen Quelle.

Überwachung

Die wichtigste Lehre: „Der Cronjob lief ohne Fehler" ist keine Aussage über den Spiegel. Die Prüfung in Icinga liest heute eine Statusdatei, die der Abgleich selbst schreibt, und meldet sich, wenn ein Lauf scheitert, zu lange her ist oder weniger Veröffentlichungen vorliegen als erwartet. Diese Zahl — derzeit 34 — hat schon am ersten Tag zwei fehlende Veröffentlichungen gefunden. Für die beiden Quellen, die ich bewusst von Hand umschalte, warnt eine eigene Prüfung, wenn der Stand älter als 30 Tage ist.

Fragen oder Anmerkungen? Gern über das Kontaktformular.