Naar de inhoud

Blog ·

Unprivileged is een meting, geen instelling

Een containerbackup terugzetten begint met het lezen van de configuratie in het archief, want de veilige waarde van één vlag is niet blind mee te sturen.

Door Provibr

Een container terugzetten op Proxmox is dezelfde API-aanroep als er een aanmaken. Je post naar het containerendpoint op een node, geeft het archief mee, en voegt de vlag toe die van aanmaken een terugzetactie maakt. Het pad voor een virtuele machine heeft die vlag niet eens: daar is het archief zelf de terugzetactie. Die symmetrie is handig en ze verbergt een val, want een van de velden in die aanroep beschrijft een beveiligingseigenschap die binnen in het archief al een waarde heeft.

Stuur je de veilige waarde mee, dan kun je de container kapotmaken. Laat je het veld weg, dan zet je misschien een privileged container in een vloot die er geen hoort te hebben. De enige juiste zet is eerst het archief lezen en dan handelen naar wat erin staat.

Twee endpoints die op elkaar lijken

Het pad voor een virtuele machine en dat voor een container verschillen op meer plaatsen dan de naam doet vermoeden:

Virtuele machineContainer
EndpointPOST /nodes/{node}/qemuPOST /nodes/{node}/lxc
Het archiefarchive=<volid>ostemplate=<volid> plus restore=1
De naamname=hostname=
De doelopslag moet accepterenimagesrootdir
Taaksoort in de taakidentificatieqmrestorevzrestore

Twee van die regels zijn gemakkelijk verkeerd te doen op een manier die een verwarrende fout oplevert. Proxmox noemt een containerarchief een besturingssysteemsjabloon, omdat dezelfde parameter allebei accepteert, en bij een virtuele machine is de aanwezigheid van archive zelf al de terugzetactie, dus daar bestaat geen aparte vlag voor. En images en rootdir zijn twee verschillende inhoudssoorten: een opslag kan de ene aanbieden zonder de andere, dus overal images eisen wijst prima containeropslag af, terwijl helemaal niet controleren de klant een zin over containermappen in handen geeft die hem niets zegt.

Om welke van de twee soorten het gaat wordt één keer vastgesteld. Die wordt van de bestandsnaam van het archief gelezen op het moment dat het archief in de lijst verschijnt, bewaard bij het terugzetpunt, en meegestuurd met de instructie; de agent kiest zijn endpoint aan de hand van dat woord en heeft geen terugvalpad. Het moet die kant op werken, want een 404 van Proxmox onderscheidt een gast van de andere soort niet van een gast die niet meer bestaat. Het andere endpoint proberen na een 404 zou een verwijderde virtuele machine als container laten aanspreken, en op een cluster waar dat nummer intussen opnieuw is uitgegeven wordt dan de verkeerde gast aangeraakt.

Eén vlag wordt helemaal nooit meegestuurd, en die heet force. Dit is de toevoegende terugzetactie: er verschijnt een machine naast het origineel en het origineel blijft draaien. force is de vlag waarmee Proxmox een bestaande gast overschrijft, hij bestaat op beide endpoints, en hij hoort bij de andere soort terugzetactie, die zijn eigen bericht, zijn eigen recht en een getypte bevestiging heeft. Hem permanent uit dit codepad houden is goedkoper dan onthouden dat je hem niet moet zetten.

Eén vlag wordt altijd meegestuurd, en die heet unique. Zonder die vlag erft de teruggezette gast de hardware-adressen van de netwerkkaarten van het origineel, en twee machines die op hetzelfde adres antwoorden zijn een storing op precies de machine die je zorgvuldig niet wilde aanraken.

Drie weigeringen voordat er iets geschreven is

Elke preflight bestaat omdat het alternatief een citaat van Proxmox is waar een klant niets mee kan. Het archief moet er nog zijn, want het platform kiest het uit een index die per constructie een waarneming van het verleden is. Het doelnummer moet vrij zijn, en vrij moet vrij op de hypervisor betekenen en niet vrij in onze eigen administratie: het platform deelt uit binnen het bereik dat het beheert, dus een gast die iemand met de hand heeft aangemaakt is volstrekt echt en volstrekt afwezig in elke administratie die wij bijhouden. En de doelopslag moet de juiste inhoudssoort accepteren.

Voor een container is er een vierde, en dat is degene waar dit artikel over gaat.

Drie dingen die je met een privileged archief kunt doen, en twee zijn stil verkeerd

Unprivileged containers zijn de veilige standaard, en het platform heeft geen manier om iets anders uit te drukken. Blijkt een archief dus een privileged container te bevatten, dan heeft de agent precies drie mogelijkheden.

De eerste is de unprivileged-vlag toch meesturen. Proxmox past dan een identiteitsmapping toe over het teruggezette filesystem; zijn eigen parameterbeschrijving zegt dat het veld niet met de hand gewijzigd hoort te worden. Het terugzetten slaagt, de taak meldt dat het goed ging, en de container werkt niet.

De tweede is het veld weglaten. Proxmox neemt de waarde dan uit het archief, en er komt een privileged container in de vloot: een die de kernel van de host deelt met rootrechten, en dat is precies waar het beleid voor bestaat.

De derde is weigeren, met een zin die zegt wat er in het archief zit. Dat is wat er gebeurt, en het gebeurt voordat er iets geschreven is. Er wordt helemaal geen verzoek verstuurd om de container aan te maken.

De configuratie lezen die in het archief zit

De meting is één aanroep naar het extract-endpoint van het archief. Drie details zijn het weten waard.

Het antwoord is tekst en geen JSON. Het is het configuratiebestand van de container, één sleutel met waarde per regel, precies zoals het op schijf staat, dus het heeft zijn eigen kleine parser nodig naast degene die de JSON van de API afhandelt.

En de afwezigheid van de sleutel betekent het tegenovergestelde van wat afwezigheid gewoonlijk betekent. Proxmox schrijft de unprivileged-regel alleen weg wanneer die waar is. Een configuratie zonder die regel beschrijft een privileged container. Elke lezer die "niet gevonden" opvat als "onbekend, waarschijnlijk in orde" laat precies het geval door waarvoor de controle gebouwd is, dus de vergelijking is ruimhartig in wat ze als waar accepteert en weigert al het andere.

Is de configuratie helemaal niet te lezen, dan wordt het terugzetten eveneens geweigerd, en reist het citaat van Proxmox mee terug. Dat is meestal een rechtenmelding, want het extract-endpoint wil backuprechten op de gast en toewijzingsrechten op de backupopslag. Hier dichtvallen kost werkelijk iets: een API-token waaraan één recht ontbreekt kan geen container terugzetten, en de reden is een controle en geen beperking. Het blijft de juiste kant om op te falen, want de open vraag erachter heeft twee stil verkeerde antwoorden.

Dezelfde leesactie beantwoordt een tweede vraag

De configuratie in het archief zegt ook welke mount points er deel van uitmaakten, en de regels van Proxmox daarvoor zijn niet de regels die mensen verwachten:

Wat de configuratie zegtZit het in het archief?Waarom
Het rootfilesystemAltijdHet heeft helemaal geen backupoptie; het veld staat niet in zijn schema
Een beheerd volume met de backupoptie aanJaUitdrukkelijk aangezet
Een beheerd volume zonder die optieNeeDe optie moet aan staan wil een mount point meegenomen worden
Een map van de hostNeeDe inhoud van bind mount points wordt niet meegebackupt
Een blokapparaat van de hostNeeHetzelfde, voor device mount points

De derde regel is de gevaarlijke. Bij een schijf van een virtuele machine is uitgesloten de uitzondering en meegenomen de standaard; bij een mount point van een container is het andersom. Dat omdraaien levert een dekkingstabel op die "in de backup" zegt over de meest voorkomende configuratie die er is, en dat is erger dan helemaal geen tabel, want het is een belofte.

Snapshotsecties in de configuratie worden overgeslagen. Een container met vijf snapshots zou anders vijf versies van hetzelfde rootfilesystem bijdragen, elk uit een willekeurig moment.

Eén aanroep bedient beide vragen in plaats van twee, want twee aanroepen zouden twee verschillende archieven kunnen beschrijven. En het oordeel wordt op het platform berekend en niet door de agent: de agent meldt de regels zoals hij ze aantrof, en er is geen veld waarin hij volledige dekking zou kunnen beweren, ook al zou hij willen. Aantoonbaar buiten de backup wint van niet gemeten, dus een container met één bind mount en één onleesbare regel is gedeeltelijk en niet onbekend, en de onleesbare regel houdt zijn eigen woord in de tabel.

Er is een vlag die zegt of de configuratie überhaupt gelezen is, en die is geen versiering. Een agent die hem niet kon lezen geeft een lege lijst terug, en een lege lijst is niet te onderscheiden van een container zonder mount points, behalve dat het tweede niet bestaat.

Wanneer niemand kan zeggen wat er gebeurd is

Een terugzetactie die begint en dan zijn antwoord kwijtraakt, doordat de agent opnieuw startte of de verbinding wegviel, mag niet geraden worden. Er zijn drie bewijsbronnen: de archiefindex, de machine die had moeten verschijnen, en de status van de taak in Proxmox. Alleen de derde kan een mislukking vaststellen; de andere twee kunnen alleen een succes bevestigen, want een ontbrekend archief en een ontbrekende machine passen allebei even goed bij een terugzetactie die nog loopt.

Die gevolgtrekking gebeurt op het platform. De taakopzoeking van de agent draagt alleen het citaat van Proxmox terug en trekt zelf geen enkele conclusie, want beslissen wat de drie bronnen bij elkaar betekenen vraagt om de run en de bedoeling waarmee hij begon naast elkaar, en alleen het platform heeft ze allebei.

Niets wordt eindeloos opnieuw geprobeerd. Er is een teller met een plafond van acht pogingen, en bij het standaardinterval van zes uur komt dat neer op ongeveer twee dagen. Pogingen waarbij de taak aantoonbaar nog liep tellen niet mee, want een grote backup over een traag netwerk mag een nacht duren. Loopt de teller af, dan wordt de run onbekend, en nooit mislukt. Mislukt zou een bewering zijn die niemand geverifieerd heeft, en voltooid zou een archief beweren dat niemand gezien heeft.

Wat we zouden opschrijven

  1. Stuur geen waarde mee voor een eigenschap die al in de invoer bestaat. Lees hem, en bevestig hem daarna of weiger.
  2. Zoek uit wat een ontbrekende sleutel betekent voordat je de parser schrijft. Hier betekent hij de onveilige waarde, en dat is het tegenovergestelde van de gebruikelijke afspraak.
  3. Val dicht wanneer de meting niet beschikbaar is, en zeg hardop wat dat kost, want iemand loopt ertegenaan.
  4. Laat één leesactie elke vraag beantwoorden die ze kan beantwoorden. Twee aanroepen kunnen twee verschillende toestanden beschrijven.
  5. Leg het oordeel waar de context is. Een waarnemer die geen oordeel kan uitdrukken kan er ook geen verkeerd geven.
  6. Geef een uitgeputte herhaalpoging zijn eigen eindwoord. Onbekend is eerlijk; mislukt en voltooid zijn allebei beweringen die niemand gedaan heeft.

Voor de duidelijkheid over wat dit is: klantbackups zitten achter een uitrolvlag die standaard uit staat, dus niets hiervan is vandaag te koop. En de belangrijke grens aan het bewijs: er is geen echte backup of terugzetactie tegen een draaiende hypervisor gedraaid. Het parametergedrag hierboven is uit de eigen bron en documentatie van Proxmox gelezen, en de code is beproefd tegen een vervangende server die dezelfde endpoints beantwoordt. De extract-aanroep is bovendien niet geprobeerd tegen een archief op een aparte backupserver, alleen tegen bestandsgebaseerde opslag.

Uit het backupwerk aan Provibr. Waarom een archief dat niemand heeft teruggezet nog geen backup is staat in een backup die nooit is teruggezet, wat de verschillende backupmodi werkelijk garanderen staat in vzdump-modi in Proxmox, en waarom een container opnieuw installeren neerkomt op vernietigen en opnieuw opbouwen staat in een container opnieuw installeren is vervangen.

Begin met één host en één agent

Maak een account aan, installeer de agent met één commando en koppel je eerste Proxmox-host. De proefperiode loopt 14 dagen en vraagt geen betaalgegevens.