SSD Nodes Learn 🎉 VPS vanaf $5.50/mnd
Gidsen Matt ConnorDoor Matt Connor

Duplicate machine-id na VPS clone oplossen

Heeft u na het klonen van een VPS problemen met DHCP leases door een dubbele /etc/machine-id? Volg deze vier stappen om de ID veilig te regenereren en uw image correct voor te bereiden.

Wat /etc/machine-id is en waarom een duplicaat een probleem vormt

Een gekloonde VPS start op met dezelfde /etc/machine-id als de server waarvan deze is gekloond, terwijl die waarde bij precies één installatie hoort. De oplossing bestaat uit vier commando's: maak het bestand leeg, verwijder de D-Bus-kopie als dit een echt bestand is, genereer het opnieuw en start opnieuw op. De herstart is de stap die mensen vaak overslaan, terwijl juist die stap de wijziging effectief maakt.

/etc/machine-id bevat een hexadecimale tekenreeks van 32 tekens in kleine letters, afgesloten met een newline. Gedecodeerd is dit een waarde van 16 bytes (128-bit). De man-page van machine-id(5) noemt dit vertrouwelijk en stelt dat het niet op het netwerk mag worden blootgesteld, omdat alles wat dit uitleest uw machine later opnieuw kan herkennen. Het wordt eenmalig geschreven tijdens de installatie van het systeem en wordt daarna niet meer gewijzigd.

Er is vaak verwarring tussen drie verschillende identificatiegegevens, dus het is nuttig om deze te onderscheiden. De hostname is een label dat u zelf kiest en op elk gewenst moment kunt wijzigen. De DMI (desktop management interface) product-UUID in /sys/class/dmi/id/product_uuid is afkomstig van de hypervisor en is alleen leesbaar door root. De machine ID is de derde: het besturingssysteem genereert deze en elke gebruiker op de machine kan deze uitlezen.

Wat leest daadwerkelijk de machine ID

De DHCP client identifier. Dit is het punt dat voor problemen zorgt. systemd.network(5) documenteert ClientIdentifier= in de [DHCPv4] sectie als standaardwaarde duid, wat een RFC 4361 client ID verstuurt die is opgebouwd uit een IAID en een DUID (DHCP unique identifier). networkd.conf(5) documenteert het standaard DUID-type als vendor, waarbij de DUID-waarde wordt gegenereerd met 43793 als vendor identifier (systemd) en de gehashte inhoud van de machine ID. DHCPv6 gebruikt dezelfde DUID. Twee klonen met dezelfde machine ID genereren dezelfde DUID-hash, en als ze ook dezelfde interfacenaam behouden, versturen ze een byte-identieke client identifier. De DHCP-server ziet dan één client in plaats van twee en biedt beide systemen dezelfde lease aan. Het symptoom is een IP-adres dat verspringt tussen de twee servers, of één server die zijn adres verliest zodra de andere vernieuwt.

journald. Journal-bestanden bevinden zich in /var/log/journal/<machine-id>/. De map is letterlijk vernoemd naar de ID. Als u de journals van twee klonen naar één collector verstuurt, komen ze in dezelfde map terecht en worden ze als één host gelezen.

D-Bus. /var/lib/dbus/machine-id is waar dit bestandsformaat is ontstaan. Op Debian en Ubuntu is dit een symbolische link naar /etc/machine-id. Op sommige systemen is het een afzonderlijk bestand dat een eigen kopie bevat, en die kopie vormt de valstrik in de onderstaande procedure.

Per-host agents. Monitoring-agents, licentiecontroles, inventarisatietools en back-upclients gebruiken vaak de machine ID als hun standaard host-identifier, omdat deze stabiel is en geen configuratie vereist. Twee servers die dezelfde identiteit rapporteren, resulteren in één samengevoegde reeks statistieken, of één licentieplaats die twee machines dekt. Controleer hoe uw agent de host ID afleidt in plaats van aan te nemen dat deze de hostname gebruikt.

Hoe u vaststelt of er sprake is van een duplicaat

Voer dit uit op beide servers en vergelijk de uitvoer.

cat /etc/machine-id
ls -l /var/lib/dbus/machine-id
sudo cat /sys/class/dmi/id/product_uuid

cat /etc/machine-id

Identieke machine-ID's op twee actieve servers betekenen dat de ene vanaf de andere is gekloond. hostnamectl toont dezelfde waarde op de Machine ID:-regel als u de voorkeur geeft aan één commando.

Het ls -l-resultaat bepaalt de volgende stap. Een symbolische koppeling ziet er als volgt uit:

lrwxrwxrwx 1 root root 15 Aug 21 09:12 /var/lib/dbus/machine-id -> /etc/machine-id

ls -l /etc/machine-id

Een regel die begint met -rw-r--r-- betekent dat het een echt bestand is dat zijn eigen kopie van het oude ID bevat. U moet dit verwijderen, omdat systemd-machine-id-setup dit bestand leest voordat het andere acties onderneemt.

Het product-UUID is ook van belang. systemd-machine-id-setup(1) gebruikt het KVM-UUID voordat het terugvalt op willekeurige generatie. Als uw provider beide klonen hetzelfde SMBIOS (system management BIOS) UUID heeft gegeven, resulteert regeneratie tweemaal in hetzelfde machine-ID. Verschillende product-UUID's op de twee systemen betekenen dat u zich hier geen zorgen over hoeft te maken.

De machine-ID regenereren op een gekloonde VPS

De volgorde is van belang. systemd-machine-id-setup(1) stelt dat als er al een geldige D-Bus machine-ID voor het systeem is geconfigureerd, deze D-Bus machine-ID wordt gekopieerd en gebruikt om /etc/machine-id te initialiseren. Laat u een bestaande /var/lib/dbus/machine-id staan, dan regenereert u exact de waarde waar u vanaf wilde.

sudo truncate -s 0 /etc/machine-id
sudo rm -f /var/lib/dbus/machine-id       # only if ls -l showed a real file
sudo systemd-machine-id-setup
sudo ln -sf /etc/machine-id /var/lib/dbus/machine-id
cat /etc/machine-id

Het eerst leegmaken van het bestand is vereist, omdat de tool alleen actie onderneemt wanneer het bestand ontbreekt of leeg is; het doet niets met een bestand dat al een geldige ID bevat. systemd-machine-id-setup rapporteert de uitgevoerde actie op de standaardfout (stderr). Op een KVM VPS ziet u doorgaans:

Initializing machine ID from KVM UUID.

Initializing machine ID from random generator. is de melding wanneer er geen hypervisor UUID beschikbaar is. Beide resultaten zijn in orde, zolang cat /etc/machine-id nu een andere waarde toont dan de andere server.

De symbolische link zorgt ervoor dat D-Bus en systemd dezelfde waarde gebruiken. Als u de voorkeur geeft aan een afzonderlijk echt bestand, voer dan sudo dbus-uuidgen --ensure uit: dit creëert het bestand met een nieuwe UUID wanneer het bestand nog niet bestaat. Als dbus niet is geïnstalleerd, bestaat de map /var/lib/dbus helemaal niet, faalt ln met No such file or directory, en kunt u beide regels overslaan.

Start daarna opnieuw op.

sudo reboot

Waarom een herstart niet optioneel is

Elk proces dat de oude waarde al heeft ingelezen, gebruikt deze nog steeds. sd_id128_get_machine() slaat de ID op in het cachegeheugen van het aanroepende proces, waardoor een actieve daemon nooit merkt dat het bestand is gewijzigd. journald heeft /var/log/journal/<old-id>/system.journal al geopend en blijft hier gegevens aan toevoegen. systemd-networkd heeft zijn DUID bij het opstarten bepaald en blijft bij elke vernieuwing de oude client-identifier sturen; dit is meestal precies de fout die u probeerde te herstellen. Ook D-Bus heeft zijn ID bij het opstarten ingelezen. U kunt services één voor één herstarten, maar u zult er altijd een missen, en bovendien houdt PID 1 de oude waarde ook vast.

Controleer na de herstart beide helften:

cat /etc/machine-id
ls /var/log/journal/

/var/log/journal/ bevat nu een tweede map die is vernoemd naar de nieuwe ID, en nieuwe vermeldingen worden daar opgeslagen. De standaard journalctl leest alleen de map van de huidige machine, waardoor uw geschiedenis van vóór het klonen verdwijnt uit het standaardoverzicht. De gegevens staan nog wel op de schijf: journalctl --merge leest elke journal-map, inclusief de oude. Verwijder de oude map zodra u zeker weet dat u die logs niet meer nodig heeft.

Dit is ook de reden waarom u de procedure niet kunt oefenen in een container. Een container deelt de kernel van de host en start nooit zijn eigen PID 1 op, terwijl de herstart juist het hele doel van deze oefening is. Test het op de manier zoals het in productie gebeurt: kloon een VM, voer de commando's uit, start opnieuw op en vergelijk vervolgens de ID met die van de bronmachine.

Truncateer vóór de snapshot, niet na het klonen

Het één voor één herstellen van klonen werkt. Het corrigeren van de image is echter beter, omdat elke server die wordt hersteld vanuit een foutieve snapshot dezelfde waarde overneemt. Voer dit uit als laatste stap voordat u de template afsluit.

sudo truncate -s 0 /etc/machine-id
sudo rm -f /var/lib/dbus/machine-id
sudo ln -s /etc/machine-id /var/lib/dbus/machine-id
sudo shutdown -h now

Maak het bestand leeg. Verwijder het niet. machine-id(5) adviseert een leeg bestand voor images die op meerdere machines worden gebruikt, omdat een leeg bestand op de juiste locatie toestaat dat een tijdelijk bestand via een bind-mount over het echte bestand wordt geplaatst wanneer de image alleen-lezen wordt gebruikt. Op een alleen-lezen /etc bevindt de bij het opstarten gegenereerde ID zich in dat tijdelijke bestand, en systemd-machine-id-setup --commit schrijft deze weg zodra het bestandssysteem beschrijfbaar is.

Een bijwerking om rekening mee te houden: een niet-ingevulde machine-ID markeert de volgende opstart als een eerste opstart, waardoor units met ConditionFirstBoot=yes tijdens die opstart worden uitgevoerd en bij elke daaropvolgende opstart worden overgeslagen. Controleer wat uw image zou uitvoeren met grep -rl ConditionFirstBoot /usr/lib/systemd/system/ voordat u de template bouwt.

Een template en een snapshot zijn verschillende objecten, en het verschil bepaalt of de identiteit wordt gekopieerd. Een template is een build-artifact dat u doelbewust voorbereidt, terwijl een snapshot een kopie van één draaiende server op een specifiek tijdstip is en de identiteit van die server samen met de data overneemt.

Waarom cloud-images dit correct afhandelen en uw snapshot niet

Distributie-cloud-images zijn ontworpen om gekloond te worden. Daarom worden ze geleverd met een leeg machine-ID, dat bij de eerste boot wordt ingevuld. cloud-init heeft hiervoor een gedocumenteerde procedure. cloud-init clean --machine-id zet /etc/machine-id op de letterlijke tekenreeks uninitialized op systemd-systemen. De cloud-init CLI-referentie beschrijft dit als best practice bij het klonen van een golden image, zodat de volgende boot van die image een uniek machine-ID genereert.

Een snapshot die u zelf heeft gemaakt, is een ander verhaal. Het bestand was al ingevuld op het moment dat u op snapshot klikte. Elke server die hiervan wordt hersteld, draagt dus diezelfde waarde, en het herstelproces wist deze niet. Dit is hetzelfde type probleem als het verplaatsen van een draaiende server naar een nieuwe VPS, waarbij de kopie exact is, maar de identiteit het onderdeel is dat u juist niet wilde kopiëren.

Wat een kloon nog meer dupliceert

  • SSH host keys. /etc/ssh/ssh_host_* wordt ook gekopieerd, waardoor beide servers dezelfde vingerafdruk aan clients presenteren. Verwijder deze bestanden en voer sudo ssh-keygen -A uit, of sudo dpkg-reconfigure openssh-server op Debian en Ubuntu. Uw clients zullen daarna waarschuwen voor een gewijzigde host key; dit is het juiste gedrag.
  • De hostname. Stel deze in met sudo hostnamectl set-hostname app02 en controleer vervolgens of /etc/hosts de nieuwe naam nog steeds correct omzet.
  • Statische netwerkconfiguratie. Een kloon van een machine met een statisch adres veroorzaakt een conflict met het origineel zodra deze opstart. Lees /etc/netplan/ voordat de kloon verbinding maakt met het netwerk.
  • De klok. Een herstelde snapshot hervat met de tijd die gold op het moment dat de snapshot werd gemaakt. Een grote sprong in de kloktijd op een herstelde VPS verstoort de validatie van TLS-certificaten en brengt de volgorde van logs in de war totdat de tijdsynchronisatie is bijgewerkt.

Doorloop ook de checklist voor de eerste tien minuten van een nieuwe VPS op de kloon. Een gekloonde machine erft de gebruikersaccounts, SSH-keys, firewallregels en geplande taken van de bronmachine over, terwijl niets daarvan is gecontroleerd voor de nieuwe taak die de kloon moet uitvoeren.

FAQ

Moet ik opnieuw opstarten na het wijzigen van /etc/machine-id?

Ja. Processen lezen de machine-ID eenmalig in en cachen deze, waardoor de nieuwe waarde niet terechtkomt bij processen die al actief zijn. journald blijft schrijven naar de journal-directory die vernoemd is naar de oude ID, en de DHCP-client blijft een client-identifier sturen die is afgeleid van de oude waarde; dit is meestal de reden waarom u deze heeft gewijzigd. Het herstarten van individuele services lost sommige problemen op, maar PID 1 behoudt ook de oude waarde. Start opnieuw op en bevestig daarna met cat /etc/machine-id en door de waarde te vergelijken met de andere server.

Is /etc/machine-id hetzelfde als de hardware-UUID?

Nee. De DMI-product-UUID in /sys/class/dmi/id/product_uuid is afkomstig van de hypervisor en is alleen leesbaar door root. De machine-ID wordt gegenereerd door het besturingssysteem en staat in een tekstbestand dat elke gebruiker kan lezen. Ze zijn in één richting verbonden: op een KVM-guest genereert systemd-machine-id-setup een nieuwe machine-ID op basis van de hypervisor-UUID wanneer er geen D-Bus-ID is om te kopiëren. Als twee clones dezelfde product-UUID delen, genereren ze dezelfde machine-ID; vergelijk dat bestand dus ook voordat u het resultaat vertrouwt.

Moet ik /etc/machine-id verwijderen of leeg laten?

Laat het bestand leeg wanneer u een image voorbereidt. machine-id(5) geeft de voorkeur aan een leeg bestand, omdat systemd er een tijdelijk bestand overheen kan mounten (bind-mount) wanneer de image draait met een read-only /etc. Het verwijderen van het bestand werkt op een beschrijfbaar systeem en sommige clone-scripts doen het op die manier, maar een leeg bestand is de veiligere standaard. cloud-init schrijft het woord uninitialized in het bestand voor hetzelfde doel.

Waarom kregen mijn twee gekloonde servers hetzelfde DHCP-adres?

Omdat beide dezelfde client-identifier stuurden. systemd-networkd gebruikt standaard ClientIdentifier=duid voor DHCPv4, en de standaard DUID is opgebouwd uit een hash van /etc/machine-id. Identieke machine-ID's produceren dus identieke identifiers op clones die ook dezelfde interfacenaam hebben behouden. De DHCP-server matcht op die identifier, behandelt beide verzoeken als één client en verstrekt één lease. Geef elke machine een eigen machine-ID en start beide opnieuw op. Als de server nog steeds het oude adres aanbiedt, wis dan de verouderde lease op de DHCP-server zelf.

#machine-id#systemd#cloning#snapshots#dhcp