Zum Inhalt springen

Blog ·

Unprivilegiert wird gemessen, nicht gesetzt

Eine Containerwiederherstellung beginnt damit, die Konfiguration im Archiv zu lesen, denn der sichere Wert für ein Feld lässt sich nicht blind senden.

Von Provibr

Einen Container auf Proxmox wiederherzustellen ist derselbe API-Aufruf wie einen anzulegen. Man postet an den Container-Endpunkt auf einem Knoten, übergibt das Archiv und setzt das Feld, das aus dem Anlegen eine Wiederherstellung macht. Der Weg für die virtuelle Maschine hat dieses Feld nicht einmal: Dort ist das Archiv selbst die Wiederherstellung. Diese Symmetrie ist bequem und sie verbirgt eine Falle, denn eines der Felder in diesem Aufruf beschreibt eine Sicherheitseigenschaft, die im Archiv bereits einen Wert hat.

Senden Sie den sicheren Wert, machen Sie den Container möglicherweise kaputt. Lassen Sie das Feld weg, stellen Sie möglicherweise einen privilegierten Container in eine Flotte, in der es keinen geben soll. Der einzige richtige Zug ist, zuerst das Archiv zu lesen und dann nach dem zu handeln, was darin steht.

Zwei Endpunkte, die sich ähnlich sehen

Der Weg für die virtuelle Maschine und der für den Container unterscheiden sich an mehr Stellen, als der Name vermuten lässt:

Virtuelle MaschineContainer
EndpunktPOST /nodes/{node}/qemuPOST /nodes/{node}/lxc
Das Archivarchive=<volid>ostemplate=<volid> und restore=1
Der Namename=hostname=
Der Zielspeicher muss annehmenimagesrootdir
Vorgangsart in der Vorgangskennungqmrestorevzrestore

Zwei dieser Zeilen lassen sich auf eine Weise falsch machen, die einen verwirrenden Fehler erzeugt. Proxmox nennt ein Containerarchiv eine Betriebssystemvorlage, denn derselbe Parameter nimmt beides an, und bei einer virtuellen Maschine ist das Vorhandensein von archive selbst die Wiederherstellung, es gibt also kein eigenes Feld dafür. Und images und rootdir sind zwei verschiedene Inhaltsarten: Ein Speicher kann das eine ohne das andere anbieten, überall images zu verlangen lehnt also völlig brauchbaren Containerspeicher ab, während gar nicht zu prüfen dem Kunden einen Satz über Containerverzeichnisse in die Hand drückt, der ihm nichts sagt.

Welche der beiden Arten vorliegt, wird einmal festgelegt. Sie wird in dem Moment aus dem Dateinamen des Archivs gelesen, in dem das Archiv aufgelistet wird, bleibt beim Wiederherstellungspunkt und reist mit der Anweisung mit; der Agent wählt seinen Endpunkt nach diesem Wort und hat keinen Rückfallweg. Es muss in dieser Richtung laufen, denn ein 404 von Proxmox unterscheidet einen Gast der anderen Art nicht von einem Gast, den es nicht mehr gibt. Nach einem 404 den anderen Endpunkt zu versuchen ließe eine gelöschte virtuelle Maschine als Container ansprechen, und auf einem Cluster, auf dem diese Nummer inzwischen neu vergeben wurde, wird der falsche Gast angefasst.

Ein Feld wird überhaupt nie gesendet, und es heißt force. Dies ist die hinzufügende Wiederherstellung: Eine Maschine erscheint neben dem Original, und das Original läuft weiter. force ist das Feld, mit dem Proxmox einen bestehenden Gast überschreibt, es existiert auf beiden Endpunkten, und es gehört zur anderen Art Wiederherstellung, die eine eigene Nachricht, ein eigenes Recht und eine Bestätigung hat, die abgetippt werden muss. Es dauerhaft aus diesem Codeweg herauszulassen ist billiger, als daran zu denken, es nicht zu setzen.

Ein Feld wird immer gesendet, und es heißt unique. Ohne es erbt der wiederhergestellte Gast die Hardwareadressen der ursprünglichen Netzwerkkarten, und dass zwei Maschinen auf dieselbe Adresse antworten, ist ein Ausfall auf der Maschine, die Sie sorgsam nicht anfassen wollten.

Drei Ablehnungen, bevor irgendetwas geschrieben wird

Jede Vorprüfung gibt es, weil die Alternative ein Zitat von Proxmox ist, mit dem ein Kunde nichts anfangen kann. Das Archiv muss noch da sein, denn die Plattform wählt es aus einem Verzeichnis, das konstruktionsbedingt eine Beobachtung der Vergangenheit ist. Die Zielnummer muss frei sein, und frei muss frei auf dem Hypervisor bedeuten und nicht frei in unserer eigenen Verwaltung: Die Plattform vergibt innerhalb des Bereichs, den sie verwaltet; ein Gast, den jemand von Hand angelegt hat, ist deshalb vollkommen real und in jeder Aufzeichnung, die wir führen, vollkommen abwesend. Und der Zielspeicher muss die richtige Inhaltsart annehmen.

Bei einem Container gibt es eine vierte, und um die geht es in diesem Artikel.

Drei Dinge, die man mit einem privilegierten Archiv tun kann, und zwei sind still falsch

Unprivilegierte Container sind die sichere Voreinstellung, und die Plattform hat keine Möglichkeit, etwas anderes auszudrücken. Stellt sich also heraus, dass ein Archiv einen privilegierten Container enthält, hat der Agent genau drei Möglichkeiten.

Die erste ist, das Feld für unprivilegiert trotzdem zu senden. Proxmox legt dann eine Identitätsabbildung über das wiederhergestellte Dateisystem; die eigene Parameterbeschreibung sagt, dass das Feld nicht von Hand geändert werden soll. Die Wiederherstellung gelingt, der Vorgang meldet alles in Ordnung, und der Container funktioniert nicht.

Die zweite ist, das Feld wegzulassen. Proxmox nimmt dann den Wert aus dem Archiv, und ein privilegierter Container tritt der Flotte bei: einer, der sich den Kern des Hosts mit Root-Rechten teilt, und genau das soll die Richtlinie verhindern.

Die dritte ist abzulehnen, mit einem Satz, der sagt, was im Archiv steht. Das ist, was geschieht, und es geschieht, bevor irgendetwas geschrieben wird. Es wird überhaupt keine Anfrage zum Anlegen des Containers gesendet.

Die Konfiguration lesen, die im Archiv steckt

Die Messung ist ein Aufruf des Endpunkts, der die Konfiguration aus einem Archiv ausliest. Drei Einzelheiten sind wissenswert.

Die Antwort ist Text und kein JSON. Sie ist die Konfigurationsdatei des Containers, ein Schlüssel und ein Wert je Zeile, genau so, wie sie auf der Platte liegt, sie braucht also einen eigenen kleinen Parser neben dem, der das JSON der API verarbeitet.

Und die Abwesenheit des Schlüssels bedeutet das Gegenteil von dem, was Abwesenheit gewöhnlich bedeutet. Proxmox schreibt die Zeile für unprivilegiert nur dann, wenn sie wahr ist. Eine Konfiguration ohne sie beschreibt einen privilegierten Container. Jeder Leser, der „nicht gefunden“ als „unbekannt, wird schon passen“ behandelt, winkt genau den Fall durch, für den die Prüfung gebaut wurde, der Vergleich ist deshalb großzügig darin, was er als wahr annimmt, und lehnt alles andere ab.

Lässt sich die Konfiguration überhaupt nicht lesen, wird die Wiederherstellung ebenfalls abgelehnt, und das Zitat von Proxmox reist damit zurück. Das ist meist eine Rechtemeldung, denn der Ausleseendpunkt verlangt Backup-Rechte auf dem Gast und Zuteilungsrechte auf dem Backup-Speicher. Hier geschlossen zu scheitern hat einen echten Preis: Ein API-Token, dem ein Recht fehlt, kann keinen Container wiederherstellen, und der Grund dafür ist eine Prüfung und keine Beschränkung. Es ist trotzdem die richtige Seite zum Scheitern, denn die offene Frage dahinter hat zwei still falsche Antworten.

Derselbe Lesevorgang beantwortet eine zweite Frage

Die Konfiguration im Archiv sagt außerdem, welche Mountpoints Teil davon waren, und die Regeln von Proxmox sind dort nicht die, die man erwartet:

Was die Konfiguration sagtIm Archiv?Warum
Das Root-DateisystemImmerEs hat überhaupt keine Backup-Option; das Feld steht nicht in seinem Schema
Ein verwaltetes Volume mit eingeschalteter Backup-OptionJaAusdrücklich aktiviert
Ein verwaltetes Volume ohne sieNeinDie Option muss eingeschaltet sein, damit ein Mountpoint aufgenommen wird
Ein Verzeichnis vom HostNeinDie Inhalte von Bind-Mountpoints werden nicht gesichert
Ein Blockgerät vom HostNeinDasselbe, für Device-Mountpoints

Die dritte Zeile ist die gefährliche. Bei der Platte einer virtuellen Maschine ist Ausschluss die Ausnahme und Einschluss die Voreinstellung; bei einem Container-Mountpoint ist es umgekehrt. Das verkehrt herum zu haben erzeugt eine Abdeckungstabelle, die über die häufigste Konfiguration überhaupt „im Backup“ sagt, und das ist schlimmer als gar keine Tabelle, denn es ist ein Versprechen.

Snapshot-Abschnitte in der Konfiguration werden übersprungen. Ein Container mit fünf Snapshots steuerte sonst fünf Fassungen desselben Root-Dateisystems bei, jede aus einem beliebigen Moment.

Ein Aufruf bedient beide Fragen statt zwei, denn zwei Aufrufe könnten zwei verschiedene Archive beschreiben. Und das Urteil wird auf der Plattform berechnet und nicht vom Agenten: Der Agent meldet die Zeilen so, wie er sie vorgefunden hat, und es gibt kein Feld, in dem er vollständige Abdeckung behaupten könnte, selbst wenn er wollte. Nachweislich außerhalb des Backups schlägt nicht gemessen, ein Container mit einem Bind-Mount und einer unlesbaren Zeile ist also teilweise und nicht unbekannt, und die unlesbare Zeile behält ihr eigenes Wort in der Tabelle.

Es gibt ein Feld, das sagt, ob die Konfiguration überhaupt gelesen wurde, und es ist keine Zierde. Ein Agent, der sie nicht lesen konnte, gibt eine leere Liste zurück, und eine leere Liste ist von einem Container ohne Mountpoints nicht zu unterscheiden, außer dass es den zweiten nicht gibt.

Wenn niemand sagen kann, was geschehen ist

Eine Wiederherstellung, die beginnt und dann ihre Antwort verliert, weil der Agent neu gestartet ist oder die Verbindung abgerissen ist, darf nicht erraten werden. Es gibt drei Beweisquellen: das Archivverzeichnis, die Maschine, die erscheinen sollte, und den Status des Proxmox-Vorgangs. Nur die dritte kann einen Fehlschlag feststellen; die anderen beiden können nur einen Erfolg bestätigen, denn ein fehlendes Archiv und eine fehlende Maschine passen beide genauso gut zu einer Wiederherstellung, die noch läuft.

Diese Überlegung geschieht auf der Plattform. Das Nachschlagen des Vorgangs durch den Agenten trägt nur das Zitat von Proxmox zurück und zieht keinen eigenen Schluss, denn zu entscheiden, was die drei Quellen zusammen ergeben, braucht den Lauf und die Absicht, aus der er entstanden ist, nebeneinander, und nur die Plattform hat beides.

Nichts wird ewig wiederholt. Es gibt einen Zähler mit einer Obergrenze von acht Versuchen, und bei einem Standardabstand von sechs Stunden ergibt das etwa zwei Tage. Versuche, bei denen der Vorgang nachweislich noch lief, zählen nicht dagegen, denn ein großes Backup über ein langsames Netz darf eine Nacht dauern. Läuft der Zähler ab, wird der Lauf unbekannt und nie fehlgeschlagen. Fehlgeschlagen wäre eine Behauptung, die niemand überprüft hat, und abgeschlossen behauptete ein Archiv, das niemand gesehen hat.

Was wir aufschreiben würden

  1. Senden Sie keinen Wert für eine Eigenschaft, die in der Eingabe bereits vorhanden ist. Lesen Sie sie, und bestätigen Sie sie dann oder lehnen Sie ab.
  2. Finden Sie heraus, was ein fehlender Schlüssel bedeutet, bevor Sie den Parser schreiben. Hier bedeutet er den unsicheren Wert, also das Gegenteil der üblichen Gewohnheit.
  3. Scheitern Sie geschlossen, wenn die Messung nicht verfügbar ist, und sagen Sie laut, was das kostet, denn jemand wird darauf stoßen.
  4. Lassen Sie einen Lesevorgang jede Frage beantworten, die er beantworten kann. Zwei Aufrufe können zwei verschiedene Zustände beschreiben.
  5. Legen Sie das Urteil dorthin, wo der Zusammenhang ist. Ein Beobachter, der kein Urteil ausdrücken kann, kann auch keines falsch treffen.
  6. Geben Sie einer erschöpften Wiederholung ein eigenes Endwort. Unbekannt ist ehrlich; fehlgeschlagen und abgeschlossen sind beides Behauptungen, die niemand aufgestellt hat.

Zur Klarheit darüber, was das ist: Kundenbackups liegen hinter einem Rollout-Schalter, der standardmäßig aus ist, nichts davon ist also heute käuflich. Und die wichtige Grenze der Belege: Es wurde kein echtes Backup und keine echte Wiederherstellung gegen einen laufenden Hypervisor gefahren. Das Parameterverhalten oben wurde aus der eigenen Quelle und Dokumentation von Proxmox gelesen, und der Code wurde gegen einen Ersatzserver ausgeübt, der dieselben Endpunkte beantwortet. Der Ausleseaufruf wurde außerdem nicht gegen ein Archiv auf einem eigenen Backupserver versucht, nur gegen dateibasierten Speicher.

Aus der Backup-Arbeit bei Provibr. Warum ein Archiv, das niemand wiederhergestellt hat, noch kein Backup ist, steht in ein nie wiederhergestelltes Backup, was die verschiedenen Backup-Modi tatsächlich garantieren, steht in was die vzdump-Modi von Proxmox garantieren, und warum die Neuinstallation eines Containers ein Zerstören und ein Neubauen ist, steht in ein Container wird ersetzt.

Fangen Sie mit einem Host und einem Agenten an

Konto erstellen, den Agenten mit einem einzigen Befehl installieren und Ihren ersten Proxmox-Host verbinden. Die Testphase läuft 14 Tage und fragt nicht nach Zahlungsdaten.