menghasilkan ID unik mesin yang konsisten

20

Bisakah kita menghasilkan id unik untuk setiap PC, seperti uuuidgen, tetapi tidak akan pernah berubah kecuali ada perubahan perangkat keras? Saya sedang berpikir untuk menggabungkan CPUID dan MACADDR dan hash mereka untuk menghasilkan ID yang konsisten, tetapi saya tidak tahu bagaimana mem-parsing mereka menggunakan skrip bash, yang saya tahu adalah bagaimana saya bisa mendapatkan CPUID dari

dmidecode -t 4 | grep ID

dan

ifconfig | grep ether

maka saya perlu menggabungkan string hex dan hash menggunakan sha1 atau md5 untuk membuat string hex panjang tetap.
Bagaimana saya bisa menguraikan output itu?

uray
sumber
4
Apa sebenarnya masalah yang Anda coba selesaikan dengan menggunakan metode ini?
Darkhogg
1
Saya dengan Darkhogg. Biasanya merupakan ide yang buruk untuk mencoba melakukan hal-hal seperti ini pada zaman ini. Virtualisasi telah membuat praktik mengikat perangkat lunak ke perangkat keras fisik menjadi sia-sia. Biasanya ada jawaban yang lebih baik jika Anda memeriksa dengan cermat kebutuhan Anda (itulah yang dikendarai oleh Darkhogg).
Calphool
4
saya tidak menggunakan ini untuk mengikat perangkat lunak ke mesin, itu adalah rig penambangan linux yang perlu mengidentifikasi dirinya ke layanan kontrol dan pemantauan cloud, daripada menamai ribuan rig secara manual, saya perlu secara unik mengidentifikasi mereka menggunakan ID perangkat keras mereka
uray
1
@ user77710: Jika itu masalahnya, apakah Anda benar-benar peduli dengan perangkat keras? Mengapa tidak menghasilkan UUID di mesin jika tidak ada. Itulah poin dari UUID - mereka unik secara universal (kemungkinan tumpang tindih mereka secara astronomis tidak mungkin). serverfault.com/questions/103359/how-to-create-a-uuid-in-bash
Calphool
1
@ JoRounceville - Saya tidak bermaksud bahwa SecureBoot itu sendiri solusinya - meskipun mendukung sertifikat yang ditandatangani sendiri - tetapi metodenya . Tetapi ia menggunakan API yang ditawarkan oleh firmware sistem - dan sistem UEFI mana pun akan memiliki UUID sebanyak yang Anda perlukan sudah disiapkan atas nama setiap variabel firmware - lihat jawaban saya. Juga, Anda tidak memerlukan aplikasi apa pun - atau bash- untuk menghasilkan UUID di linux apa pun. cat /proc/sys/kernel/random/uuid.
mikeserv

Jawaban:

21

Bagaimana dengan dua ini:

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

Anda kemudian dapat menggabungkan dan hash dengan:

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

Untuk menghapus trailing dash, tambahkan satu pipa lagi:

$ 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

Seperti yang ditunjukkan @mikeserv dalam jawabannya , nama antarmuka dapat berubah di antara booting. Ini berarti bahwa apa yang dimaksud dengan eth0 hari ini mungkin adalah eth1 besok, jadi jika Anda eth0mengerti Anda mungkin akan mendapatkan alamat MAC yang berbeda pada bot yang berbeda. Sistem saya tidak berperilaku seperti ini sehingga saya tidak bisa benar-benar menguji tetapi solusi yang mungkin adalah:

  1. Terima HWaddroutput ifconfigtetapi simpan semuanya, tidak hanya yang sesuai dengan NIC tertentu. Sebagai contoh, pada sistem saya, saya memiliki:

    $ 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  

    Dengan mengambil kedua alamat MAC dan melewati mereka sha256sum, Anda harus bisa mendapatkan nama yang unik dan stabil, terlepas dari apa NIC disebut apa:

    $ 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    

    Perhatikan bahwa hash berbeda dari yang di atas karena saya lewat kedua alamat MAC dikembalikan oleh ifconfigke sha256sum.

  2. Buat hash berdasarkan UUID hard drive Anda sebagai gantinya:

    $ blkid | grep -oP 'UUID="\K[^"]+' | sha256sum | awk '{print $1}'
    162296a587c45fbf807bb7e43bda08f84c56651737243eb4a1a32ae974d6d7f4
terdon
sumber
itu bagus, tapi bagaimana cara menghilangkan trailing dash '-'?
uray
@ user77710 lihat jawaban yang diperbarui.
terdon
1
Saya kira cpuid lebih buruk ... wikipedia.org/wiki/cpuid
mikeserv
@ ahmerverv, ya memang, saya mengerti maksud Anda. Terima kasih, jawabannya diedit.
terdon
Menghasilkan ID yang sama untuk semua OS tamu di host yang sama.
Nitinkumar Ambekar
23

Pertama, harap perhatikan bahwa CPUID jelas bukan penanda pengidentifikasi unik yang dapat diakses secara umum untuk sistem apa pun selain Intel Pentium III. Meskipun hashing dengan alamat MAC tentu saja dapat menyebabkan penanda unik, ini hanya disebabkan oleh kualitas unik dari MAC itu sendiri dan CPUID dalam hal ini tidak lebih dari keadaan langsung. Selain itu, hash yang dihasilkan tidak akan lebih unik dari UUID motherboard, dan itu jauh lebih mudah untuk diambil dan prosesnya jauh lebih mudah untuk dikorbankan. Dari wikipedia.org/wiki/cpuid :

EAX = 3 : Nomor Seri Prosesor

Lihat juga: Pentium III § Kontroversi tentang masalah privasi

Ini mengembalikan nomor seri prosesor. Nomor seri prosesor diperkenalkan pada Intel Pentium III, tetapi karena masalah privasi, fitur ini tidak lagi diterapkan pada model selanjutnya (bit fitur PSN selalu dihapus). Prosesor Efficeon dan Crusoe dari Transmeta juga menyediakan fitur ini. Namun CPU AMD, jangan mengimplementasikan fitur ini dalam model CPU apa pun.

Anda dapat melihat cpuid yang diurai sendiri dengan melakukan cat /proc/cpuinfoatau bahkan adil lscpu.

Ini memberi Anda semua alamat MAC untuk antarmuka jaringan yang dikenali oleh kernel linux, saya pikir:

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

Mungkin perlu memfilter daftar itu jika mungkin menyertakan nics virtual dengan MAC yang dibuat secara acak. Anda dapat melakukan ini dengan bendera dalam panggilan untuk ipsecara langsung. Lihat ip a helpinformasi tentang cara melakukannya.

Perhatikan juga bahwa masalah ini tidak unik ipdan harus juga ditangani jika Anda menggunakannya ifconfig, tetapi dapat ditangani dengan lebih andal ip- yang merupakan bagian dari rangkaian iproute2jaringan dan dipelihara secara aktif - daripada yang dapat dilakukan ifconfig- yang merupakan anggota dari net-toolspaket dan melihat lalu Linux rilis pada tahun 2001 . Karena perubahan fitur di kernel sejak rilis terakhir, ifconfigdiketahui salah melaporkan beberapa tanda fitur jaringan dan penggunaannya harus dihindari jika memungkinkan.

Namun, pahami bahwa pemfilteran dengan nama antarmuka kernel seperti eth[0-9]bukan cara yang dapat diandalkan untuk melakukan hal itu, karena ini dapat berubah berdasarkan urutan deteksi paralel mereka udevselama proses boot. Silakan lihat Nama Jaringan yang Dapat Diprediksi untuk informasi lebih lanjut tentang itu.

Karena dmidecodetidak diinstal pada sistem saya, saya awalnya berpikir untuk hash daftar serial hard disk yang dihasilkan seperti:

lsblk -nro SERIAL

Lakukan lsblk --helpuntuk beberapa petunjuk tentang memperbaiki daftar itu - menurut jenis disk, katakanlah. Pertimbangkan juga lspcidan / atau lsusbmungkin.

Menggabungkannya mudah:

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

Ketika Anda memberi tahu saya bahwa Anda memasukkan sumber daya pengguna di ujung Anda ke id uniknya, dan hard disk tidak dapat diandalkan, saya pikir akan mengubah taktik saya.

Yang dipertimbangkan, saya melihat ke sistem file lagi dan menemukan /sys/class/dmi/idfolder. Saya memeriksa beberapa file:

cat ./board_serial ./product_serial

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

Namun, yang ini sepertinya cukup bagus, tapi saya tidak akan mempublikasikan hasilnya:

sudo cat /sys/class/dmi/id/product_uuid

Saya berharap di situlah dmidecodemendapatkan banyak informasi dan sebenarnya itu memang terlihat seperti itu . Menurut man dmidecodeAnda, Anda juga dapat menyederhanakan penggunaan alat itu dengan banyak dengan menetapkan argumen:

dmidecode -s system-uuid

Lebih sederhana lagi, Anda hanya bisa membaca file. Perhatikan bahwa file khusus ini mengidentifikasi motherboard. Berikut adalah kutipan dari tambalan kernel 2007 yang awalnya menerapkan ekspor ini ke /sysfssistem file virtual:

+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);

Anda mungkin dapat menggunakan data itu sendiri untuk mengidentifikasi sistem - jika motherboard sudah cukup. Tetapi Anda dapat menggabungkan informasi ini dengan MAC sistem dengan cara yang sama seperti yang saya tunjukkan yang mungkin Anda lakukan dengan hard disk:

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

Kernel Linux juga dapat menghasilkan UUID untuk Anda:

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

Atau:

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

Memang, ini dibuat secara acak dan Anda harus memikirkan kembali penugasan ID, tapi itu semudah mendapatkan setidaknya. Dan itu harus cukup solid jika Anda dapat menemukan cara untuk menguncinya.

Terakhir, pada sistem UEFI ini menjadi jauh lebih mudah dilakukan - karena setiap variabel lingkungan firmware EFI menyertakan UUID sendiri. Variabel lingkungan {Platform,}LangCodes-${UUID}harus ada pada setiap sistem UEFI, harus bertahan reboot dan bahkan sebagian besar pembaruan dan modifikasi firmware, dan sistem Linux apa pun dengan efivarfsmodul yang dimuat dapat mencantumkan salah satu atau kedua nama hanya dengan:

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

Bentuk yang lebih lama - LangCodes-${UUID}tampaknya sekarang sudah tidak digunakan lagi , dan pada sistem yang lebih baru seharusnya PlatformLangCodes-${UUID}tetapi, menurut spesifikasi, satu atau yang lain harus ada di setiap sistem UEFI. Dengan sedikit usaha, Anda dapat mendefinisikan variabel persisten reboot Anda sendiri, dan mungkin memanfaatkan generator UUID kernel dengan cara itu. Jika tertarik, lihatlah efitools .

mikeserv
sumber
bahkan tidak memiliki harddisk atau disk apa pun yang berjalan, rig penambangannya, jika Anda tidak tahu apa yang dilihatnya diit.cz/sites/default/files/images/3988/... mesin virtual ini tidak dapat menjalankan 6 GPU secara tunggal motherboard
uray
lagi pula itu tidak boleh menggunakan nomor acak karena itu mengalahkan tujuan penamaan mesin secara konsisten, karena mereka boot ID tidak boleh berubah
uray
@ user77710 - Sial, bung, benda itu keren. Apakah itu satu mesin? Mungkin Anda benar, tetapi mungkin saja dengan beberapa kombo XDMX dan Chromium - beberapa hal grafik terdistribusi. Bagaimanapun, itu tidak masalah - saya mendapatkannya mundur. Siapa yang ingin menghamburkan diri dari uang mereka? Saya sedang memikirkan beberapa hal lisensi perangkat lunak atau sesuatu - Anda sedang melakukan rekening bank.
mikeserv
Ada beberapa trik bagus yang Anda dapatkan di sana, +1.
terdon
@terdon - pujian itu sangat dihargai, tetapi, sebagian besar, itu bukan trik. ip2secara khusus dirancang untuk diuraikan, dan mungkin saya tidak melakukannya dengan cukup baik - saya kira hal yang sama dapat dilakukan hampir tanpa grep/sed. Mungkin hal yang sama bisa dilakukan dengan mudah udevadm. Dan setiap nama variabel lingkungan EFI dirancang untuk diidentifikasi secara unik untuk situasi seperti ini.
mikeserv
19

Banyak distribusi modern mengirimkan file yang /etc/machine-idberisi string 32-karakter heksadesimal unik. Itu berasal dari systemd, di mana halaman manual memiliki lebih banyak informasi , dan mungkin sesuai untuk tujuan Anda.

XZS
sumber
+1, @XZS, Anda juga dapat menambahkan informasi yang relevan dari URL di sini.
Ramesh
1
Ini bagus, dan saya menemukan informasi serupa dan hampir menggunakannya ... tetapi saya sudah berkomitmen untuk rute yang berbeda. Namun, perlu dicatat bahwa ini dbusspesifik, saya pikir, dan berubah jika sistem operasi dihapus / diinstal ulang.
mikeserv
Ini sangat sangat mengagumkan.
GeneCode
5

Pada banyak mesin Linux, file tersebut /var/lib/dbus/machine-idberisi id unik untuk setiap distribusi Linux dan dapat diakses melalui panggilan dbus_get_local_machine_id(). Ini mungkin sama dengan yang /etc/machine-iddisebutkan di atas. Ini bekerja pada instalasi Linux virtual juga. Saya telah memeriksanya di distribusi Ubuntu, SuSE dan CentOS saat ini.

peringkat
sumber
1
Di Fedora 19 + 20 file itu tidak ada. Itu di sini: /etc/machine-id.
slm
Mungkin saya tidak cukup jelas. Maksud saya adalah jika Anda tidak menemukannya di satu tempat, lihat di tempat lain. Atau tulis program Anda sendiri menggunakan pemanggilan fungsi.
rankeney
0

Apakah Anda memerlukan ID mesin untuk berubah ketika perangkat keras berubah? Apakah ID mesin digunakan untuk melindungi sesuatu? Cara terbaik yang saya yakini memiliki ID mesin "konsisten" adalah dengan menyimpan string acak di suatu tempat di sistem dan dengan cara itu jika ada perubahan perangkat keras, maka ID mesin tidak akan berubah. Ini juga baik untuk sistem tervirtualisasi di mana akses perangkat keras dibatasi dan ID MAC adalah 00: 00: 00: 00

Coba sesuatu seperti skrip sh ini untuk membuat dan mendapatkan 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
sumber
Karena Anda /dev/urandommenunjukkan Linux, Anda hanya dapat melakukan cat /proc/sys/kernel/random/uuid >$FILEyang secara acak menghasilkan UUID yang diformat dengan benar pada setiap pembacaan. Namun, setiap kegigihan yang diimplementasikan disk dapat dihapus, dan, asalkan dapat diterima, dan asalkan dbusdiinstal, Anda mungkin harus melakukan seperti yang disarankan oleh @XZS.
mikeserv
0

Jawaban lain memberikan sejumlah cara mengekstraksi id dari perangkat keras. Anda dapat memutuskan untuk menggunakan satu perangkat keras sebagai pengenal atau banyak. Ini bermasalah jika Anda perlu menukar atau mengganti perangkat keras secara sewenang-wenang.

Beberapa orang mungkin malah menyimpan id id yang dihasilkan di harddrive mereka (atau menggunakan UUID) tetapi harddrides dapat dikloning.

Modul TPM dan boot aman mungkin menyediakan sarana untuk mengikat motherboard dan perangkat keras lainnya dengan instalasi ke harddisk.

Selalu lebih mudah dalam kasus ini jika Anda memberikan informasi lebih lanjut tentang apa yang ingin Anda capai.

jgmjgm
sumber