web-dev-qa-db-fra.com

générer un ID unique cohérent

Pouvons-nous générer un identifiant unique pour chaque PC, quelque chose comme uuuidgen, mais cela ne changera jamais sauf s'il y a des changements matériels? Je pensais à fusionner CPUID et MACADDR et les hacher pour générer un ID cohérent, mais je ne sais pas comment les analyser à l'aide du script bash, ce que je sais, c'est comment puis-je obtenir CPUID à partir de

dmidecode -t 4 | grep ID

et

ifconfig | grep ether

alors je dois combiner ces chaînes hexadécimales et les hacher en utilisant sha1 ou md5 pour créer une chaîne hexadécimale de longueur fixe.
Comment analyser cette sortie?

21
uray

Que diriez-vous de ces deux:

$ Sudo dmidecode -t 4 | grep ID | sed 's/.*ID://;s/ //g'
52060201FBFBEBBF
$ ifconfig | grep eth1 | awk '{print $NF}' | sed 's/://g'
0126c9da2c38

Vous pouvez ensuite les combiner et les hacher avec:

$ echo $(Sudo dmidecode -t 4 | grep ID | sed 's/.*ID://;s/ //g') \
       $(ifconfig | grep eth1 | awk '{print $NF}' | sed 's/://g') | sha256sum 
59603d5e9957c23e7099c80bf137db19144cbb24efeeadfbd090f89a5f64041f  -

Pour supprimer le tiret arrière, ajoutez un autre tuyau:

$ echo $(Sudo dmidecode -t 4 | grep ID | sed 's/.*ID://;s/ //g') \
       $(ifconfig | grep eth1 | awk '{print $NF}' | sed 's/://g') | sha256sum |
  awk '{print $1}'
59603d5e9957c23e7099c80bf137db19144cbb24efeeadfbd090f89a5f64041f

Comme @mikeserv le souligne dans sa réponse , le nom de l'interface peut changer entre les bottes. Cela signifie que ce qui est eth0 aujourd'hui pourrait être eth1 demain, donc si vous recherchez eth0 vous pourriez obtenir une adresse MAC différente sur des bottes différentes. Mon système ne se comporte pas de cette façon, je ne peux donc pas vraiment tester, mais les solutions possibles sont:

  1. Grep pour HWaddr dans la sortie de ifconfig mais conservez-les tous, pas seulement celui correspondant à une carte réseau spécifique. Par exemple, sur mon système, j'ai:

    $ ifconfig | grep HWaddr
    eth1      Link encap:Ethernet  HWaddr 00:24:a9:bd:2c:28  
    wlan0     Link encap:Ethernet  HWaddr c4:16:19:4f:ac:g5  
    

    En saisissant les deux adresses MAC et en les passant par sha256sum, vous devriez pouvoir obtenir un nom unique et stable, quel que soit NIC s'appelle quoi:

    $ echo $(Sudo dmidecode -t 4 | grep ID | sed 's/.*ID://;s/ //g') \
         $(ifconfig | grep -oP 'HWaddr \K.*' | sed 's/://g') | sha256sum |
          awk '{print $1}'
    662f0036cba13c2ddcf11acebf087ebe1b5e4044603d534dab60d32813adc1a5    
    

    Notez que le hachage est différent de ceux ci-dessus car je passe les deux adresses MAC renvoyées par ifconfig à sha256sum.

  2. Créez à la place un hachage basé sur les UUID de vos disques durs:

    $ blkid | grep -oP 'UUID="\K[^"]+' | sha256sum | awk '{print $1}'
    162296a587c45fbf807bb7e43bda08f84c56651737243eb4a1a32ae974d6d7f4
    
22
terdon

Tout d'abord, veuillez noter que le CPUID est définitivement pas un marqueur d'identification communément accessible pour tout système ultérieur à un Intel Pentium III. Bien que le hacher avec des adresses MAC puisse conduire à des marqueurs uniques, cela n'est dû qu'aux qualités uniques des MAC eux-mêmes et le CPUID dans ce cas n'est rien de plus que circonstanciel. De plus, le hachage résultant n'est probablement pas plus unique que l'UUID de la carte mère, ce qui est beaucoup plus facile à récupérer et le processus est beaucoup moins sujet à l'erreur. De wikipedia.org/wiki/cpuid :

EAX = 3 : Numéro de série du processeur

Voir aussi: Pentium III § Controverse sur les problèmes de confidentialité

Cela renvoie le numéro de série du processeur. Le numéro de série du processeur a été introduit sur Intel Pentium III, mais en raison de problèmes de confidentialité, cette fonctionnalité n'est plus implémentée sur les modèles ultérieurs (le bit de fonctionnalité PSN est toujours effacé). Les processeurs Efficeon et Crusoe de Transmeta offrent également cette fonctionnalité. Cependant, les processeurs AMD n'implémentent cette fonctionnalité dans aucun modèle de CPU.

Vous pouvez afficher vous-même un processeur analysé en faisant cat /proc/cpuinfo ou même simplement lscpu.

Cela vous donne toutes les adresses MAC pour les interfaces réseau reconnues par le noyau linux, je pense:

ip a | sed '\|^ *link[^ ]* |!d;s|||;s| .*||'

Il peut être nécessaire de filtrer cette liste si elle peut inclure des cartes réseau virtuelles avec des MAC générés de manière aléatoire. Vous pouvez le faire avec des indicateurs dans l'appel à ip directement. Voir ip a help pour savoir comment procéder.

Notez également que ce problème n'est pas propre à ip et doit également être traité si vous utilisez ifconfig, mais qu'il peut être traité de manière plus fiable avec ip - qui fait partie du iproute2 suite résea et est activement maintenu - qu'il ne peut avec ifconfig - qui est membre de net-tools package et a vu un Linux sortie en 2001 . En raison de la modification des fonctionnalités du noyau depuis sa dernière version, ifconfig est connu pour dénaturer certains indicateurs de fonctionnalité résea et son utilisation doit être évitée si possible.

Comprenez, cependant, que le filtrage avec des noms d'interface de noyau comme eth[0-9] n'est pas un moyen fiable de le faire, car ceux-ci peuvent changer en fonction de leur ordre de détection en parallèle par udev pendant le processus de démarrage. Veuillez consulter Noms de réseau prévisibles pour en savoir plus.

Parce que dmidecode n'est pas installé sur mon système, j'ai d'abord pensé hacher une liste de publications sur disque dur générées comme:

lsblk -nro SERIAL

Faire lsblk --help pour quelques indices sur le raffinement de cette liste - par type de disque, par exemple. Pensez également à lspci et/ou lsusb peut-être.

Les combiner est facile:

{ ip a | sed ... ; lsblk ... ; } | #abbreviated... for brevity...
    tr -dc '[:alnum:]' | #deletes all chars not alphanumeric - including newlines
    sha256sum #gets your hash

Comme vous m'avez informé que vous saisissez les ressources des utilisateurs de votre côté à leurs identifiants uniques, et que les disques durs ne peuvent pas être invoqués pour exister, j'ai pensé à changer de tactique.

Cela dit, j'ai de nouveau examiné le système de fichiers et trouvé le /sys/class/dmi/id dossier. J'ai vérifié quelques fichiers:

cat ./board_serial ./product_serial

###OUTPUT###
To be filled by O.E.M.
To be filled by O.E.M.

Cependant, celui-ci semble être assez bon, mais je ne publierai pas la sortie:

Sudo cat /sys/class/dmi/id/product_uuid

Je suppose que c'est là que dmidecode obtient de toute façon une grande partie de ses informations et en fait ça y ressemble . Selon man dmidecode vous pouvez également simplifier considérablement votre utilisation de cet outil en spécifiant l'argument:

dmidecode -s system-uuid

Plus simple encore, cependant, vous pouvez simplement lire le fichier. Notez que ce fichier particulier identifie spécifiquement une carte mère. Voici un extrait du patch du noyau 2007 qui implémentait à l'origine ces exportations vers le /sysfs système de fichiers virtuel:

+DEFINE_DMI_ATTR_WITH_SHOW(bios_vendor,      0444, DMI_BIOS_VENDOR);
+DEFINE_DMI_ATTR_WITH_SHOW(bios_version,         0444, DMI_BIOS_VERSION);
+DEFINE_DMI_ATTR_WITH_SHOW(bios_date,        0444, DMI_BIOS_DATE);
+DEFINE_DMI_ATTR_WITH_SHOW(sys_vendor,       0444, DMI_SYS_VENDOR);
+DEFINE_DMI_ATTR_WITH_SHOW(product_name,         0444, DMI_PRODUCT_NAME);
+DEFINE_DMI_ATTR_WITH_SHOW(product_version,   0444, DMI_PRODUCT_VERSION);
+DEFINE_DMI_ATTR_WITH_SHOW(product_serial,    0400, DMI_PRODUCT_SERIAL);
+DEFINE_DMI_ATTR_WITH_SHOW(product_uuid,         0400, DMI_PRODUCT_UUID);
+DEFINE_DMI_ATTR_WITH_SHOW(board_vendor,         0444, DMI_BOARD_VENDOR);
+DEFINE_DMI_ATTR_WITH_SHOW(board_name,       0444, DMI_BOARD_NAME);
+DEFINE_DMI_ATTR_WITH_SHOW(board_version,     0444, DMI_BOARD_VERSION);
+DEFINE_DMI_ATTR_WITH_SHOW(board_serial,         0400, DMI_BOARD_SERIAL);
+DEFINE_DMI_ATTR_WITH_SHOW(board_asset_tag,   0444, DMI_BOARD_ASSET_TAG);
+DEFINE_DMI_ATTR_WITH_SHOW(chassis_vendor,    0444, DMI_CHASSIS_VENDOR);
+DEFINE_DMI_ATTR_WITH_SHOW(chassis_type,         0444, DMI_CHASSIS_TYPE);
+DEFINE_DMI_ATTR_WITH_SHOW(chassis_version,   0444, DMI_CHASSIS_VERSION);
+DEFINE_DMI_ATTR_WITH_SHOW(chassis_serial,    0400, DMI_CHASSIS_SERIAL);
+DEFINE_DMI_ATTR_WITH_SHOW(chassis_asset_tag, 0444, DMI_CHASSIS_ASSET_TAG);

Vous pourrez peut-être utiliser ces données seules pour identifier le système - si la carte mère est suffisante. Mais vous pouvez combiner ces informations avec les MAC du système de la même manière que j'ai démontré que vous pourriez faire avec les disques durs:

Sudo sh <<\CMD | tr -dc '[:alnum:]' | sha256sum
        ip a | sed '\|^ *link[^ ]* |!d;s|||;s| .*||'
        cat /sys/class/dmi/id/product_uuid 
CMD

Le noyau Linux peut également générer des UUID pour vous:

cat /proc/sys/kernel/random/uuid #new random uuid each time file is read

Ou:

cat /proc/sys/kernel/random/boot_id #randomly generated per boot

Certes, il est généré de manière aléatoire et vous devrez repenser l'attribution des ID, mais c'est à peu près aussi simple que possible get au moins. Et cela devrait être assez solide si vous pouvez trouver un moyen de le saisir.

Enfin, sur les systèmes UEFI, cela devient beaucoup plus facile à faire - car chaque variable d'environnement du micrologiciel EFI comprend son propre UUID. La variable d'environnement {Platform,}LangCodes-${UUID} devrait être présent sur chaque système UEFI, devrait persister les redémarrages et même la plupart mises à niveau et modifications du micrologiciel, et tout système Linux avec le module efivarfs chargé peut répertorier l'un ou les deux noms aussi simplement que:

printf '%s\n' /sys/firmware/efi/efivars/*LangCodes-*

L'ancienne forme - LangCodes-${UUID} est apparemment maintenant obsolète , et sur les nouveaux systèmes devrait être PlatformLangCodes-${UUID} mais, selon les spécifications, l'un ou l'autre devrait être présent dans chaque système UEFI. Avec peu d'effort, vous pouvez définir vos propres variables persistantes de redémarrage, et peut-être utiliser davantage le générateur UUID du noyau de cette façon. Si vous êtes intéressé, regardez efitools .

24
mikeserv

De nombreuses distributions modernes expédient un fichier /etc/machine-id contenant une chaîne hexadécimale de 32 caractères probablement unique. Il provient de systemd, où ne page de manuel contient plus d'informations , et peut être approprié à votre objectif.

21
XZS

Sur de nombreuses machines Linux, le fichier /var/lib/dbus/machine-id Contient un identifiant unique pour chaque distribution Linux et est accessible par un appel à dbus_get_local_machine_id(). C'est probablement le même que le /etc/machine-id Mentionné ci-dessus. Il fonctionne également sur les installations virtuelles Linux. Je l'ai vérifié sur les distributions Ubuntu, SuSE et CentOS actuelles.

6
rankeney

Avez-vous besoin que l'ID de la machine change lorsque le matériel change? L'ID d'ordinateur est-il utilisé pour protéger quelque chose? La meilleure façon, je pense, d'avoir un ID d'ordinateur "cohérent" est de stocker une chaîne aléatoire quelque part sur le système et de cette façon si l'un des composants matériels change, l'ID d'ordinateur ne changera pas non plus. C'est également bon pour les systèmes virtualisés où l'accès au matériel est restreint et l'ID MAC est 00: 00: 00: 00

Essayez quelque chose comme ce script sh pour créer et obtenir l'ID:

#!/bin/sh
FILE="/etc/machine-id"

if [ ! -f $FILE ]; then
    cat /dev/urandom|tr -dc A-Z0-9|head -c32 > $FILE;
fi

cat $FILE;
0
ub3rst4r

Les autres réponses donnent un certain nombre de façons d'extraire les identifiants du matériel. Vous pouvez décider d'utiliser un seul matériel comme identifiant ou plusieurs. Cela est problématique si vous devez échanger ou remplacer arbitrairement des pièces de matériel.

Certaines personnes peuvent plutôt stocker id un ID généré sur leur disque dur (ou utiliser l'UUID) mais les disques durs peuvent être clones.

Les modules TPM et le démarrage sécurisé peuvent fournir un moyen de lier la carte mère et d'autres matériels avec une installation sur un disque dur.

C'est toujours un peu plus facile dans ces cas si vous donnez plus d'informations sur ce que vous voulez accomplir.

0
jgmjgm