Cプログラミングで一貫したマシン固有IDを生成する

Cプログラミングで一貫したマシン固有IDを生成する

ハードウェアが変更されない限り、時間が経っても変更されない一意のIDを生成できますか?ハードウェアはacプログラムを使用して作成する必要があります。

MACアドレスやハードドライブのシリアル番号のなりすましなどのなりすましから保護することができれば良いでしょう。しかし、これが絶対的な要件ではありません。

統計のために複数のコンピュータからソフトウェアデータを収集するには、これらのIDが必要です。

私は次のような同様の投稿をたくさん読んだ。 一貫したシステム固有IDの生成;しかし、私のニーズに合わない。

通常のユーザーとして実行するにはこのプログラムが必要なので、「dmidecode」などのコマンドは使用できません。 MACアドレスを使用する以外に解決策がなくても、ユーザーがWi-Fiからイーサネットに切り替えたときにUUIDを変更したくないので、最初のMACアドレスだけを取得することは問題になる可能性があります。最も重要なのは、VMwareまたはVPNがインストールされていてもUUIDは同じままである必要があることです。したがって、すべてのmacアドレスを取得することは、古いツールがより多くのネットワークインターフェイスとより多くのmacアドレスを生成してUUIDを変更したため、オプションではありません。

また、仮想マシンで動作したいと思います。生成されたゲストuuidはホストとは異なる必要があります。

この問題に対するそのような解決策があるかどうかはわかりません。しかし、私の考えは、sys/class/net/*/addressesを読むだけで、既存のすべての物理ハードウェアインターフェイスのMACアドレスを取得することです。その後、すべてのMacアドレスが追加され、sha1を使用してハッシュされ、UUIDが生成されます。しかし、変更されるトラックのみを選択するようにトラックをフィルタリングするにはどうすればよいですか?オーダーが変わらず、添付文字列とUUIDが変更されていることを確認できますか?

それ以外の場合は、root権限やサードパーティのツールなしでハードドライブのシリアル番号を検索できますか? (サードパーティ製ソフトウェアのソースを見つけることができれば大丈夫でしょう)

他の解決策も非常に歓迎されます。

PS:カーネル2.6以降のすべてのLinuxバージョンと互換性があるはずです。

ベストアンサー1

短い答え

私のすべての研究と試みによると、次の制約に準拠した一意のIDを生成するプログラムを作成することは不可能であると言いたいと思います。

  • 同じコンピュータで作成された場合は、毎回IDが同じでなければなりません。
  • 別のコンピュータで作成された場合は、IDが異なる必要があります。
  • このプログラムはユーザーとして実行する必要があります。
  • このプログラムは、カーネルバージョン2.6以降のすべてのLinuxディストリビューションと互換性がなければなりません。
  • コンピュータが改造されている場合(ハードウェアの交換など)、IDが異なる場合があります。
  • プログラムは、コンピュータにインストールする必要があるサードパーティ製のツールに依存してはいけません。

長い答え

ここでは、Macアドレスを使った試みを紹介します。

ここでの目標は、すべての物理ネットワークインターフェイスのアドレスを取得する方法を見つけることです。一般ユーザーとして、私はMACアドレスを見つける最も簡単な方法は "/sys"ディレクトリにあるシステムファイルを読み取ることです。このファイルはLinux 2.6以降で利用可能なので、完璧です。

私の調査結果によれば、以下の規則が適用された。 https://www.kernel.org/doc/Documentation/sysfs-rules.txt

udevライブラリは外部から追加する必要があるため、このルールで推奨されているように使用することはできません。だからここで見つけることができるソースコードを見ました。http://cgit.freedesktop.org/systemd/systemd/tree/src/libudev

ここで学んだのは、Macアドレスを検索するには「sys / subsystem」を探す必要があり、存在する場合はそこから「net」ディレクトリを見つけると、各ネットワークインタフェースのディレクトリを見つけることができるということです。 「subsystem」フォルダがない場合は、「sys/class」、「sys/bus」、および「sys/block」フォルダで「net」ディレクトリを探す必要があります。実際、私はいつも「教室」でそれらを見つけますが、規則によるとそれは期待してはいけません。

私は上記の「net」フォルダにネットワークディレクトリを見つけることができると言いましたが、これはまったく真実ではありません。 Linux 2.6(私はRHEL 4を使用しています)では、「sys / devices」のmacアドレスとそのディレクトリへのシンボリックリンクを含む「address」ファイルを見つけることができるディレクトリです。上位のLinuxバージョンでは、「アドレス」ファイルを見つけることができる「/sys/devices」ディレクトリへの直接シンボリックリンクになります。 (カーネルをLinux 4.3にアップデートして、RHEL 6、Debian 7、Debian 8、Ubuntu 15、Ubuntu 15を試してみました。)

最新のLinuxバージョン(4.3)でも、「/sys/subsystem」ディレクトリを見たことがありません。

sysfsの新しいレイアウト(>= linux 3): 物理インターフェイスと仮想インターフェイスを区別するためにデバイスの devpath を見たいと思います。 「/sys/class/net」のマイシンボリックリンクは、次のディレクトリを指します。

  • "/sys/devices/pci0000:00/0000:00:11.0/0000:02:01.0/net/eth0"
  • "/sys/devices/virtual/net/eth1"

eth1 は、次のトピックに基づいて作成された仮想仮想ネットワークカードです。物理アダプタなしでコンピュータに仮想イーサネットインターフェイスを作成するには?

これにより、仮想フォルダが「仮想」フォルダ内にあることがわかり、これが区別方法です。

sysfsの以前のレイアウト(Linux 2.6):

仮想ネットワークインターフェイスのディレクトリには「デバイス」シンボリックリンクはありません。

「/sys/class/net/eth0/device -> /sys/devices....」を見つけることができます。ただし、仮想eth1がある場合、「/sys/class/net/eth1」には対応する記号はありません。リンク。


要約すると、「opendir」、「readdir」、「access('...'、F_OK)」、「fopen」..を使用すると、物理インターフェイスのmacアドレスのみを取得できます。

次に、ソートして同じ順序で表示されることを確認し、すべてをバッファに追加し、opensslのSHA1を使用し、いくつかの解析を実行してUUIDのように見えます。

しかし、問題は、ネットワークデバイスのdevpathのどこかに「仮想」フォルダがあるという事実に依存したくないということです。上記のリンクは、これが常に真であるとは言いません。したがって、この質問にはこのように答えることはできません。

私のすべての研究が他の人に役立つことを願っています。

おすすめ記事