machine-id
7
miscellany
nosh
machine-id
identify the machine for various applications
Description
Machine IDs are UUIDs.
A machine ID is a 128-bit number that is intended to be a globally unique ID for identifying the machine, and that is intended to be constant across system restarts (once it has been set up), or (at minimum) from restart to shutdown.
It is not dependent from the presence of any particular piece of hardware.
Replacing hardware is not intended to affect a machine ID; although replacing the particular non-volatile storage that is used to store the machine ID when the system is powered off will result in a change to the machine ID, obviously.
It identifies the whole machine, not individual pieces.
It is not suitable for use (in whole or in part) in IPv6 addresses (which identify individual interfaces) or anywhere else at the network layer, but it is suitable for identifying entire hosts on a network at the application layer.
It is important to blank machine IDs when cloning systems from images, so that multiple clones do not have the same machine ID.
It is unsuitable for publishing.
It is globally unique in order to prevent collisions at the application level, not in order to be globally visible.
The application layer use originally envisaged by its inventor was that coöperating applications using network-capable IPC could compare machine IDs to determine whether they could communicate via non-networkable IPC such as AF_LOCAL sockets or shared memory.
Like network hardware MAC addresses, machine IDs are information that potentially hostile people can use for tracking other people.
It is important to blank or eliminate machine IDs when providing data to the outside world.
Hashing machine IDs, with or without a "salt", is insufficient for privacy.
Privacy requires that IDs cannot be correlated, not that they cannot be decrypted; and a hashed ID(+salt) in one place can still be correlated with the same hashed ID(+salt) elsewhere.
Faulty and nil UUIDs
Some older softwares, including old versions of systemd, do not create valid UUIDs as machine IDs.
In particular, they create entirely random UUIDs where even the UUID variant and type are random.
Machine ID generation at system bootstrap (or otherwise) should attempt to correct for this, by converting any UUID that is not a type 1 to type 5 DCE-variant UUID into a type 4 DCE-variant UUID.
This conversion is done by simply overwriting the type and variant parts of the UUID.
A nil UUID (NCS-variant with all zeroes) should be treated as unset, and not corrected in this manner.
A nil UUID isn't globally unique by its very nature and is unsuitable as a machine ID.
The aforementioned correction system, if applied to it, would not work.
Storage
Non-volatile storage
The machine ID, once set up, is stored in the file /etc/machine-id.
If a machine ID can be read and parsed from that file, then (subject to the aforementioned corrections of variant and type) it should be considered to be valid and initialized.
Machine IDs are stored in the file as 32 lowercase hexadecimal characters (the machine ID as a 128-bit bigendian integer) followed by a linefeed.
On Linux operating systems, both systemd and recent versions of dbus-daemon1 read this file.
On FreeBSD systems, ports of dbus-daemon1 read /usr/local/etc/machine-id instead.
Older versions of dbus-daemon1 (from before 2013) read /var/lib/dbus/machine-id or /var/db/dbus/machine-id, according to platform.
To prevent inconsistency, these can just be symbolic links to /etc/machine-id.
(Symbolic links the other way around would break if /var or one of its subdirectories is not mounted, as can be the case at the point that a machine ID is generated during system bootstrap.)
On the BSDs, the machine ID is also stored, but as a human-readable-form UUID, in /etc/hostid.
Volatile storage
The machine ID, once set up, is also stored in the file /run/machine-id.
This may, according to need, be the source of a bind mount over the top of /etc/machine-id.
On the BSDs the machine ID is stored in the kern.hostuuid
variable (see sysctl1).
It is also stored, but as a human-readable-form UUID, in /run/hostid.
Host IDs
An older unique ID for machines is the host ID, as queried and set by the gethostid3 and sethostid3 library functions.
As those functions' manual pages state, this is a mechanism that was dropped by its originating system in 1994, but that has continued since largely due to the inertia of standardization.
It really shouldn't be used at all on systems with machine UUIDs available.
One way of generating a host ID is to hash the machine ID.
Ironically, this provides a more stable host ID than some of the original schemes for determining a host ID did.
(They were only as stable as the host's IPv4 address assignment, for example.)
As long as the machine ID does not change, the host ID will not change; and the host ID can be set up before network interfaces, and domain name to address mapping facilities, are even available.
Generation
There are multiple hashing protocols in use, and softwares should not rely upon any particular choice:
The Dawidek mechanism on FreeBSD takes the upper 32 bits of the MD5 of the machine ID.
setup-machine-id1 takes the lower 32-bits of the CubeHash (see cubehash1) of the machine ID.
Storage
The BSD C library expects the host ID to be stored in the kern.hostid
variable (see sysctl1).
The GNU C library expects the host ID to be stored in the /etc/hostid file.
On the BSDs, this file contains the machine ID as a human-readable-form UUID, and this file is not used for the host ID.
On Linux operating systems, setup-machine-id1 will also write the host ID to the /run/hostid file.
This may, according to need, be the source of a bind mount over the top of /etc/hostid.
Example users
systemd-journald1
This uses the machine ID for naming directories under /run/log/journal/ and /var/log/journal/.
Furthermore, it includes the machine ID in every individual journal entry.
journalctl1
This distinguishes log streams by the embedded machine IDs in every entry.
Changing machine IDs across reboots will make it split log output into different log streams.
Machine IDs are not stripped by journalctl or in general by other tools that export or print systemd journal entries.
dbus-daemon1
Clients can make a org.freedesktop.DBus.Peer.GetMachineId remote procedure call to obtain the machine ID.
Most applications that use the Desktop Bus (D-Bus)
The complaint was raised in 2007 that all applications softwares that used the libdbus library read the machine ID even though they made no use of it (outwith a mechanism known as "X11 autolaunching").
Ten years later, the D-Bus developers came around to the idea that X11 autolaunching was not preferable and that applications softwares should not have such a drastic coupling to the machine ID, and this is no longer the case with softwares built with newer libraries.
systemd-networkd1
This broadcasts the machine ID (hashed with a known fixed salt) over the LAN as the unique client identifier part of the DHCP protocol.
(Other DHCP clients tend to use MAC addresses for this.)
It also broadcasts the machine ID locally on each link as part of Ethernet LLDP, if enabled.
systemd's kernel-install8
This uses the machine ID for directory names on the EFI System Partition.
chromium1
Google Chrome uses the machine ID to lock user profiles to the machines that they were generated on.
ungoogled-chromium has a --disable-machine-id command-line option that switches this off, however as of 2019 this option is still problematic in practice and there are open bugs about it causing profile data loss.
pulseaudio1
PulseAudio uses the machine ID in the names of its settings files under ~/.config/pulse/.
systemd-random-seed1
This writes the machine ID (in binary) to /dev/random before writing the seed to it, every time.
History
The machine ID mechanism was invented by Havoc Pennington for Desktop Bus (D-Bus) in 2006.
The idea was that communicating D-Bus clients and servers could determine whether they were on a single shared system.
However, the Desktop Bus mechanism never became network transparent (like CORBA and others), meaning that clients and servers were always on a single shared system.
Pawel Jakub Dawidek added a unique per-machine UUID mechanism to FreeBSD in April 2007, making it use the SMBIOS system UUID from the machine's firmware if available.
Lennart Poettering et al. adopted a modified version of the D-Bus machine ID mechanism in systemd for Fedora 15.
Initially, it generated invalid UUIDs.
This bug was corrected some years later.
Sometime around 2013, D-Bus was modified to use the systemd files for storing machine IDs.
Author
Jonathan de Boyne Pollard