一貫したシステム固有IDの生成

一貫したシステム固有IDの生成

uuuidgenなど、各PCに一意のIDを生成できますが、ハードウェアが変更されない限り、決して変更されませんか? CPUIDとMACADDRをマージしてハッシュして一貫したIDを生成しようとしていますが、bashスクリプトを使用して解析する方法がわかりません。私が知っているのは、CPUIDを取得する方法だけです。

dmidecode -t 4 | grep ID

そして

ifconfig | grep ether

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

答え1

これら二つはどうですか?

$ 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. grep forHWaddrの出力は、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  
    

    2つの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    
    

    ifconfigで返された2つのMACアドレスを渡したため、ハッシュは上記とは異なりますsha256sum

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

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

答え2

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

cat /proc/cpuinfoCPUIDを実行したり表示したりしても、自分で確認できますlscpu

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

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

ランダムに生成されたMACを持つ仮想ネットワークカードが含まれる可能性がある場合は、リストをフィルタリングする必要があります。ダイレクトコールでフラグを使用してこれを行うことができますipip a helpこれを行う方法については、参考資料を参照してください。

また、この問題は固有のものではなく、使用しているip場合は処理する必要がありますifconfigが、より確実に処理できますipiproute2ネットワークファミリーそして積極的に保つよりも良いことはifconfig次のとおりです。net-toolsパックLinuxで最後に確認済み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ジェネレータをより活用できます。興味のある人は一度見てみるといいと思います。エフェツール

答え3

/etc/machine-id多くの最新のディストリビューションには、固有の16進数32文字の文字列を含むファイルが付属しています。これはsystemdから派生します。マンページにはより多くの情報が含まれています。、あなたの目的に適している可能性があります。

答え4

ハードウェアが変更されたら、コンピュータ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;

関連情報