Machines are a compilation of hardware gathered into a system. Computers are no exception with their components:
Just like individual components, many systems have identifiers such as a brand and model along with a unique serial number. For custom configurations, we can leverage our own or use one from the operating system (OS).
In this tutorial, we explore ways to extract or generate a unique identifier (ID) from and for a Linux machine as a whole. First, we briefly define what an identity is and check what sources we can use to acquire it. Next, we go over some of those sources. After that, we show three ways to get ID information for a system. Finally, generating custom identities is discussed.
We tested the code in this tutorial on Debian 11 (Bullseye) with GNU Bash 5.1.4. It should work in most POSIX-compliant environments.
2. Machine Identity and Data Sources
For our purposes, we define a machine identity as a relatively small piece of information that we can use to uniquely identify a machine in terms of hardware. As opposed to, e.g., knowing when Linux was installed, we mainly focus on the physical components.
In fact, software vendors often use custom identities to link a product license to a given system.
There are several data sources we use to extract such information for a whole machine:
Importantly, the options above were picked based on standards, availability, and usefulness. Depending on the identity data, we may leverage one or more of these methods.
For example, the dmidecode command comes with many Linux distributions. With it, we use the –string option and specific categories.
Armed with these sources, let’s see how we can identify systems in different scenarios.
3. Pre-built Machines
Manufacturers sometimes assemble complete computing kits with selected components. For example, many desktop computer configurations and laptops often come prepackaged.
Of course, brands and models repeat, so they aren’t really unique:
$ dmidecode -s system-product-name PowerEdge X666
Yet, such off-the-shelf products commonly have a unique ID. Under Linux, depending on the system type, this ID can be part of the DMI interface:
$ dmidecode --string system-uuid 10666fee-0108-3264-1000-beef10de1667
Using system-uuid, we isolate only the hexadecimal serial number given to the system when manufactured and assembled.
Alternatively, we can use system-serial-number:
$ dmidecode --string system-serial-number X01M666
This tag is often leveraged for servicing and is thus usually easier to remember. To get a complete picture of all available information about the system as a whole, we can use the SYSTEM –type with dmidecode:
$ dmidecode --type SYSTEM # dmidecode 3.2 Getting SMBIOS data from sysfs. SMBIOS 2.7 present. Handle 0x0100, DMI type 1, 27 bytes System Information Manufacturer: Dell Inc. Product Name: PowerEdge X666 Version: Not Specified Serial Number: X01M666 UUID: 10666fee-0108-3264-1000-beef10de1667 Wake-up Type: Power Switch SKU Number: SKU=NotProvided;ModelName=PowerEdge X666 Family: Not Specified Handle 0x0C00, DMI type 12, 5 bytes System Configuration Options Option 1: NVRAM_CLR: Clear user settable NVRAM areas and set defaults Option 2: PWRD_EN: Close to enable password Handle 0x2000, DMI type 32, 11 bytes System Boot Information Status: No errors detected
Notably, there are other ways to get the same information.
Let’s try it with /sys:
$ cat /sys/class/dmi/id/product_uuid 10666fee-0108-3264-1000-beef10de1667 $ cat /sys/class/dmi/id/product_serial X01M666
Finally, we can also use lshw:
$ lshw XOST description: Rack Mount Chassis product: PowerEdge X666 (SKU=NotProvided;ModelName=PowerEdge X666) vendor: LENOVO serial: X01M666 width: 64 bits capabilities: smbios-2.8 dmi-2.8 smp vsyscall32 configuration: boot=normal chassis=rackmount sku=SKU=NotProvided;ModelName=PowerEdge X666 uuid=10666FEE-0108-3264-1000-BEEF10DE1667
Of course, some machines are custom, so these entries may be ‘Not Specified’ or even empty, depending on the circumstances. In such cases, we can turn to other solutions.
To identify a machine, we can use its mainboard, also called a baseboard or motherboard.
Because it’s the basis and touchpoint of all other parts, a mainboard limits the components which are compatible with a given system. Thus, it might not be so easy to switch out a baseboard without having to change another component.
Let’s see how we can identify the mainboard of a system from our sources:
$ dmidecode --string baseboard-serial-number ..MX66601XD10007. $ cat /sys/class/dmi/id/board_serial ..MX66601XD10007. $ lshw -class bus *-core description: Motherboard product: 0XB0X1 vendor: LENOVO physical id: 0 version: X01 serial: ..MX66601XD10007. [...]
Critically, the serial number of the mainboard may be the same as other identifiers like the system-serial-number from dmidecode, especially if it isn’t a short service tag.
Such serial number overlap may mean that the manufacturer hasn’t supplied the information through DMI. However, ID duplication may also be a sign that we’re working in a virtual environment.
5. Linux Machine ID
While it’s related to the software as well, Linux machines usually provide their own ID under /etc/machine-id:
$ cat /etc/machine-id 10beef666feed1010430667db1000100
This identity is sometimes a link to /var/lib/dbus/machine-id, generated as a random number by dbus-uuidgen.
Because of this, such an ID comes with several potential problems:
- relates to software, not hardware
- can be dynamically changed
- may be the same on cloned virtual machines
Even when there are no single reliable identities, we can generate our own. Let’s see how.
6. Generating Identifiers
When a system ID doesn’t tell us enough or we’re unable to use that for any reason, we can usually still extract stable information to produce our own custom machine identity.
For example, we can hash any hardware information together:
- storage device sizes
- partitioning scheme
- main memory size
- CPU specifications
- number of ports
In fact, any software ID can be added:
Let’s do a simple computation:
$ echo "$(fdisk --list)$(lshw -short)" | md5sum | cut --delimiter=' ' --fields=1 403b0e3b8b5d6206660d10c13cdb7919
Here, we use the GNU coreutils md5sum system utility to compute the hash of two command outputs:
- disk information and partitioning scheme from fdisk
- general hardware information from lshw
Finally, we use cut to only get the actual MD5 sum.
In this article, we looked at methods to extract an identity from a Linux system. We discussed sources, tools, and alternatives.
In conclusion, which method one chooses to obtain a machine ID under Linux depends on the system and the use case for the information.