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:

  • /sys sysfs pseudo-filesystem
  • dmidecode tool
  • lshw hardware list utility

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.