Naar de inhoud

Blog ·

Een etiket dat een hostnaamwijziging overleeft

Een sticker op een server is een openbaar document. Wat erop staat, waarom de QR-code geen URL bevat, en hoe een streepjescodetabel geverifieerd wordt.

Door Provibr

Een sticker op een server is een openbaar document. Hij reist mee in een koeriersbus, hij wordt gelezen door medewerkers van een remote hands-dienst die werken voor een bedrijf waarmee je nooit een contract hebt gesloten, en uiteindelijk wordt de machine uit dienst genomen en gaat de sticker met het chassis de afvalcontainer in. Alles wat erop gedrukt staat is, over de levensduur van de machine, gepubliceerd.

Die ene constatering bepaalt bijna alles over wat er op een datacenteretiket hoort te staan, en sluit het meeste uit van wat mensen erop zetten.

Wat erop staat, en wat niet

Drie dingen: een ondoorzichtige locator, het revisienummer van deze afdruk, en dezelfde locator nog eens in voor mensen leesbare vorm, gegroepeerd per vier zodat iemand hem kan intypen als de code niet wil scannen.

Er staat niet op: de klantnaam, de organisatie, het serienummer, de assettag, het rack waar hij op dit moment in staat, de hostnaam, een logo, of een token van welke soort dan ook. Een etiket is een identiteit, geen dossier.

Over het rack wordt het meest gediscussieerd, want het op de sticker schrijven is handig tot precies de eerste keer dat een machine verhuist. Daarna vermeldt de sticker met stelligheid een verkeerde locatie, en een verkeerde locatie die er gezaghebbend uitziet is erger dan geen. Een niveau lager is dat ook de reden dat een rackpositie geen sticker krijgt: een U-positie is geen ding maar een coördinaat, en hij houdt op te betekenen wat hij betekende zodra de begineenheid van het rack gecorrigeerd wordt.

Waarom de QR-code geen URL bevat

Het gebruikelijke bij alles met een QR-code is een link te coderen. Wij coderen de kale locator, om drie redenen in volgorde van gewicht.

Een sticker overleeft een hostnaam. Een account dat later naar zijn eigen domein verhuist zou anders duizend gedrukte etiketten hebben die naar een adres wijzen dat het niet meer bedient, en niemand drukt duizend etiketten opnieuw.

Een URL zegt meer dan een locator. Hij noemt het platform, en op het eigen domein van een klant noemt hij de klant. Dat is precies de categorie informatie waar het etiket vrij van hoort te zijn: een URL is geen snelkoppeling, het is een extra veld, en het is het veld met de meeste omstanders.

En er is precies één invoerweg. Een telefooncamera, een USB-scanner die in een veld typt en een mens die met de hand overneemt leveren alle drie dezelfde tekenreeks in hetzelfde vak. Een URL zou een vierde vorm scheppen die alleen de camera ooit produceert, en een vierde vorm is een vierde ding om fout te doen.

De locator is geen bearertoken

Dit is het deel dat de rest veilig maakt. De locator in handen hebben levert je niets op.

Een scan is een gewone geauthenticeerde handeling. De organisatiepoort draait, het leesrecht wordt gecontroleerd, de zoekopdracht wordt tot het account beperkt, en pas dan zegt de server of deze locator hier bestaat. Een locator van een ander account levert precies hetzelfde antwoord op als een die iemand verzonnen heeft: onbekend. Een ingetrokken locator krijgt een eigen weigering, want dat is een ander feit en wie de sticker vasthoudt verdient te weten welk van de twee het is.

Er is ook geen leverancierprefix. Een schema ervoor zou de software onze sticker laten onderscheiden van de streepjescode die de fabrikant er al op geplakt heeft, en het zou iedereen die de sticker vindt vertellen bij welk platform hij hoort. De vorm doet dat werk stil: een locator is zestien tekens uit een bekend alfabet, en alles wat die vorm niet heeft wordt opgezocht als assettag of serienummer, wat de scanstroom toch al nodig heeft voor de streepjescode van de fabrikant en voor iemand die een nummer van het chassis afleest.

Zestien tekens, en waarom zestien

Het alfabet is Crockford base32: de cijfers en de letters zonder I, L, O en U. I en L zijn te verwarren met het cijfer één, O met nul; de U laat de standaard vallen om onbedoelde grofheid te vermijden. Wij volgen hem omdat twee andere codes in dit product dat al doen, en twee alfabetten zouden een fout zijn die op zijn moment wacht.

Zestien tekens uit een alfabet van tweeëndertig tekens is tachtig bits. De lengte is niet gekozen op raadbaarheid, want raden levert niets op: de zoekopdracht wordt hoe dan ook geautoriseerd. Ze is gekozen op botsingen. Tachtig bits maakt een duplicaat over miljoenen etiketten verwaarloosbaar, zodat de unieke index eronder nooit een herhaling afdwingt die een gebruiker opmerkt. Zestien is ook ongeveer de langste tekenreeks die iemand in vier groepen van vier zonder fout overneemt.

Normalisatie draait op alles wat binnenkomt: trimmen, hoofdletters maken, spaties en koppeltekens weghalen, en dan I en L naar één en O naar nul toewijzen. Niemand die van een sticker overtypt hoort te hoeven weten dat die letters ontbreken. De U heeft met opzet geen toewijzing: geen cijfer lijkt erop, dus een U is een echte typfout en hoort thuis in een weigering en niet in een stille vervanging.

Code 128, met de hand geschreven, en geverifieerd in plaats van vertrouwd

De QR-code gebruikt een bibliotheek die al in de lockfile stond voor tweefactorauthenticatie: geen runtime-afhankelijkheden, en een renderer die SVG maakt zonder een canvas of een DOM aan te raken. Die hergebruiken is beter dan een tweede QR-codeerder schrijven.

Voor Code 128 bestond hier zo'n pakket niet. De kandidaten die het werk doen slepen een tekenlaag mee die op een canvas of een browser gericht is, wat precies het enige is dat een op de server gerenderde SVG niet mag hebben, en ze zijn twee ordes van grootte groter dan het ding werkelijk is. Code 128 is klein: een tabel met patronen, een startteken, een controlesom modulo honderddrie, en een stopteken. Dat is een paar honderd regels en geen toeleveringsketen voor een tabel die sinds 1981 niet veranderd is.

Het probleem met een standaardtabel uit een specificatie overtypen is dat een fout erin stil faalt. De SVG ziet er perfect uit, de tests slagen, en maanden later leest een scanner in een datacenter een ander teken. De tabel wordt daarom geverifieerd door vier onafhankelijke invarianten en een decoder, allemaal in het testbestand:

  1. Honderdzes patronen naast het stopteken, elk van precies zes elementen die samen elf modules zijn.
  2. Even pariteit in de balken. Elk Code 128-teken heeft een even som over zijn drie balken; dat is de eigenschap waarmee een scanner uitrekent welke kant hij op leest, en ze geldt voor alle honderdzes. Eén verkeerd getypt cijfer breekt of dit of de som hierboven.
  3. Elementbreedtes tussen één en vier, en alle honderdzes patronen verschillend.
  4. Het stopteken, het enige patroon met zeven elementen en dertien modules.
  5. Een decoder in de test die de gegenereerde balkbreedtes terugleest en de invoertekenreeks moet herstellen, controleteken inbegrepen.

Een tabel die vier onafhankelijke invarianten en een heen-en-terugtoets overleeft is niet "waarschijnlijk goed", en dat onderscheid is de hele reden om ze te schrijven.

We zijn in subset B gebleven in plaats van automatisch te wisselen. Het etiket draagt hoofdletters en cijfers, en die dekt subset B in één keer. Subset C zou cijferparen halveren, maar een locator is geen cijferreeks, dus een automatische wissel zou een tak zijn die nooit afgaat.

De vellindeling volgt uit de streepjescode

Vierentwintig etiketten per A4-pagina, drie naast elkaar en acht onder elkaar. Dat getal is geen ontwerpvoorkeur, het is rekenwerk dat de andere kant op loopt.

Een Code 128 van zestien tekens is tweehonderdelf modules breed: elf voor de start, elf per teken, elf voor het controleteken en dertien voor de stop. Tel er twee quiet zones van tien modules bij op en je hebt tweehonderdeenendertig modules in de breedte nodig. De praktische ondergrens voor een gewone scanner is een module van een kwart millimeter, waaronder lezen van betrouwbaar naar incidenteel gaat. Dat is achtenvijftig millimeter streepjescode.

Vier kolommen op een A4 geeft een etiket van rond de tweeënvijftig millimeter breed en een module van bijna twee tienden van een millimeter: een vel dat er netter uitziet en niet leest in een koud gangpad. Drie bij acht geeft een etiket van zeventig bij zevenendertig millimeter, een bruikbare breedte van vierenzestig, en een module van 0,277 millimeter. Het aantal volgt uit de code in plaats van andersom. Het vel is met opzet vol, met de marge binnen elk etiket in plaats van rond het raster, zodat een printerstuurprogramma nooit iets hoeft te schalen, en schalen is het enige dat een streepjescode niet verdraagt.

Die ondergrens is een constante in de bron en geen commentaarregel, zodat een test de modulebreedte van de gerenderde SVG ertegen meet. Een indelingswijziging die de streepjescode te dun perst is een rode test in plaats van een klacht uit het gangpad.

Eén actief etiket per object

Herdrukken zijn het gewone geval, dus de database draagt de invariant en niet de code. Twee partiële unieke indexen, één voor machines en één voor racks, de enige twee dingen die een etiket dragen, laten hoogstens één etiket toe dat niet ingetrokken is. Zonder die indexen laat een herdruk die halverwege mislukt twee geldige stickers op één machine achter, en kan niemand zeggen welke de echte is. Een tweede paar houdt de revisie uniek per object, zodat een herdruk optelt en zich nooit herhaalt. Drie cijfers is het plafond: het getal moet leesbaar blijven, en duizend herdrukken van één machine is geen etiketteringsprobleem.

Wat we zouden opschrijven

  1. Behandel de sticker als gepubliceerd, en bepaal wat erop komt door te vragen wie hem over vijf jaar leest.
  2. Codeer de identificatie, niet een link. Die overleeft een domeinwijziging, een naamsverandering en een overname; een URL overleeft er geen van.
  3. Maak de identificatie op zichzelf waardeloos, zodat een verloren sticker een logistiek probleem is en geen beveiligingsprobleem.
  4. Verifieer een standaardtabel met invarianten en een heen-en-terugtoets, want die soort fout faalt nooit luidruchtig.
  5. Leid de afdrukindeling af uit de kleinste leesbare module, en leg die ondergrens vast als een constante die een test kan meten.

Voor de eerlijkheid over onze eigen positie: het datacenterwerk zit achter een uitrolvlag die standaard uit staat, met daarbovenop een instelling per organisatie, dus dit is een beschrijving van een ontwerp en geen aankondiging. Twee dingen zijn uitdrukkelijk onbewezen. De QR-matrix is niet door een onafhankelijke implementatie gedecodeerd, want er zit geen decoder in deze repository. En er is niets op papier gedrukt en in een gangpad gescand, en dat is de enige toets die er voor een streepjescode werkelijk toe doet. Dezelfde redenering over wat een onderdeel mag weten komt hier elders terug: inloggegevens blijven op de host, en de agent verbindt uitsluitend uitgaand.

Uit het datacenterwerk aan Provibr. Wat voorkomt dat twee mensen dezelfde rack-unit claimen staat in de enige echte grens op rackbezetting.

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.