générer un ID unique cohérent

20

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 puis-je analyser cette sortie?

uray
la source
4
Quel est exactement le problème que vous essayez de résoudre en utilisant cette méthode?
Darkhogg
1
Je suis avec Darkhogg. C'est généralement une mauvaise idée d'essayer de faire ce genre de choses aujourd'hui. La virtualisation a rendu inutile la pratique de lier des logiciels à du matériel physique. Il y a généralement une meilleure réponse si vous examinez attentivement vos besoins (c'est ce que Darkhogg cherche à faire).
Calphool
4
je ne l'utilise pas pour lier un logiciel à une machine, c'est une plate-forme d'extraction Linux qui doit s'identifier au service de contrôle et de surveillance du cloud, au lieu de nommer des milliers de plates-formes manuellement, j'ai besoin de les identifier de manière unique en utilisant leur ID matériel
uray
1
@ user77710: Si c'est le cas, alors vous souciez-vous vraiment du matériel? Pourquoi ne pas simplement générer un UUID sur la machine s'il n'en existe pas. C'est le but d'un UUID - ils sont universellement uniques (leurs chances de chevauchement sont astronomiquement improbables). serverfault.com/questions/103359/how-to-create-a-uuid-in-bash
Calphool
1
@JoeRounceville - Je ne voulais pas dire que SecureBoot lui-même était la solution - bien qu'il supporte les certificats auto-signés - mais plutôt sa méthode . Mais il utilise une API offerte par le micrologiciel du système - et tout système UEFI aura autant d'UUID que vous pourriez avoir déjà besoin de configurer au nom de chaque variable de micrologiciel - voir ma réponse. De plus, vous n'avez besoin d'aucune application - ou bash- pour vous générer un UUID sur n'importe quel Linux. cat /proc/sys/kernel/random/uuid.
mikeserv

Réponses:

21

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, eth0vous 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 for HWaddrdans la sortie de ifconfigmais 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 transmettant sha256sum, vous devriez pouvoir obtenir un nom unique et stable, quel que soit le NIC appelé:

    $ 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
terdon
la source
c'est bien, mais comment se débarrasser du tiret de fin '-'?
uray
@ user77710 voir la réponse mise à jour.
terdon
1
Je suppose que cpuid est pire ... wikipedia.org/wiki/cpuid
mikeserv
@mikeserv ah, oui en effet, je vois votre point. Merci, réponse modifiée.
terdon
Génère le même ID pour tous les OS invités sur le même hôte.
Nitinkumar Ambekar
23

Tout d'abord, veuillez noter que le CPUID n'est certainement pas un marqueur d'identification unique communément accessible pour un système ultérieur à un Intel Pentium III. Bien que le hacher avec des adresses MAC puisse certainement 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 processeur.

Vous pouvez afficher vous-même un processeur analysé en faisant cat /proc/cpuinfoou 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 à ipdirectement. Voir ip a helppour savoir comment procéder.

Notez également que ce problème n'est pas propre à ipet doit également être traité si vous utilisez ifconfig, mais qu'il peut être traité de manière plus fiable ip- qui fait partie de la iproute2suite réseau et est activement géré - qu'il ne peut le faire ifconfig- qui est membre du net-toolspackage et a vu une version Linux pour la dernière fois en 2001 . En raison de l'évolution des fonctionnalités du noyau depuis sa dernière version, il ifconfigest connu de mal déclarer certains indicateurs de fonctionnalité de réseau et son utilisation doit être évitée si possible.

Comprenez, cependant, que le filtrage avec des noms d'interface du 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 udevpendant le processus de démarrage. Veuillez consulter les noms de réseau prévisibles pour en savoir plus.

Parce qu'il dmidecoden'est pas installé sur mon système, j'ai d'abord pensé à hacher une liste de publications en série sur le disque dur générées comme:

lsblk -nro SERIAL

Faites lsblk --helpquelques indices pour affiner cette liste - par type de disque, par exemple. Considérez également lspciet / ou lsusbpeut - ê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 considéré, j'ai de nouveau examiné le système de fichiers et trouvé le /sys/class/dmi/iddossier. 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 m'attends à ce que ce soit là où dmidecodeobtient la plupart de ses informations de toute façon et en fait, cela lui ressemble . Selon man dmidecodevous, 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 correctif du noyau 2007 qui implémentait à l'origine ces exportations vers le /sysfssystè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 d' obtenir 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}doit être présente sur chaque système UEFI, doit persister les redémarrages et même la plupart des mises à niveau et modifications du micrologiciel, et tout système Linux avec le efivarfsmodule 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 désormais obsolète , et sur les systèmes plus récents, 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é, consultez efitools .

mikeserv
la source
il n'a même pas de disque dur ou de disque en cours d'exécution, sa plate-forme d'extraction, si vous ne savez pas ce que c'est, cette machine virtuelle diit.cz/sites/default/files/images/3988/… ne peut pas exécuter 6 GPU sur un seul carte mère
uray
de toute façon, il ne devrait jamais utiliser de nombre aléatoire car il a pour but de nommer la machine de manière cohérente, car ils démarrent l'ID ne devrait pas changer
uray
@ user77710 - Dang, mec, cette chose est cool. Est-ce une seule machine? Vous avez probablement raison, mais cela pourrait être possible avec un combo de XDMX et de Chrome - des trucs graphiques distribués. Quoi qu'il en soit, cela n'aurait pas d'importance - je l'avais à l'envers. Qui voudrait se battre avec son argent? Je pensais à quelque chose de licence de logiciel ou quelque chose - vous faites des comptes bancaires.
mikeserv
Voici quelques astuces astucieuses que vous avez obtenues, +1.
terdon
@terdon - le compliment est très apprécié, mais, pour la plupart, ce ne sont pas des astuces. ip2est spécifiquement conçu pour être analysé, et il se peut que je ne le fasse pas assez bien - je soupçonne que la même chose peut se faire presque sans grep/sed. On pourrait probablement faire la même chose aussi facilement avec udevadm. Et chaque nom de variable d'environnement EFI est conçu pour être identifié de manière unique pour exactement ce genre de situations.
mikeserv
19

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

XZS
la source
+1, @XZS, vous pouvez également ajouter ici les informations pertinentes à partir de l'URL.
Ramesh
1
C'est bien, et j'ai trouvé des informations similaires et je les ai presque utilisées ... mais j'étais déjà engagé sur une voie différente. Néanmoins, il convient de noter que cela est dbusspécifique, je pense, et change si un système d'exploitation est effacé / réinstallé.
mikeserv
C'est vraiment génial.
GeneCode
5

Sur de nombreuses machines Linux, le fichier /var/lib/dbus/machine-idcontient 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 celui /etc/machine-idmentionné ci-dessus. Il fonctionne également sur les installations Linux virtuelles. Je l'ai vérifié sur les distributions Ubuntu, SuSE et CentOS actuelles.

Rankeney
la source
1
Dans Fedora 19 + 20, ce fichier n'existe pas. Il est ici: /etc/machine-id.
slm
Peut-être que je n'étais pas assez clair. Mon point était que si vous ne le trouvez pas un endroit, regardez dans l'autre. Ou écrivez votre propre programme en utilisant l'appel de fonction.
rankeney
0

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 limité 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;
ub3rst4r
la source
Puisque votre /dev/urandomindique Linux de toute façon, vous pouvez simplement faire cat /proc/sys/kernel/random/uuid >$FILEce qui génère aléatoirement un UUID correctement formaté à chaque lecture. Néanmoins, toute persistance implémentée sur disque est sujette à suppression, et, à condition que cela soit acceptable et fourni dbusest installé, vous devriez probablement faire comme @XZS l'a suggéré à la place.
mikeserv
0

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 à la place 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.

jgmjgm
la source