일관된 머신 고유 ID 생성 해시하여 일관된 ID를 생성하는 것에 대해

우리는 uuuidgen과 같은 각 PC에 대해 고유 한 ID를 생성 할 수 있지만 하드웨어 변경이없는 한 절대 변경되지 않습니까? CPUID와 MACADDR을 병합하고 해시하여 일관된 ID를 생성하는 것에 대해 생각하고 있었지만 bash 스크립트를 사용하여 구문 분석하는 방법을 모르겠습니다.

dmidecode -t 4 | grep ID

ifconfig | grep ether

그런 다음 16 진수 문자열을 결합하고 고정 길이 16 진수 문자열을 만들려면 sha1 또는 md5를 사용하여 해시해야합니다.
그 출력을 어떻게 파싱 할 수 있습니까?



답변

이 두 가지는 어떻습니까?

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

그런 다음 다음을 결합하여 해시 할 수 있습니다.

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

후행 대시를 제거하려면 파이프를 하나 더 추가하십시오.

$ 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

@mikeserv 가 그의 답변에서 지적한 것처럼 인터페이스 이름 부팅간에 변경 될 수 있습니다 . 이것은 오늘 eth0가 내일 eth1 일 수 있음을 의미하므로 grep eth0하면 다른 부트에서 다른 MAC 주소를 얻을 수 있습니다. 내 시스템은 이런 식으로 작동하지 않으므로 실제로 테스트 할 수는 없지만 가능한 해결책은 다음과 같습니다.

  1. 그렙은 대한 HWaddr의 출력에 ifconfig있지만, 그들 모두 특정 NIC에 해당뿐만 아니라 하나를 유지한다. 예를 들어, 내 시스템에는 다음이 있습니다.

    $ 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  

    두 MAC 주소를 모두 가져 와서 전달하면 sha256sumNIC가 무엇인지에 관계없이 고유하고 안정적인 이름을 얻을 수 있습니다.

    $ 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    

    해시 내가 의해 반환 모두 MAC 주소를 통과하고 있기 때문에 위의 것과 다르다는 것을 참고 ifconfig로를 sha256sum.

  2. 대신 하드 드라이브의 UUID를 기반으로 해시를 작성하십시오.

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

답변

첫째, CPUID는 Intel Pentium III 이후의 시스템에서 일반적으로 액세스 가능한 고유 식별 마커가 아닙니다 . MAC 주소로 해시하는 것은 확실히 고유 한 마커로 이어질 수 있지만, 이는 MAC 자체의 고유 한 특성 때문이며,이 경우 CPUID는 정황에 지나지 않습니다. 또한 결과로 생성되는 해시는 마더 보드의 UUID보다 더 독창적이지 않으며 검색하기가 훨씬 쉽고 프로세스 오류가 훨씬 적습니다. 에서 wikipedia.org/wiki/cpuid :

EAX = 3 : 프로세서 일련 번호

참고 : Pentium III § 개인 정보 보호 문제에 대한 논쟁

프로세서의 일련 번호를 반환합니다. 프로세서 일련 번호는 Intel Pentium III에 도입되었지만 개인 정보 보호 문제로 인해이 기능은 이후 모델에서 더 이상 구현되지 않습니다 (PSN 기능 비트는 항상 지워짐). Transmeta의 Efficeon 및 Crusoe 프로세서도이 기능을 제공합니다. 그러나 AMD CPU는 CPU 모델에서이 기능을 구현하지 않습니다.

구문 분석 된 CPU를 직접 cat /proc/cpuinfo또는 심지어 수행하여 볼 수도 있습니다 lscpu.

이것은 리눅스 커널이 인식하는 네트워크 인터페이스에 대한 모든 MAC 주소를 얻는다.

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

임의로 생성 된 MAC을 가진 가상 nic를 포함 할 수있는 경우이 목록을 필터링해야합니다. ip직접 호출 할 때 플래그를 사용하여이 작업을 수행 할 수 있습니다 . ip a help그렇게하는 방법에 대한 정보는 참조하십시오 .

또한이 문제는 고유하지 않으며 , ip사용하는 경우에도 처리해야 ifconfig하지만 ip, iproute2네트워크 제품군의 일부이며 ifconfig구성원 인 경우보다 더 안정적으로 처리 할 수 있습니다. 의 net-tools패키지 리눅스와 마지막 톱 2001 년 출시 . 마지막 릴리스 이후 커널의 기능 변경으로 인해 일부 네트워킹 기능 플래그ifconfig잘못보고하는 것으로 알려져 있으며 가능하면 사용을 피해야합니다.

그러나 커널 인터페이스 이름을 사용한 필터링 은 부팅 프로세스 중 eth[0-9]병렬 감지 순서에 따라 변경 될 수 있으므로 신뢰할 수있는 방법이 아니라는 점을 이해 udev하십시오. 이에 대한 자세한 내용은 예측 가능한 네트워크 이름 을 참조하십시오 .

dmidecode내 시스템에 설치되어 있지 않기 때문에 처음에는 다음과 같이 생성 된 하드 디스크 직렬 목록을 해시하는 것으로 생각했습니다.

lsblk -nro SERIAL

lsblk --help를 들어 디스크 유형별로 목록을 구체화하는 단서가 있습니다. 또한 고려 lspci및 / 또는 lsusb어쩌면.

그것들을 결합하는 것은 쉽습니다.

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

당신이 나에게 당신이 그들의 고유 한 ID에 당신의 자원을 키우고 있다고 나에게 알려 주었고, 하드 디스크는 존재를 믿을 수 없어 내 압정을 바꿀 것으로 생각했다.

그 점을 고려하여 파일 시스템을 다시 살펴보고 /sys/class/dmi/id폴더를 찾았습니다 . 몇 가지 파일을 확인했습니다.

cat ./board_serial ./product_serial

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

그러나 이것은 꽤 좋은 것처럼 보이지만 출력을 게시하지는 않습니다.

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

나는 dmidecode그것이 정보의 많은 부분을 어쨌든 얻는 곳 이기를 기대하고 실제로는 그것이 정보 처럼 보인다 . 에 따르면 man dmidecode인수를 지정하여 해당 도구의 사용을 크게 단순화 할 수 있습니다.

dmidecode -s system-uuid

그래도 더 간단하지만 파일을 읽을 수 있습니다. 이 특정 파일은 특히 마더 보드를 식별합니다. 다음은 이러한 내보내기를 가상 파일 시스템으로 원래 구현 한 2007 커널 패치 에서 발췌 한 내용입니다 /sysfs.

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

마더 보드가 충분한 경우 해당 데이터 만 사용하여 시스템을 식별 할 수 있습니다. 그러나 하드 디스크로 할 수있는 것과 같은 방식으로이 정보를 시스템의 MAC과 결합 할 수 있습니다.

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

Linux 커널은 다음과 같은 UUID도 생성 할 수 있습니다.

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

또는:

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

물론, 그것은 무작위로 생성되며 ID 할당을 다시 생각해야하지만 최소한 쉽게 얻을 수 있습니다. 그리고 키를 넣을 방법을 찾을 수 있다면 상당히 견고해야합니다.

마지막으로, UEFI 시스템에서는 모든 EFI 펌웨어 환경 변수에 자체 UUID가 포함되어 있으므로 훨씬 쉽게 수행 할 수 있습니다. 환경 변수 {Platform,}LangCodes-${UUID}는 모든 UEFI 시스템에 존재해야하며 재부팅 및 대부분의 펌웨어 업그레이드 및 수정을 유지해야 하며, efivarfs모듈이로드 된 Linux 시스템은 다음과 같이 간단하게 하나 또는 둘 모두의 이름을 나열 할 수 있습니다.

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

오래된 형태는 – LangCodes-${UUID}분명히되어 지금은 사용되지 않는 , 그리고 새로운 시스템에 있어야 PlatformLangCodes-${UUID}사양, 하나 또는 다른 모든 UEFI 시스템에 존재해야한다에 따라,하지만. 약간의 노력만으로도 재부팅 영속 변수를 직접 정의하고 커널 UUID 생성기를 더 많이 활용할 수 있습니다. 관심이 있다면 efitools를 살펴 보십시오 .


답변

많은 현대 배포판에는 /etc/machine-id아마도 가장 고유 한 16 진 32 자 문자열이 포함 된 파일 이 제공됩니다. 맨 페이지에 자세한 정보가 있는 systemd에서 시작되었으며 사용자의 목적에 적합 할 수 있습니다.


답변

많은 Linux 시스템에서 파일 /var/lib/dbus/machine-id은 각 Linux 배포에 대한 고유 ID를 포함하며에 대한 호출을 통해 액세스 할 수 있습니다 dbus_get_local_machine_id(). 이것은 아마도 /etc/machine-id위에서 언급 한 것과 같습니다. 가상 Linux 설치에서도 작동합니다. 현재 Ubuntu, SuSE 및 CentOS 배포판에서 확인했습니다.


답변

하드웨어가 변경 될 때 변경하려면 머신 ID가 필요합니까? 컴퓨터 ID를 사용하여 무언가를 보호하고 있습니까? “일관된”컴퓨터 ID를 갖는 가장 좋은 방법은 시스템 어딘가에 임의의 문자열을 저장하는 것이며 하드웨어가 변경되면 컴퓨터 ID도 변경되지 않습니다. 하드웨어 액세스가 제한되고 MAC ID가 00 : 00 : 00 : 00 인 가상화 시스템에도 좋습니다.

이 sh 스크립트와 같은 것을 시도하여 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;

답변

다른 답변은 하드웨어에서 ID를 추출하는 여러 가지 방법을 제공합니다. 하나의 하드웨어를 식별자 또는 다수로 사용하기로 결정할 수 있습니다. 하드웨어를 임의로 교체하거나 교체해야하는 경우 문제가됩니다.

일부 사람들은 대신 생성 된 ID를 하드 드라이브에 저장하거나 UUID를 사용하지만 하드 드라이브를 복제 할 수 있습니다.

TPM 모듈 및 보안 부팅은 마더 보드 및 기타 하드웨어를 하드 드라이브에 설치하여 바인딩하는 수단을 제공 할 수 있습니다.

당신이 달성하고자하는 것에 대해 더 많은 정보를 제공하면이 경우에는 항상 조금 더 쉽습니다.