Linux ID

来源:互联网 发布:完美假期周晨曦淘宝店 编辑:程序博客网 时间:2024/06/06 07:42

原文:http://0pointer.de/blog/projects/ids.html

When programming software that cooperates with software running on behalf ofother users, other sessions or other computers it is often necessary to work withunique identifiers. These can be bound to various hardware and software objectsas well as lifetimes. Often, when people look for such an ID to use they pickthe wrong one because semantics and lifetime or the IDs are not clear. Here's alittle incomprehensive list of IDs accessible on Linux and how you should orshould not use them.

Hardware IDs

  1. /sys/class/dmi/id/product_uuid: The main board product UUID, asset by the board manufacturer and encoded in the BIOS DMI information. It maybe used to identify a mainboard and only the mainboard. It changes when theuser replaces the main board. Also, often enough BIOS manufacturers write bogusserials into it. In addition, it is x86-specific. Access for unprivileged usersis forbidden. Hence it is of little general use.
  2. CPUID/EAX=3 CPU serial number: A CPU UUID, as set by theCPU manufacturer and encoded on the CPU chip. It may be used to identify a CPUand only a CPU. It changes when the user replaces the CPU. Also, most modernCPUs don't implement this feature anymore, and older computers tend to disablethis option by default, controllable via a BIOS Setup option. In addition, itis x86-specific. Hence this too is of little general use.
  3. /sys/class/net/*/address: One or more network MAC addresses, asset by the network adapter manufacturer and encoded on some network cardEEPROM. It changes when the user replaces the network card. Since network cardsare optional and there may be more than one the availability if this ID is notguaranteed and you might have more than one to choose from. On virtual machinesthe MAC addresses tend to be random. This too is hence of little general use.
  4. /sys/bus/usb/devices/*/serial: Serial numbers of various USBdevices, as encoded in the USB device EEPROM. Most devices don't have a serialnumber set, and if they have it is often bogus. If the user replaces his USBhardware or plugs it into another machine these IDs may change or appear inother machines. This hence too is of little use.

There are various other hardware IDs available, many of which you maydiscover via the ID_SERIAL udev property of various devices, such hard disksand similar. They all have in common that they are bound to specific(replacable) hardware, not universally available, often filled with bogus dataand random in virtualized environments. Or in other words: don't use them, don'trely on them for identification, unless you really know what you are doing andin general they do not guarantee what you might hope they guarantee.

Software IDs

  1. /proc/sys/kernel/random/boot_id: A random ID that is regeneratedon each boot. As such it can be used to identify the local machine's currentboot. It's universally available on any recent Linux kernel. It's a good andsafe choice if you need to identify a specific boot on a specific bootedkernel.
  2. gethostname(), /proc/sys/kernel/hostname: A non-random IDconfigured by the administrator to identify a machine in the network. Oftenthis is not set at all or is set to some default value such aslocalhost and not even unique in the local network. In addition itmight change during runtime, for example because it changes based on updatedDHCP information. As such it is almost entirely useless for anything butpresentation to the user. It has very weak semantics and relies on correctconfiguration by the administrator. Don't use this to identify machines in adistributed environment. It won't work unless centrally administered, whichmakes it useless in a globalized, mobile world. It has no place inautomatically generated filenames that shall be bound to specific hosts. Justdon't use it, please. It's really not what many people think it is.gethostname() is standardized in POSIX and hence portable to otherUnixes.
  3. IP Addresses returned by SIOCGIFCONF or the respective Netlink APIs: Thesetend to be dynamically assigned and often enough only valid on local networksor even only the local links (i.e. 192.168.x.x style addresses, or even169.254.x.x/IPv4LL). Unfortunately they hence have little use outside ofnetworking.
  4. gethostid(): Returns a supposedly unique 32-bit identifier for thecurrent machine. The semantics of this is not clear. On most machines thissimply returns a value based on a local IPv4 address. On others it isadministrator controlled via the/etc/hostid file. Since the semanticsof this ID are not clear and most often is just a value based on the IP address it isalmost always the wrong choice to use. On top of that 32bit are notparticularly a lot. On the other hand this is standardized in POSIX and henceportable to other Unixes. It's probably best to ignore this value and if peopledon't want to ignore it they should probably symlink/etc/hostid to/var/lib/dbus/machine-id or something similar.
  5. /var/lib/dbus/machine-id: An ID identifying a specific Linux/Unixinstallation. It does not change if hardware is replaced. It is not unreliablein virtualized environments. This value has clear semantics and is consideredpart of the D-Bus API. It is supposedly globally unique and portable to allsystems that have D-Bus. On Linux, it is universally available, given thatalmost all non-embedded and even a fair share of the embedded machines shipD-Bus now. This is the recommended way to identify a machine, possibly with afallback to the host name to cover systems that still lack D-Bus. If yourapplication links againstlibdbus, you may access this ID withdbus_get_local_machine_id(), if not you can read it directly from the file system.
  6. /proc/self/sessionid: An ID identifying a specific Linux loginsession. This ID is maintained by the kernel and part of the auditing logic. Itis uniquely assigned to each login session during a specific system boot,shared by each process of a session, even across su/sudo and cannot be changedby userspace. Unfortunately some distributions have so far failed to set thingsup properly for this to work (Hey, you, Ubuntu!), and this ID is always(uint32_t) -1 for them. But there's hope they get this fixedeventually. Nonetheless it is a good choice for a unique session identifier onthe local machine and for the current boot. To make this ID globally unique itis best combined with/proc/sys/kernel/random/boot_id.
  7. getuid(): An ID identifying a specific Unix/Linux user. This ID isusually automatically assigned when a user is created. It is not unique acrossmachines and may be reassigned to a different user if the original user wasdeleted. As such it should be used only locally and with the limited validityin time in mind. To make this ID globally unique it is not sufficient tocombine it with/var/lib/dbus/machine-id, because the same ID might beused for a different user that is created later with the same UID. Nonethelessthis combination is often good enough. It is available on all POSIX systems.
  8. ID_FS_UUID: an ID that identifies a specific file system in theudev tree. It is not always clear how these serials are generated but thistends to be available on almost all modern disk file systems. It is notavailable for NFS mounts or virtual file systems. Nonetheless this is often agood way to identify a file system, and in the case of the root directory evenan installation. However due to the weakly defined generation semantics theD-Bus machine ID is generally preferrable.

Generating IDs

Linux offers a kernel interface to generate UUIDs on demand, by reading from/proc/sys/kernel/random/uuid. This is a very simple interface togenerate UUIDs. That said, the logic behind UUIDs is unnecessarily complex andoften it is a better choice to simply read 16 bytes or so from/dev/urandom.

Summary

And the gist of it all: Use /var/lib/dbus/machine-id! Use/proc/self/sessionid! Use/proc/sys/kernel/random/boot_id!Use getuid()! Use /dev/urandom! And forget about therest, in particular the host name, or the hardware IDs such as DMI. And keep inmind that you may combine the aforementioned IDs in various ways to getdifferent semantics and validity constraints.


0 0
原创粉丝点击