一貫したマシン固有IDを生成する


20

uuuidgenなど、PCごとに一意のIDを生成できますが、ハードウェアの変更がない限り変更されませんか?CPUIDとMACADDRをマージしてハッシュして一貫したIDを生成することを考えていましたが、bashスクリプトを使用してそれらを解析する方法がわかりません。

dmidecode -t 4 | grep ID

そして

ifconfig | grep ether

次に、これらの16進文字列を結合し、sha1またはmd5を使用してハッシュして、固定長の16進文字列を作成する必要があります。
その出力をどのように解析できますか?


4
この方法を使用して解決しようとしている問題は何ですか?
ダークホッグ14

1
私はダークホッグと一緒です。一般的に、このようなことをこの時代にしようとするのは悪い考えです。仮想化により、ソフトウェアを物理的なハードウェアにバインドするという習慣が無意味になりました。要件を厳密に調べると、通常、より良い答えがあります(これがDarkhoggが推進していることです)。
カルフール14

4
私はマシンにソフトウェアをバインドするために、これを使用してはいけない、それは必要性は、私が独自に彼らのハードウェアIDを使用してそれらを識別する必要が代わりに手動でリグの何千もの命名の、雲の制御および監視サービスに自分自身を識別することlinuxの採掘リグがある
uray

1
@ user77710:その場合、ハードウェアについて本当に気にしますか?マシン上にUUIDが存在しない場合、それを生成しないでください。それがUUIDのポイントです-それらは普遍的に一意です(重複する確率は天文学的にはありえないことです)。 serverfault.com/questions/103359/how-to-create-a-uuid-in-bash
Calphool

1
@JoeRounceville- SecureBoot自体がソリューションであることを意味しませんでした- 自己署名証明書をサポートしますが、むしろその方法です。ただし、システムのファームウェアが提供するAPIを使用します。UEFIシステムには、各ファームウェア変数の名前で既にセットアップする必要がある限り多くのUUIDがあります-私の答えを参照してください。また、bashLinuxでUUIDを生成するためのアプリケーションは必要ありません。cat /proc/sys/kernel/random/uuid
mikeserv 14

回答:


21

これら2つはどうですか:

$ 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  -

末尾のダッシュを削除するには、もう1つのパイプを追加します。

$ 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になる可能性があることを意味しeth0ます。私のシステムはこのように動作しないため、実際にテストすることはできませんが、考えられる解決策は次のとおりです。

  1. 特定のNICに対応するものだけでなく、すべてのHWaddr出力でGrepを使用しifconfigます。たとえば、私のシステムには次のものがあります。

    $ 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アドレスsha256sumを取得して通過させることにより、どのNICが何と呼ばれているかに関係なく、一意で安定した名前を取得できるはずです。

    $ 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    

    ifconfigtoが返すMACアドレスの両方を渡すため、ハッシュは上記のものとは異なることに注意してくださいsha256sum

  2. 代わりに、ハードドライブのUUIDに基づいてハッシュを作成します。

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

それはいいですが、末尾のダッシュ「-」を取り除く方法は?
uray 14

@ user77710は更新された回答を参照してください。
テルドン

1
cpuidの方が悪いと思います... wikipedia.org/wiki/cpuid
mikeserv 14

@mikeservああ、はい、確かに、あなたの主張がわかります。ありがとう、編集された回答。
テルドン

同じホスト上のすべてのゲストOSに同じIDを生成します。
ニティンクマールアンベカル

23

まず、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モデルにもこの機能を実装していません。

解析したcpuidを自分で表示することcat /proc/cpuinfoも、単に実行することもできますlscpu

これにより、Linuxカーネルによって認識されるネットワークインターフェイスのすべてのMACアドレスが取得されます。

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

ランダムに生成されたMACを持つ仮想NICが含まれている可能性がある場合、そのリストをフィルタリングする必要があります。これを行うには、ip直接呼び出しのフラグを使用します。ip a helpその方法については、を参照してください。

また、この問題は固有のものではなく、ip使用する場合にも対処する必要がありますが、ネットワークスイートの一部であり、アクティブに維持される- メンバーifconfigよりも確実に処理できることに注意してくださいパッケージと最後ののこぎり、Linuxの2001年にリリース。前回のリリース以降にカーネルの機能が変更されたため、一部のネットワーク機能フラグ誤って報告することが知られおり、可能な限りその使用を避ける必要があります。ipiproute2ifconfignet-toolsifconfig

ただし、カーネルインターフェイス名のようなフィルタリング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を調べてください


このdiit.cz/sites/default/files/images/3988 / ...を見てわからない場合は、ハードディスクもディスクも実行されていません。マイニングリグも、仮想マシンは単一で6 GPUを実行できませんマザーボード
uray

それはconsistenlyマシンに名前を付けるの目的を破ったとして、彼らはIDは変更されないブートアップとして、とにかくそれは、任意の乱数を使用しないでください
uray

@ user77710-ダン、男、それはクールだ。それは1台のマシンですか?おそらくあなたは正しいですが、XDMXとChromiumのいくつかのコンボ-いくつかの分散グラフィックスのもので可能かもしれません。とにかく、それは重要ではありません-私はそれを後方に持っていました。誰がお金で自分を打ち負かしたいのでしょうか?私はソフトウェアライセンスのことか何かを考えていました-あなたは銀行口座をやっています。
mikeserv 14

それらはあなたがそこに着いた気の利いたトリックです、+ 1。
テルドン

@terdon-賛辞は大歓迎ですが、大部分はトリックではありません。ip2解析するように特別に設計されており、私はそれを十分にやっていない可能性があります-私は同じことをほとんどなしで行うことができると思いますgrep/sed。おそらく同じことが簡単にできますudevadm。また、各EFI環境変数名は、このような状況に合わせて一意に識別されるように設計されています。
mikeserv 14

19

最新のディストリビューションの多くは/etc/machine-id、おそらく一意の16進数の32文字の文字列を含むファイルを出荷しています。これは、マンページに詳細な情報ある systemdに由来し、目的に適している場合があります。


+ 1、@ XZS、ここからURLから関連情報を追加することもできます。
ラメシュ14

1
これは良いことであり、同様の情報を見つけてほとんど使用しました...しかし、私はすでに別のルートにコミットしていました。それでも、これはdbus特定のものであり、オペレーティングシステムがワイプ/再インストールされると変更されることに注意する必要があります。
mikeserv 14

これはかなり素晴らしいです。
GeneCode

5

多くのLinuxマシンでは、ファイルに/var/lib/dbus/machine-idは各Linuxディストリビューションの一意のIDが含まれており、への呼び出しによってアクセスできますdbus_get_local_machine_id()。これはおそらく上記と同じ/etc/machine-idです。仮想Linuxインストールでも機能します。現在のUbuntu、SuSE、CentOSディストリビューションで確認しました。


1
Fedora 19 + 20では、そのファイルは存在しません。ここにあります/etc/machine-id
slm

おそらく私は十分に明確ではなかった。私のポイントは、1つの場所が見つからない場合は、他の場所を見るということでした。または、関数呼び出しを使用して独自のプログラムを作成します。
ランケニー14

0

ハードウェアの変更時にマシン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;

/dev/urandomとにかくLinuxを示しているので、cat /proc/sys/kernel/random/uuid >$FILE読み取りごとに適切にフォーマットされたUUIDをランダムに生成することができます。それでも、ディスクに実装された永続性は削除される可能性があり、それが許容dbusされ、インストールされている場合は、代わりに@XZSが提案したとおりに実行する必要があります。
mikeserv 14

0

他の答えは、ハードウェアからIDを抽出するいくつかの方法を提供します。1つまたは複数のハードウェアを識別子として使用することもできます。これは、ハードウェアを任意に交換または交換する必要がある場合に問題になります。

代わりに、生成されたIDをハードドライブに保存する(またはUUIDを使用する)場合もありますが、ハードドライブは複製できます。

TPMモジュールとセキュアブートは、マザーボードやその他のハードウェアをハードドライブにインストールするための手段を提供します。

達成したいことについてもっと情報を提供すれば、これらのケースでは常に少し簡単になります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.