1. Introduction
Machines are a compilation of hardware gathered into a system. Computers are no exception with their components:
- central processing unit (CPU)
- random access memory (RAM)
- mainboard
- secondary storage
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.
4. Mainboard
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.
7. Summary
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.