tạo ID duy nhất của máy nhất quán


20

Chúng tôi có thể tạo một id duy nhất cho mỗi PC, một cái gì đó như uuuidgen, nhưng nó sẽ không bao giờ thay đổi trừ khi có thay đổi phần cứng? Tôi đã suy nghĩ về việc hợp nhất CPUID và MACADDR và ​​băm chúng để tạo ID nhất quán, nhưng tôi không biết làm thế nào để phân tích chúng bằng cách sử dụng tập lệnh bash, điều tôi biết là làm cách nào tôi có thể lấy CPUID từ

dmidecode -t 4 | grep ID

ifconfig | grep ether

sau đó tôi cần kết hợp các chuỗi hex đó và băm chúng bằng cách sử dụng sha1 hoặc md5 để tạo chuỗi hex có độ dài cố định.
Làm thế nào tôi có thể phân tích đầu ra đó?


4
Chính xác vấn đề bạn đang cố gắng giải quyết bằng phương pháp này là gì?
Darkhogg

1
Tôi với Darkhogg. Nói chung, đó là một ý tưởng tồi để cố gắng làm những điều này trong thời đại ngày nay. Ảo hóa đã làm cho việc thực hành phần mềm ràng buộc với loại phần cứng vật lý trở nên vô nghĩa. Thường có câu trả lời tốt hơn nếu bạn kiểm tra chặt chẽ các yêu cầu của bạn (đó là những gì Darkhogg đang lái xe).
Calphool

4
Tôi không sử dụng phần mềm này để liên kết một phần mềm với máy, đó là giàn khai thác linux cần nhận dạng chính nó với dịch vụ giám sát và kiểm soát đám mây, thay vì đặt tên hàng ngàn giàn theo cách thủ công, tôi cần xác định duy nhất chúng bằng ID phần cứng của chúng
uray

1
@ user77710: Nếu đó là trường hợp, vậy bạn có thực sự quan tâm đến phần cứng không? Tại sao không chỉ tạo UUID trên máy nếu không tồn tại. Đó là điểm của một UUID - chúng là duy nhất trên toàn cầu (tỷ lệ trùng lặp của chúng là không thể thực hiện được về mặt thiên văn). serverfault.com/questions/103359/how-to-create-a-uuid-in-bash
Calphool

1
@JoeRounceville - Tôi không có ý đó SecureBoot bản thân là giải pháp - mặc dù nó không hỗ trợ chứng chỉ tự ký - mà đúng hơn là nó phương pháp . Nhưng nó sử dụng API do phần sụn của hệ thống cung cấp - và bất kỳ hệ thống UEFI nào cũng sẽ có nhiều UUID như bạn có thể cần thiết lập theo tên của từng biến phần sụn - xem câu trả lời của tôi. Ngoài ra, bạn không cần bất kỳ ứng dụng nào - hoặc bash- để tạo UUID cho bạn trên bất kỳ linux nào. cat /proc/sys/kernel/random/uuid.
mikeerv

Câu trả lời:


21

Thế còn hai cái này:

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

Sau đó, bạn có thể kết hợp và băm chúng với:

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

Để xóa dấu gạch ngang, thêm một ống nữa:

$ 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

Như @mikeerv chỉ ra trong câu trả lời của anh ấy , tên giao diện có thể thay đổi giữa các lần khởi động. Điều này có nghĩa là eth0 hôm nay có thể là eth1 vào ngày mai, vì vậy nếu bạn grep cho eth0bạn có thể nhận được một địa chỉ MAC khác nhau trên các bốt khác nhau. Hệ thống của tôi không hoạt động theo cách này vì vậy tôi thực sự không thể kiểm tra nhưng các giải pháp khả thi là:

  1. Grep cho HWaddrtrong đầu ra của ifconfignhưng giữ tất cả chúng, không chỉ là một tương ứng với một NIC cụ thể. Ví dụ: trên hệ thống của tôi, tôi có:

    $ 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  

    Bằng cách lấy cả hai địa chỉ MAC và chuyển chúng qua sha256sum, bạn sẽ có thể có được một tên duy nhất và ổn định, bất kể NIC được gọi là gì:

    $ 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    

    Lưu ý rằng các hash là khác biệt so với những người ở trên vì tôi đi qua cả hai địa chỉ MAC được trả về bởi ifconfigđến sha256sum.

  2. Thay vào đó, hãy tạo một hàm băm dựa trên UUID của (các) ổ cứng của bạn:

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

nó tốt, nhưng làm thế nào để thoát khỏi dấu gạch ngang '-'?
uray

@ user77710 xem câu trả lời cập nhật.
terdon

1
Tôi đoán cpuid tệ hơn ... wikipedia.org/wiki/cpuid
mikeerv

@mikeerv ah, đúng vậy, tôi thấy quan điểm của bạn. Cảm ơn, trả lời chỉnh sửa.
terdon

Tạo cùng một ID cho tất cả các hệ điều hành khách trên cùng một máy chủ.
Nitinkumar Ambekar

23

Đầu tiên, xin lưu ý rằng CPUID chắc chắn không phải là dấu hiệu nhận dạng duy nhất có thể truy cập phổ biến cho bất kỳ hệ thống nào muộn hơn Intel Pentium III. Mặc dù băm nó với các địa chỉ MAC chắc chắn có thể dẫn đến các điểm đánh dấu duy nhất, điều này chỉ là do các phẩm chất duy nhất của chính MAC và CPUID trong trường hợp đó không có gì khác hơn là hoàn cảnh. Hơn nữa, hàm băm kết quả không có khả năng độc đáo hơn UUID của bo mạch chủ, và điều đó dễ lấy hơn rất nhiều và quá trình này ít bị lỗi hơn. Từ wikipedia.org/wiki/cpuid :

EAX = 3 : Số sê-ri của bộ xử lý

Xem thêm: Pentium III § Tranh cãi về các vấn đề riêng tư

Điều này trả về số sê-ri của bộ xử lý. Số sê-ri bộ xử lý đã được giới thiệu trên Intel Pentium III, nhưng do lo ngại về quyền riêng tư, tính năng này không còn được triển khai trên các mẫu máy sau này (bit tính năng PSN luôn bị xóa). Bộ xử lý Efficeon và Crusoe của Transmeta cũng cung cấp tính năng này. Tuy nhiên, CPU AMD không triển khai tính năng này trong bất kỳ mẫu CPU nào.

Bạn có thể xem một cpuid được phân tích bằng cách thực hiện cat /proc/cpuinfohoặc thậm chí chỉ lscpu.

Điều này giúp bạn có tất cả các địa chỉ MAC cho các giao diện mạng được nhận dạng bởi kernel linux, tôi nghĩ:

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

Có thể cần phải lọc danh sách đó nếu nó có thể bao gồm các ảnh ảo với các MAC được tạo ngẫu nhiên. Bạn có thể làm điều này với cờ trong cuộc gọi đến iptrực tiếp. Xem ip a helpđể biết thông tin về cách làm như vậy.

Cũng lưu ý rằng vấn đề này không phải là duy nhất ipvà cũng phải được xử lý nếu bạn sử dụng ifconfig, nhưng nó có thể được xử lý một cách đáng tin cậy hơn ip- là một phần của bộ iproute2mạng và được duy trì tích cực - hơn là với ifconfigmột thành viên của net-toolsgói và lần cuối cùng thấy một bản phát hành Linux vào năm 2001 . Do thay đổi các tính năng trong kernel kể từ lần phát hành cuối cùng của nó, ifconfigđược biết là báo cáo sai một số cờ tính năng mạng và nên tránh sử dụng nó nếu có thể.

Tuy nhiên, hiểu rằng việc lọc với các tên giao diện kernel như eth[0-9]không phải là một phương tiện đáng tin cậy để làm như vậy, vì chúng có thể thay đổi dựa trên thứ tự phát hiện song song của chúng udevtrong quá trình khởi động. Vui lòng xem Tên Mạng Dự đoán để biết thêm về điều đó.

Bởi vì dmidecodekhông được cài đặt trên hệ thống của tôi, ban đầu tôi nghĩ sẽ băm một danh sách các sê-ri đĩa cứng được tạo như sau:

lsblk -nro SERIAL

Làm lsblk --helpcho một số manh mối về tinh chỉnh danh sách đó - theo loại đĩa, nói. Cũng xem xét lspcivà / hoặc lsusbcó thể.

Kết hợp chúng thật dễ dàng:

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

Như bạn đã thông báo cho tôi, bạn đang khóa tài nguyên của người dùng vào cuối id của họ và các đĩa cứng không thể dựa vào sự tồn tại, tôi nghĩ sẽ thay đổi chiến thuật của mình.

Điều đó xem xét, tôi nhìn vào hệ thống tập tin một lần nữa và tìm thấy /sys/class/dmi/idthư mục. Tôi đã kiểm tra một vài trong số các tập tin:

cat ./board_serial ./product_serial

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

Tuy nhiên, cái này có vẻ khá tốt, nhưng tôi sẽ không công bố đầu ra:

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

Tôi hy vọng đó là nơi dmidecodenhận được nhiều thông tin của nó và thực tế nó trông giống như vậy . Theo man dmidecodebạn cũng có thể đơn giản hóa việc sử dụng công cụ đó rất nhiều bằng cách chỉ định đối số:

dmidecode -s system-uuid

Tuy nhiên, đơn giản hơn, bạn chỉ có thể đọc tệp. Lưu ý rằng tập tin cụ thể này xác định cụ thể một bo mạch chủ. Đây là một đoạn trích từ bản vá nhân năm 2007 ban đầu thực hiện các bản xuất này sang /sysfshệ thống tệp ảo:

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

Bạn có thể sử dụng dữ liệu đó một mình để xác định hệ thống - nếu bo mạch chủ là đủ. Nhưng bạn có thể kết hợp thông tin này với MAC của hệ thống giống như cách tôi đã chứng minh bạn có thể làm với đĩa cứng:

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

Nhân Linux cũng có thể tạo UUID cho bạn:

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

Hoặc là:

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

Cấp, nó được tạo ngẫu nhiên và bạn sẽ phải suy nghĩ lại về việc gán ID, nhưng nó dễ dàng như vậy để có được ít nhất. Và nó sẽ khá vững chắc nếu bạn có thể tìm một phương tiện để khóa nó.

Cuối cùng, trên các hệ thống UEFI, điều này trở nên dễ thực hiện hơn - vì mọi biến môi trường phần sụn EFI đều bao gồm UUID của chính nó. Biến môi trường {Platform,}LangCodes-${UUID}phải có mặt trên mọi hệ thống UEFI, nên tiếp tục khởi động lại và thậm chí hầu hết các nâng cấp và sửa đổi phần sụn, và bất kỳ hệ thống Linux nào có efivarfsmô-đun được tải đều có thể liệt kê một hoặc cả hai tên đơn giản như:

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

Hình thức cũ hơn - LangCodes-${UUID}hiện rõ ràng không dùng nữa và trên các hệ thống mới hơn nên PlatformLangCodes-${UUID}, nhưng theo thông số kỹ thuật, cái này hay cái kia nên có trong mọi hệ thống UEFI. Với một chút nỗ lực, bạn có thể xác định các biến liên tục khởi động lại của riêng mình và có thể sử dụng nhiều hơn trình tạo UUID của kernel theo cách đó. Nếu quan tâm, hãy nhìn vào efitools .


Nó thậm chí không có ổ cứng hoặc bất kỳ ổ đĩa nào đang chạy, giàn khai thác của nó, nếu bạn không biết nó đang xem diit.cz/sites/default/files/images/3988/ máy ảo nào không thể chạy 6 GPU trên một bo mạch chủ
uray 16/07/14

dù sao thì nó cũng không bao giờ nên sử dụng bất kỳ số ngẫu nhiên nào vì nó đánh bại mục đích đặt tên máy một cách nhất quán, vì chúng khởi động ID không nên thay đổi
uray 16/07/14

@ user77710 - Dang, anh bạn, điều đó thật tuyệt. Có phải đó là một cái máy không? Có lẽ bạn đúng, nhưng có thể với một số kết hợp XDMX và Chromium - một số công cụ đồ họa phân tán. Dù sao, nó sẽ không thành vấn đề - tôi đã có nó ngược. Ai muốn đánh bại tiền của họ? Tôi đã suy nghĩ một số điều cấp phép phần mềm hoặc một cái gì đó - bạn đang làm tài khoản ngân hàng.
mikeerv

Đó là một số thủ thuật tiện lợi mà bạn có ở đó, +1.
terdon

@terdon - Lời khen được đánh giá cao, nhưng, đối với hầu hết các phần, chúng không phải là thủ thuật. ip2được thiết kế đặc biệt để được phân tích cú pháp và có thể là tôi không làm tốt lắm - tôi nghi ngờ điều tương tự có thể được thực hiện gần như không có grep/sed. Có lẽ điều tương tự có thể được thực hiện dễ dàng với udevadm. Và mỗi tên biến môi trường EFI được thiết kế để được xác định duy nhất cho chính xác các loại tình huống này.
mikeerv

19

Nhiều bản phân phối hiện đại gửi một tệp /etc/machine-idchứa chuỗi 32 ký tự thập lục phân có lẽ là duy nhất. Nó bắt nguồn từ systemd, trong đó một trang có nhiều thông tin hơn và có thể phù hợp với mục đích của bạn.


+1, @XZS, bạn cũng có thể thêm thông tin liên quan từ URL tại đây.
Ramesh

1
Điều này là tốt, và tôi đã tìm thấy thông tin tương tự và gần như đã sử dụng nó ... nhưng tôi đã cam kết với một tuyến đường khác. Tuy nhiên, tôi cần lưu ý rằng điều này là dbuscụ thể, tôi nghĩ và thay đổi nếu một hệ điều hành bị xóa / cài đặt lại.
mikeerv

Điều này là khá đáng sợ.
GeneCode

5

Trên nhiều máy Linux, tệp /var/lib/dbus/machine-idchứa một id duy nhất cho mỗi bản phân phối Linux và có thể được truy cập bằng một cuộc gọi đếndbus_get_local_machine_id() . Điều này có lẽ giống như /etc/machine-idđã đề cập ở trên. Nó cũng hoạt động trên các cài đặt Linux ảo. Tôi đã kiểm tra nó trên các bản phân phối Ubuntu, SuSE và CentOS hiện tại.


1
Trong Fedora 19 + 20 tệp đó không tồn tại. Nó ở đây : /etc/machine-id.
slm

Có lẽ tôi đã không đủ rõ ràng. Quan điểm của tôi là nếu bạn không tìm thấy nó ở một nơi, hãy tìm ở nơi khác. Hoặc viết chương trình của riêng bạn bằng cách sử dụng chức năng gọi.
Rankeney

0

Bạn có cần ID máy để thay đổi khi phần cứng thay đổi không? Là ID máy đang được sử dụng để bảo vệ một cái gì đó? Cách tốt nhất mà tôi tin là có ID máy "nhất quán" là lưu trữ một chuỗi ngẫu nhiên ở đâu đó trên hệ thống và theo cách đó nếu bất kỳ phần cứng nào thay đổi, thì ID máy sẽ không thay đổi. Điều này cũng tốt cho các hệ thống ảo hóa khi quyền truy cập phần cứng bị hạn chế và MAC ID là 00: 00: 00: 00

Hãy thử một cái gì đó như tập lệnh sh này để tạo và lấy 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;

/dev/urandomdù sao bạn cũng chỉ ra Linux, nên bạn chỉ có thể cat /proc/sys/kernel/random/uuid >$FILEtạo ngẫu nhiên một UUID được định dạng chính xác trên mỗi lần đọc. Tuy nhiên, bất kỳ sự kiên trì thực hiện trên đĩa nào cũng có thể bị xóa và, với điều kiện là chấp nhận được và được cung cấp đã dbusđược cài đặt, có lẽ bạn nên làm như @XZS đã đề xuất thay thế.
mikeerv

0

Các câu trả lời khác đưa ra một số cách trích xuất id từ phần cứng. Bạn có thể quyết định sử dụng một phần cứng làm định danh hoặc nhiều phần cứng. Đây là vấn đề nếu bạn cần trao đổi hoặc thay thế các phần cứng tùy ý.

Thay vào đó, một số người có thể lưu trữ id một id được tạo trên ổ cứng (hoặc sử dụng UUID) nhưng các ổ cứng có thể được sao chép.

Các mô-đun TPM và khởi động an toàn có thể cung cấp một phương tiện liên kết bo mạch chủ và phần cứng khác với cài đặt vào ổ cứng.

Trong những trường hợp này luôn dễ dàng hơn một chút nếu bạn cung cấp thêm thông tin về những gì bạn muốn thực hiện.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.