senn-techsenn-tech
Infrastruktur
Infrastruktur2026-09-18· Von Franz Senn

Ein Host mit apt-Exit 100 stoppte die Patch-Runde der ganzen Flotte

Der Bericht endete mit failed. Das ist zuerst eine gute Nachricht: Der Lauf hat ein Ergebnis gemeldet. Die schlechte Nachricht steht hinter dieser Zeile. Ein Datei-Host hielt in der Nacht des 16. September 2026 apt-get mit Exit-Code 100 auf, 19 Pakete waren offen, davon fünf Sicherheitsupdates. Der Runner nahm das als Abbruch der ganzen Runde, nicht als Antwort für diesen einen Host. Jeder Host hinter ihm bekam an dem Abend weder Patches noch eine CVE-Prüfung. Eine Warteschlange, deren Fehlermodus „der Rest läuft nie" heißt, ist keine Warteschlange. Sie ist eine versteckte Abhängigkeit.

Eine Queue, ein Abbruch, nichts dahinterHost 1gepatcht, CVE-Check okDatei-Hostapt-get exit 100Host 3 bis Nkein Patch, kein CVE-CheckBerichtfailed
Der Abbruch sitzt in der Mitte der Liste. Alles dahinten ist nicht versucht und gescheitert, sondern nie versucht. (Quelle: Eigene Messung, Nachtläufe 16. und 17. September 2026)

Was in der Nacht passierte

Der Nightly-Runner arbeitet die Flotte Host für Host ab, in fester Reihenfolge, und tut dabei zwei Dinge: patchen und CVEs prüfen. Die Reihenfolge ist kein Selbstzweck. Sie hält die Datenbank-Hosts am Anfang, wo ein Fehler am teuersten ist. Diese Entscheidung bleibt.

Aufgeschrieben hat niemand den zweiten Zweig. apt-get beendet sich mit 100, wenn es nicht durchkommt, so steht es in der Manpage. Ein Fremddepot hielt zwei Pakete zurück, der Runner bekam Exit 100 und machte daraus einen harten Abbruch. 19 Pakete blieben liegen, davon fünf mit Sicherheitsbezug. Dahinter: nichts. Kein Patch, kein Scan, keine Zeile „hier wurde gar nicht begonnen". Am Morgen stand failed im Bericht, und für das System war die Sache erledigt.

Erfolg und ungepatcht in einer Minute

Am 17. September haben wir nachgestellt, dabei kam der zweite Befund heraus. Ein manueller Einzellauf auf demselben Host, angesetzt beim Schreiben einer Betriebsnotiz, endete mit ok. apt meldete im selben Atemzug weiterhin 14 Pakete als „not upgraded". Erfolg und ungepatcht, eine Minute auseinander. Der Lock (flock) schützt nur den Wrapper des Nachtlaufs; ein direkter Aufruf läuft daran vorbei.

Vier Befehle aus diesem Fenster, erwartetes Ergebnis gegen reale Konsequenz:

BefehlErwartetes ErgebnisReale Konsequenz
apt-get im NachtlaufErgebnis für diesen Host, Rest läuft weiterExit 100, 19 Pakete offen, Rest nie gestartet
Manueller Einzellauf auf demselben Hostok oder failed, beides belastbarok gemeldet, während apt 14 Pakete als „not upgraded" zählt
ssh mit StrictHostKeyChecking=accept-newneue Key annehmen, geänderte Key meldenAbbruch im ssh-Aufruf, Host ohne Zeile, 13 Läufe blind
git push mit Token in der BefehlszeileUpdate läuft, Zugang bleibt privatToken stand in einer Aufzeichnung vom Juni, nach Rotation ungültig

Das Muster ist nicht Nachlässigkeit, sondern die Lücke zwischen dem, was ein Befehl zurückgibt, und dem, was wir daraus lesen. Ein Zugang in einer Befehlszeile landet in jeder Aufzeichnung, die diese Zeile mitschreibt.

Markenzeichen von Proxmox
Geprüft wird eine Flotte, nicht ein einzelner Host. Ein fehlender Eintrag fällt in so einer Liste nicht als Fehler auf, er fehlt einfach. (Quelle: Proxmox VE)

Fehlend ist schlimmer als rot

Der dritte Fund ist stiller und unangenehmer. Der CVE-Watcher führt eine eigene Pin-Datei für Hostschlüssel, unabhängig von unserer ssh-Config, und läuft mit StrictHostKeyChecking=accept-new. Eine neue Key nimmt er kommentarlos. Eine geänderte Key ist ein harter Abbruch, und weil er im ssh-Aufruf passiert, wird daraus kein roter Eintrag: Der Host fehlt. Ein Produktionsknoten war dreizehn Läufe in Folge blind, bei ruhigen Dashboards.

Dazu unsere Vorgeschichte: 34 Maschinen teilen sich einen Hostschlüssel aus einem Golden Template. Eine geänderte Key ist bei uns Routine, kein Angriff. Ein Monitoring, das diesen Normalfall nicht aushält, meldet keine Sicherheit, es schaltet sich selbst ab. Aufräumen half auch nicht: Unsere Config zu bereinigen genügte nicht, weil der Job eine zweite Pin-Datei liest, und es gibt eine dritte, versionierte Kopie. Werkzeuge mit eigener known_hosts müssen im Inventar stehen, sonst beginnt die Reparatur jede Woche von vorn.

Das ist die Lektion aus unserem DNS-SERVFAIL-Monitoring. Dort stand die Prüfung auf Grün, weil sie nur Erreichbarkeit maß und nicht die Auflösung. Hier verschwindet ein Host, weil die Prüfung nicht sagen kann, dass sie selbst nicht gelaufen ist. Eine Prüfung, die „heute habe ich nicht stattgefunden" nicht formulieren kann, ist Theater. Die Frage „hat jeder Host heute einen Eintrag bekommen?" ist deshalb eine eigene Kennzahl, pro Host, als Zeitstempel, nicht als Aggregat. Ein Summenwert über eine Flotte unterscheidet den Ausfall des Prüfers nicht von einem ruhigen Abend.

Unsere Entscheidung: fail-open für die Flotte

Wir haben den Fehlerfall beschlossen, statt ihn weiterzuverwalten. Fail-open für die Flotte, fail-stop pro Host. Das apt-Problem eines einzelnen Hosts darf nicht noch einmal mehr als dreißig Hosts ihre Patch-Nacht kosten. Ein Scheitern ist kein Abbruch mehr, sondern eine eigene Zeile mit eigenem Alarm: Host, Exit-Code, offene Pakete, Zeitpunkt. Die Reihenfolge bleibt begründet. Nur ihr Ende ist jetzt ein Normalfall.

Wer das nachbaut, braucht vier Zeilen; die stehen an einem Abend:

  1. Erwartete Hosts gegen gelieferte Zeilen. Die Liste ist bekannt, der Bericht bekommt pro Host eine Zeile, auch bei Auslassung. Melden Sie die Differenz, nicht den Aggregatwert.
  2. Host-Fehler als Zeile, nicht als Abbruch. Der Exit-Code gehört in den Bericht, die Schleife läuft weiter. Ein Alarm pro Scheitern, nicht einer pro Nacht.
  3. Zeitstempel der letzten erfolgreichen Prüfung pro Host. Ein fehlender Eintrag wird sichtbar, ohne dass jemand den Bericht lesen muss. Das ist die Antwort auf dreizehn blinde Läufe.
  4. Kein Werkzeug ohne Versionsnummer im Image-Tag. Läuft ein Patchwerkzeug in einem Container mit mutablem Tag, ist „seid ihr gepatcht?" nicht mehr beantwortbar, weil der Tag die Antwort nicht trägt. Für Patch-Management im KMU haben wir das aufgeschrieben, für die Werkzeuge selbst nie angewendet.

Punkt 4 zahlt am meisten: eine Tag-Änderung, und eine Frage, die im Audit sonst niemand beantwortet.

Prozessdoku ist kein Monitoring

Jetzt die unbequeme Seite. Unsere Flotte hat einen dokumentierten Patch-Prozess mit zwölf Schritten, inklusive Wartungsfenster. Er hat trotzdem eine Nacht hervorgebracht, in der ein Sicherheitsupdate auf dreißig Rechnern lag, während der Bericht failed schrieb und ihn niemand las. Zwölf Schritte auf Papier sind eine Absicht, keine Überwachung.

Dazu der vierte Befund: Die Plandatei des Nachtlaufs wird aus der Shell-History erzeugt, und ihre Befehle sind über die Monate von dem abgedriftet, was tatsächlich gebraucht wird. Wir vertrauen den Zahlen aus den Vorprüfungen inzwischen mehr als dem Text des Plans. Ein Plan, den niemand gegenmisst, ist eine Erinnerung.

Der fünfte Punkt klingt nach Kosmetik und ist es nicht. Der Bericht färbt seine Badge nach Wörtern: „uebersprungen" und „nicht erreichbar" werden bewusst gelb, und ein ausgeschlossenes Wort ist der String „0 Befehle fehlgeschlagen". Wer eine Meldung umformuliert, ändert die farbliche Aussage des Berichts. Wortwahl ist tragende Konstruktion, keine Textpflege. Ein Alarm, der wartet, bis ihn jemand liest, ist keine Kontrolle. Deshalb blockt bei uns CrowdSec statt fail2ban von selbst, und bei Backups wird verifiziert und zurückgespielt statt geglaubt. Beim Patchen gaben wir uns mit failed zufrieden.

Stand: 17. September 2026, zweite Nacht. Der Datei-Host hat weiterhin offene Pakete, das Fremddepot hält sie zurück. Diesmal eine Zeile mit eigenem Alarm, kein Abbruch für alle dahinter.

Weiterführende Quellen

Fragen?
Warum stoppt ein einzelner Host die ganze Patch-Runde?+

Weil der Runner für den Fehlerfall keinen eigenen Zweig hat. Er arbeitet eine feste Reihenfolge ab und wertet einen Fehler-Exit-Code als Abbruch der Übung statt als Ergebnis für diesen einen Host. Der Pfad war nie falsch programmiert, er war nie beschlossen. Aufgeschrieben wurde die Reihenfolge, nicht das Verhalten beim Scheitern.

Was unterscheidet einen roten Host von einem fehlenden Host im Bericht?+

Ein roter Host erzeugt eine Reaktion, ein fehlender keine. Beim CVE-Watcher scheiterte der Lauf im ssh-Aufruf, dadurch erschien der Host nicht als Fehler, sondern gar nicht. Die Dashboards blieben ruhig, und ein Produktionsknoten war dreizehn Läufe lang blind. Rot ist eine Beschwerde, fehlend ist Entzug.

Woher wissen Sie, dass jeder Host wirklich geprüft wurde?+

Über zwei Kennzahlen, die nichts mit Patches zu tun haben: erwartete Hostanzahl gegen gelieferte Zeilen, und ein Zeitstempel der letzten erfolgreichen Prüfung pro Host. Gemeldet wird die Differenz, nicht der Aggregatwert. So sehen Sie den Ausfall des Prüfsystems und nicht nur die Ausfälle, die es meldet.