In primo luogo, si ricorda che il CPUID è sicuramente non è un comunemente accessibili marcatore che identifica in modo univoco per qualsiasi sistema entro e non oltre un processore Intel Pentium III. Mentre l'hash con gli indirizzi MAC può certamente portare a marcatori univoci, ciò è dovuto solo alle qualità uniche dei MAC stessi e il CPUID in questo caso non è altro che circostanziale. Inoltre, è probabile che l'hash risultante non sia più unico dell'UUID della scheda madre, e questo è molto più facile da recuperare e il processo è molto meno soggetto a errori. Da wikipedia.org/wiki/cpuid :
EAX = 3 : numero di serie del processore
Vedi anche: Pentium III § Polemiche su problemi di privacy
Ciò restituisce il numero seriale del processore. Il numero di serie del processore è stato introdotto su Intel Pentium III, ma a causa di problemi di privacy, questa funzione non è più implementata sui modelli successivi (il bit di funzionalità PSN viene sempre cancellato). Anche i processori Efficeon e Crusoe di Transmeta offrono questa funzionalità. Le CPU AMD, tuttavia, non implementano questa funzione in nessun modello di CPU.
Puoi visualizzare un cpuid analizzato da cat /proc/cpuinfo
solo o semplicemente lscpu
.
Questo ti dà tutti gli indirizzi MAC per le interfacce di rete riconosciute dal kernel Linux, penso:
ip a | sed '\|^ *link[^ ]* |!d;s|||;s| .*||'
Potrebbe essere necessario filtrare tale elenco se potrebbe includere reti virtuali con MAC generati casualmente. Puoi farlo direttamente con i flag nella chiamata ip
. Vedere ip a help
per informazioni su come farlo.
Si noti inoltre che questo problema non è univoco ip
e deve essere affrontato anche se lo si utilizza ifconfig
, ma che può essere gestito in modo più affidabile ip
- che fa parte della iproute2
suite di rete e viene attivamente gestito - rispetto a quanto può fare ifconfig
- di cui è membro del net-tools
pacchetto e ha visto l'ultima versione di Linux nel 2001 . A causa delle modifiche alle funzionalità del kernel dalla sua ultima versione, ifconfig
è noto che riporta erroneamente alcuni flag delle funzionalità di rete e il suo uso dovrebbe essere evitato, se possibile.
Comprendi, tuttavia, che il filtro con nomi di interfaccia del kernel come eth[0-9]
non è un mezzo affidabile per farlo, poiché questi possono cambiare in base al loro ordine di rilevamento parallelo udev
durante il processo di avvio. Per ulteriori informazioni, vedere Nomi di rete prevedibili .
Poiché dmidecode
non è installato sul mio sistema, all'inizio ho pensato di creare un elenco di numeri di serie di dischi rigidi generati come:
lsblk -nro SERIAL
Fallo lsblk --help
per alcuni indizi sul perfezionamento di tale elenco, ad esempio per tipo di disco. Considera anche lspci
e / o lsusb
forse.
Combinarli è facile:
{ ip a | sed ... ; lsblk ... ; } | #abbreviated... for brevity...
tr -dc '[:alnum:]' | #deletes all chars not alphanumeric - including newlines
sha256sum #gets your hash
Dato che mi hai informato che stai mettendo le risorse dell'utente al tuo posto ai loro ID univoci, e non è possibile fare affidamento sul fatto che i dischi rigidi esistano, ho pensato di cambiare il mio approccio.
Detto questo, ho guardato di nuovo nel filesystem e ho trovato la /sys/class/dmi/id
cartella. Ho controllato alcuni dei file:
cat ./board_serial ./product_serial
###OUTPUT###
To be filled by O.E.M.
To be filled by O.E.M.
Tuttavia, questo sembra essere abbastanza buono, ma non pubblicherò l'output:
sudo cat /sys/class/dmi/id/product_uuid
Mi aspetto che sia lì che dmidecode
ottiene gran parte delle sue informazioni e in effetti sembra proprio così . Secondo man dmidecode
te puoi anche semplificare molto il tuo utilizzo di questo strumento specificando l'argomento:
dmidecode -s system-uuid
Più semplice, tuttavia, puoi semplicemente leggere il file. Si noti che questo particolare file identifica in modo specifico una scheda madre. Ecco un estratto dalla patch del kernel 2007 che originariamente implementava queste esportazioni nel /sysfs
filesystem virtuale:
+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);
Potresti essere in grado di utilizzare quei dati da solo per identificare il sistema, se la scheda madre è sufficiente. Ma puoi combinare queste informazioni con i MAC del sistema nello stesso modo in cui ho dimostrato che potresti fare con i dischi rigidi:
sudo sh <<\CMD | tr -dc '[:alnum:]' | sha256sum
ip a | sed '\|^ *link[^ ]* |!d;s|||;s| .*||'
cat /sys/class/dmi/id/product_uuid
CMD
Il kernel Linux può anche generare UUID per te:
cat /proc/sys/kernel/random/uuid #new random uuid each time file is read
O:
cat /proc/sys/kernel/random/boot_id #randomly generated per boot
Certo, viene generato casualmente e dovrai ripensare l'assegnazione degli ID, ma è almeno tanto semplice quanto ottenere . E dovrebbe essere abbastanza solido se riesci a trovare un modo per chiave.
Infine, sui sistemi UEFI questo diventa molto più facile da fare, poiché ogni variabile di ambiente del firmware EFI include il proprio UUID. La variabile d'ambiente {Platform,}LangCodes-${UUID}
dovrebbe essere presente su ogni sistema UEFI, dovrebbe persistere al riavvio e persino alla maggior parte degli aggiornamenti e modifiche del firmware, e qualsiasi sistema Linux con il efivarfs
modulo caricato può elencare uno o entrambi i nomi semplicemente come:
printf '%s\n' /sys/firmware/efi/efivars/*LangCodes-*
La forma più vecchia - LangCodes-${UUID}
è apparentemente ora deprecata , e sui sistemi più recenti dovrebbe essere PlatformLangCodes-${UUID}
ma, secondo le specifiche, l'una o l'altra dovrebbe essere presente in ogni sistema UEFI. Con un piccolo sforzo, puoi definire il tuo riavvio delle variabili persistenti e forse fare un uso maggiore del generatore UUID del kernel in quel modo. Se interessati, guarda gli efitools .