Naar de inhoud

Blog ·

Waar de inloggegevens van je panelen thuishoren

Een paneel dat je hypervisor- en paneelinloggegevens bewaart is het waardevolste doelwit in je stack. Dit is het alternatief, en wat het niet oplost.

Door Provibr

Elk gehost controlepaneel voor serverautomatisering vraagt je in zijn installatiewizard hetzelfde: het adres van je hypervisor, een API-token, de rootgegevens van je webhostingpaneel. Daarna slaat het ze op, want het heeft ze bij elk verzoek nodig.

Het is redelijk dat de software dat wil, en het is oprecht ongemakkelijk dat je ermee hebt ingestemd. Je hebt zojuist de database van een derde partij de mogelijkheid gegeven om elke machine te verwijderen die je bezit. Niet door een bug en niet door kwade opzet: dat is het normale, gedocumenteerde, werkende gedrag van het product.

Het is de moeite waard om precies te zijn over wat de alternatieven je werkelijk opleveren, want "we versleutelen ze in rust" is het antwoord dat iedereen geeft en het betekent op zichzelf bijna niets.

Versleuteld in rust, ontsleuteld door wie

Als een SaaS je hypervisortoken versleuteld opslaat, moet de sleutel ergens staan waar diezelfde SaaS bij kan, want hij moet het token namens jou gebruiken terwijl jij slaapt. Versleuteling in rust beschermt tegen een gestolen schijf en een gelekte backup. Het beschermt niet tegen het ding waar je je werkelijk zorgen over maakt, en dat is het platform zelf dat gecompromitteerd raakt.

Dat is geen argument tegen versleutelen in rust. Het is een argument dat de vraag "waar staat de sleutel" de enige vraag is, en dat een control plane dat kan ontsleutelen een control plane is dat ertoe gebracht kan worden om te ontsleutelen.

Waar het geheim staatWie het kan ontsleutelenWat een inbraak op het platform oplevert
Leesbaar in de database van het platformHet platformDe hypervisor van elke klant
Daar versleuteld, sleutel ook daarHet platformHetzelfde, één stap later
Versleuteld op de eigen host van de klantDie host, en alleen die hostToegang tot commando's, en geen inloggegevens

Het structurele alternatief is de derde rij: het geheim helemaal niet hebben. Dat klinkt te gemakkelijk, tot je kijkt wat het kost om het te regelen.

Houd het geheim waar de machine is

De vorm die werkt: een kleine agent draait binnen het eigen netwerk van de klant, houdt de inloggegevens lokaal, en verbindt uitgaand naar het platform. Het platform stuurt instructies. De agent houdt de sleutels.

Dat keert de schadestraal om. Wie het control plane compromitteert kan nu commando's geven, wat erg is en waar we op terugkomen, maar hij kan niet weglopen met een bestand vol hypervisortokens van elke klant, want zo'n bestand bestaat niet.

De onderdelen die het echt maken zijn weinig glamoureus.

De kluis, en waar hij eerlijk gezegd tegen beschermt

Onze agent bewaart inloggegevens in een lokaal bestand, versleuteld met XChaCha20-Poly1305. De sleutel is niet het bestand op schijf: hij wordt met HKDF afgeleid uit een sleutelbestand gemengd met de identiteit van de machine zelf, en de aanvullende geauthenticeerde data bindt de cijfertekst aan de formaatversie en aan het ID van de agent.

Het praktische gevolg is het gevolg waar je voor wilt ontwerpen. Kopieer het sleutelbestand en de kluis naar een andere machine en hij gaat niet open. Zet de backup van vorige maand van de datamap terug op een andere host en hij gaat niet open. Elk faalbeeld, verkeerde sleutel, andere agent, gewijzigde bytes, levert dezelfde niet van elkaar te onderscheiden fout op, en dat is de bedoeling.

Hier is het deel dat in de documentatie hoort van elk product dat dit doet, en er meestal niet in staat. Dit beschermt niet tegen root op de host. Dat kan het niet, en dat hoeft ook niet: de klant is eigenaar van de host en eigenaar van de inloggegevens. Waar de kluis tegen beschermt is een gelekt bestand, niet de eigenaar van de machine. Een leverancier die iets anders suggereert verkoopt je een gevoel.

De inloggegevens raken de database van het platform nooit

Dit is het deel dat je makkelijk fout doet terwijl je gelooft dat je het goed deed, want de code ziet er in beide gevallen prima uit.

Als iemand een hypervisortoken in ons paneel typt, bevat de rij die in de commandotabel belandt alleen veldnamen. De waarden reizen in een apart, kortstondig bericht dat niet wordt opgeslagen, en gaan rechtstreeks de aflevering aan de agent in. De dispatcher logt ze nooit en bewaart ze nooit.

Beoordeel je een product hierop, dan is de vraag niet "slaan jullie inloggegevens op". De vraag is "wat staat er in jullie auditlog, en wat staat er in jullie wachtrij". Een wachtrij die het geheim draagt is een database die het geheim draagt, met extra stappen.

Een geheim verwijderen is een ander probleem dan het opslaan

Een integratie verwijderen in het paneel moet ertoe leiden dat de inloggegevens verdwijnen van een machine die je niet in beheer hebt, en dat is een lastiger probleem dan het lijkt.

De voor de hand liggende uitvoering is een afstemming: vraag de agent wat hij heeft, vergelijk dat met wat de database zegt dat hij hoort te hebben, en verwijder het verschil. Dat is korter en het is gevaarlijk, want de aftrekking faalt richting alles is weg. Eén mislukte leesactie, één afgekapte lijst, en je hebt een instructie gemaakt om elke werkende integratie op die host te wissen, en die inloggegevens zijn niet terug te halen zonder dat de klant ze opnieuw typt.

Dus komt de instructie alleen uit positieve kennis: een rij bestaat omdat iemand werkelijk een integratie heeft verwijderd. Een mislukte leesactie levert nul rijen op en daarmee nul instructies, en het geheim blijft staan waar het stond, wat precies de toestand is waarin je al zat.

Hij wordt twee keer afgeleverd: meteen over de gebeurtenisbus, en nog eens bij elke sessiehandshake, voor de agent die offline was, het bericht dat verloren ging, de gateway die opnieuw startte. Beide wegen lezen dezelfde tabel, dus er is geen tweede waarheid en geen tweede volgorde.

Wat een gestolen agentcertificaat wel en niet kan

Als de agent zich met een clientcertificaat authenticeert, is de eerlijke vraag wat er gebeurt als iemand het meeneemt. Daar concreet over zijn is nuttiger dan een beveiligingspagina.

Hij kan zich voordoen als die ene agent. De sessiepoort eist wederzijdse TLS, en bovenop de TLS-controle wordt de vingerafdruk van het aangeboden certificaat opgezocht in de agenttabel, die een unieke index heeft. Een vingerafdruk wijst daarmee naar precies één agent, en de identiteit die in de handshake geclaimd wordt, wordt daarmee vergeleken. Een aanvaller met het certificaat wórdt die agent, en kan alles sturen wat een agent mag sturen: statusgebeurtenissen, resultaten, telemetrie.

Hij kan de gegevens van andere klanten niet lezen. Alles is afgebakend op de organisatie waar de agent bij hoort, afgeleid uit het certificaat en niet uit wat de client over zichzelf zegt.

Hij levert op zichzelf de inloggegevens niet op. Het certificaat is de identiteit waarmee met het platform gepraat wordt. De kluissleutel staat daar los van, leeft op de host, en is gebonden aan de machine-identiteit van die host. Wie allebei heeft, heeft root op de machine, en op dat punt is het certificaat het kleinste probleem.

Hij houdt op te werken zodra jij dat zegt, binnen ongeveer een minuut. Intrekken is een toestand in de database, geen CRL en geen OCSP. Een nieuwe verbinding wordt meteen geweigerd. Een bestaande verbinding wordt met een tussenpoos van een minuut opnieuw gecontroleerd, dus een al verbonden aanvaller heeft hooguit dat. Blijft de statuscontrole zelf mislukken, dan wordt de sessie na drie mislukkingen op rij gesloten in plaats van eindeloos opengehouden, wat het slechtste geval op ruwweg drie minuten begrenst.

En de agent ruimt zichzelf op. Bij intrekking wist hij de kluis, de kluissleutel, zijn identiteit, zijn sessiestaat en zijn wachtrijen, in die volgorde, inloggegevens eerst. Elke stap is een poging op zich en wordt afzonderlijk gelogd, want een halve wissing is beter dan geen wissing.

Certificaten leven ook kort, negentig dagen, automatisch vernieuwd op de helft met een controle per uur. Dat is minder een verdediging tegen diefstal dan een grens aan hoe lang een diefstal die niemand opmerkte bruikbaar blijft.

Wat dit niet oplost

Drie dingen, ronduit gezegd, want een dreigingsmodel zonder restrisico is een marketingpagina.

Een gecompromitteerd control plane kan nog steeds commando's geven. Het kan je tokens niet stelen, maar het kan je agent opdragen een machine te verwijderen, en de agent doet dat. De geheimen verplaatsen verplaatst de schadestraal; het haalt hem niet weg. Wat je ervoor terugkrijgt is dat de schade begrensd is door wat de API kan uitdrukken en zichtbaar is in een auditspoor, in plaats van een aanvaller die met jouw inloggegevens om drie uur 's nachts rechtstreeks op je hypervisor doet wat hij wil.

Root op de agenthost leest alles. Bij ontwerp. Is die host gecompromitteerd, dan heb je een gecompromitteerde machine binnen je eigen netwerk, en die heeft je hypervisorgegevens omdat ze daar horen te staan.

Verwijderen hangt ervan af of de agent terugkomt. Komt een host nooit meer terug, dan blijft de instructie om zijn inloggegevens te vergeten openstaan. Dat is zichtbaar in het paneel in plaats van stilletjes als afgehandeld gemarkeerd, wat de juiste ruil is, maar het is een echte beperking en het is goed om te weten voordat je erop leunt.

Vragen die het waard zijn om een leverancier te stellen

Wat je uiteindelijk ook koopt, deze vijf scheiden de producten die erover nagedacht hebben van de producten die een alinea schreven:

  1. Waar staat de ontsleutelsleutel, fysiek? Is het antwoord "in ons platform", dan beschermt versleuteling in rust tegen schijfdiefstal en verder niets.
  2. Wat staat er in het auditlog en in de takenwachtrij? Geheimen lekken daar veel vaker in dan in de tabel waar iemand voorzichtig mee was.
  3. Wat gebeurt er met inloggegevens als ik een integratie verwijder, en kan ik zien of dat werkelijk gebeurd is?
  4. Hoe lang duurt het om toegang in te trekken, en geldt dat ook voor sessies die al open zijn?
  5. Heeft iets een inkomende poort nodig? Een firewallregel die het IP-bereik van een leverancier binnenlaat op de beheerinterface van je hypervisor is een tweede, stillere versie van hetzelfde probleem.

Zo hebben we het bij Provibr gebouwd: de agent draait op de eigen hardware van de klant, houdt de inloggegevens lokaal, en verbindt uitsluitend uitgaand.

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.