web-dev-qa-db-ja.com

UNIXライクなシステムから一意のIDを取得する

Unixライクなシステムから(可能であれば)、アプリケーションが同じマシンで実行されるたびに永続する一意のIDを取得したいと思います。可能であれば、Linux、FreeBSD、Solarisなどから同じIDを取得したい...マシンごとに新しいIDを生成したくないが、既存のIDを取得し、このIDを優先するオペレーティングシステムから来て、MACアドレスのようなものを使うのは好きではありません。

他に利用できるオプションがない場合は、MACを他のものと組み合わせて使用​​できます。たとえば、idはMACアドレスと他のものの組み合わせのmd5ハッシュにすることができます。

私はあなたの提案を聞きたいです。

それが役に立つなら、私のアプリケーションはC/C++で書かれています。

これらすべての目的は、ユーザーがアプリケーションを2回以上実行しないようにすることです。一度だけ走りたいです。

22
Blue

ルートファイルシステムのUUIDはどうですか?ルートファイルシステムデバイスは、ファイルを手動で解析するか、getfsent (3)またはgetfsfile (3)を使用して、/etc/fstabから取得できます。デバイスを入手したら、/dev/disk/by-uuidのリンクを確認するか、blkidコマンドからUUIDを取得できます。

28
Jason Day

SolarisとLinuxの両方がhostid(1)ユーティリティを提供します

11

いつものように、他の人が同じ問題をどのように解決したかを確認するのが最善の方法です。

FLEXlm は、ノードロックライセンスにもホスト識別子を使用します。使用する最も一般的なホスト識別子は、ネットワークインターフェイスの1つのイーサネットMACアドレスであり、セパレータなしでまとめられています。

また、(Windowsでは)C:ドライブのボリュームシリアル番号(セパレータなしで一緒に粉砕)を使用でき、Solarisではhostidコマンドの出力(IIRC、Sunコンピュータではこの番号は実際には一意であり、システムボード上の小さなリムーバブルEEPROMにあります)。

MACアドレスは非常に簡単に偽造できますが、最近ではほぼ普遍的なIDであり(ほとんどすべての新しいコンピューターには少なくとも1つのイーサネットポートがあり、オンボードであることが非常に一般的です)、実際にはグローバルに一意であることが意図されています(実際、イーサネットプロトコルはこの一意性に依存しています)。このアプローチで発生する主な問題:

  • 一部のコンピューターには複数のイーサネットアドレスがあります。それらのいくつかはメインボード上にあり、いくつかは別々のリムーバブルカード上にあります。
  • それらは非常に簡単に偽造できます(一部のプロトコルはそれらを変更できることに依存しています)。
  • 一部の仮想化環境では、起動ごとにランダムなイーサネットアドレスが生成されます(ただし、通常、固定値を強制する方法があります)。
9
CesarB

もう1つのオプションは、Linuxに存在するコマンドである dmidecode から派生した情報を使用することです。この情報は/ dev/memからデコードされるため、ルートアクセスが必要です。

一部のマザーボードメーカーが一部のフィールドを嘘または偽造しているため、dmidecodeが読み取る情報には欠陥があることがわかっています。

5
Phillip Whelan

あなたが望むものを手に入れるための一般的で信頼できる方法はありません。

3
user3850

私はそれが可能だとは思いません。最も近い方法は、非常に長いランダムな文字列を作成し(MSがGUIDで行うように)、システムのどこかに保存することです。

3
Yoni Roit

多くのセットアップでは、ファイルシステムイメージが作成され、個別にセットアップするのではなく、多くのマシンに複製されている可能性があることを考慮する必要があります。その他の場合、マシンは何度も再セットアップされる可能性があります。言い換えれば、提供されたOSはすべて信頼できません。

ただし、CPUは一意のシリアル番号を保持しますが、CPUへのアクセスはシステムによって異なる必要があります。

1
ironfroggy

一意の識別子がどれほど安定している必要があるかについては言及していません。コードを実行するたびに、常に同じホストで同じIDを生成する必要がありますか?

いいえの場合、fuzzymonkによるuuidgenの提案が必要です。

はいの場合は、ホストに関する限り、何が「同じ」であるかを決定する必要があります。 1つの方法は、ご提案のとおり、最初のイーサネットインターフェイスのMACと「何か」のMD5合計です。その場合の「何か」については、「同じホスト」の概念にFQDNの変更が含まれていない限り、FQDNを検討します。

1
genehack

ルートファイルシステム_/_のUUIDを取得できます。これはかなり信頼性がありますが、同じディスクで実行されているchrootとVMを区別しません。

特定のOSの実行専用の内蔵または静的HDDを主に扱っている場合は、ルートファイルシステムのUUIDを使用してシステムを検出できるはずです。

ルートfsのUUIDは、次のように取得できます。alias sys_guid='Sudo /sbin/blkid | grep "$(df -h / | sed -n 2p | cut -d" " -f1):" | grep -o "UUID=\"[^\"]*\" " | sed "s/UUID=\"//;s/\"//"'

同じOSのカーネルバージョン、または同じディスクで実行されている異なるOSをさらに区別する必要がある場合は、unameのデータを使用するか、ルートfsUUIDと組み合わせることができます。

1
user4401178

UUIDを探しているようですね。これは一般的な普遍的に一意のIDです(実際には、GUIDと同じものです)

さまざまなライブラリにこれの多くのC++実装があります。または、uuidgenコマンドを使用して出力をキャプチャすることもできます。

0
csexton

ほとんどのUNIXライクなマシンには、 / dev/random からアクセスできる乱数ジェネレータがあります。 GUIDジェネレーターに真の一意性を与えるには、MACアドレスと時間のようなものが必要になります(これは、WindowsのGUIDジェネレーターが行うことです)。これに加えて、/ dev/randomから何かを取得すると、適度に優れたGUID型構造が得られます。実際には、UUIDライブラリはこの種のことをバックグラウンドで実行します。

マシンごとに1つの番号だけが必要な場合は、MACアドレスで十分です。これらは中央機関によって管理されており、2つのMACアドレスが同じになることはないと合理的に想定できます。ただし、これを使用してソフトウェアインストールをMACアドレスに関連付けようとしている場合は、一部のコンポーネントにプログラム可能なMACアドレスまたはMACアドレスのプログラム可能なコンポーネントがあることに注意してください。 Unixライクなオペレーティングシステム、特にオープンソースのオペレーティングシステムには、ハードワイヤードのシリアル番号がない傾向があります。このアプローチでは、VMでソフトウェアの複数のインスタンスを実行する際にも問題が発生する可能性があります。

1つのオプションは、USB dongle、 である可能性があります。これは、複数のメーカーから入手できます。別のオプションは、一意のコードがサーバーに提供されるライセンスサーバーである可能性があります。繰り返しになりますが、これに対するいくつかの定型ソリューションは、さまざまなソースから入手できます。

WindowsではGUIDを使用するとおっしゃいました...それがどのように作成されるかについての詳細はありますか?

それとは別に、CPU IDやハードディスクIDのようなものを試すことができます...それらは変更できないと思います(ただし、障害のあるハードディスクを交換すると問題が発生します)。

0
oliver

Jason DayとA.Danischewskiからの回答は正しい方向に進んでいるようですが、/sbin/blkid/etc/fstabはOSXに存在しないため、「Unixライクなシステム」の基準を満たしていません。

100%移植可能な唯一のアプローチは、独自のアプリケーションが作成するファイルの標準的な場所を選択することです。 /etc/YOURAPP.cfg UUIDがまだ存在しない場合は、そこに格納します。

他の人やアプリケーションがファイルを削除または変更したり、ユーザーがルートファイルシステムを変更したりすると、現在のマシンからIDが失われたり、別のマシンで使用されたりする可能性があるため、理想からはほど遠いです。読み取りおよび書き込み権限などの問題は言うまでもありません。

しかし、結局のところ、「同じマシン」のようなものはありません。どのコンピュータも、そのコンポーネント+現在の構成以上でもそれ以上でもありません。私はあなたがこれよりもうまくやれるとは思いません。

0
Chris Johnson