
Ist es möglich, eine eindeutige ID zu generieren, die sich im Laufe der Zeit nicht ändert, es sei denn, es gibt Hardwareänderungen. Die Hardware muss mit einem AC-Programm generiert werden.
Das wäre auch großartig, wenn es gegen Spoofing, wie etwa Spoofing von MAC-Adressen oder Festplattenseriennummern, resistent wäre. Aber das ist keine absolute Voraussetzung.
Eine solche ID benötige ich um Softwaredaten für Statistiken von vielen verschiedenen Rechnern zu sammeln.
Ich habe bereits viele ähnliche Beiträge gelesen, wie diesen hier: Generieren einer konsistenten, eindeutigen Maschinen-ID; aber sie entsprechen nicht meinen Bedürfnissen.
Ich muss dieses Programm als normaler Benutzer ausführen, daher kann ich keine Befehle wie „dmidecode“ und dergleichen verwenden. Selbst wenn ich keine andere Lösung habe, als MAC-Adressen zu verwenden, möchte ich nicht, dass sich die UUID ändert, wenn der Benutzer von WLAN auf Ethernet umschaltet. Daher kann es problematisch sein, nur die erste MAC-Adresse zu verwenden. Darüber hinaus muss die UUID identisch bleiben, auch wenn VMware oder VPN installiert wird. Daher ist es auch keine Option, alle MAC-Adressen zu verwenden, da diese vorherigen Tools mehr Netzwerkschnittstellen und damit mehr MAC-Adressen generieren und somit die UUID ändern.
Ich möchte auch, dass es auf einer virtuellen Maschine funktioniert. Die generierte Gast-UUID sollte sich von der Host-UUID unterscheiden.
Ich weiß nicht einmal, ob es eine solche Lösung für dieses Problem gibt. Aber ich dachte, ich könnte nur die Mac-Adressen aller physisch vorhandenen Hardwareschnittstellen nehmen, indem ich sys/class/net/*/addresses einlese. Dann alle Mac-Adressen anhängen und sie mit sha1 hashen, um die UUID zu generieren. Aber wie kann ich die Repertorien filtern, um nur eines auszuwählen, das sich ändert? Und kann ich sicher sein, dass ihre Reihenfolge nicht vertauscht wird und dadurch die angehängte Zeichenfolge und damit die UUID geändert wird.
Kann ich die Seriennummer der Festplatte auch ohne Root-Rechte und Drittanbieter-Tools abrufen? (Wenn ich die Quelle für Drittanbieter-Software finden kann, ist das in Ordnung.)
Auch andere Lösungen sind sehr willkommen.
PS: Es muss mit allen Linux-Versionen mit Kernel 2.6 oder höher kompatibel sein
Antwort1
Kurze Antwort
Aufgrund all meiner Untersuchungen und Versuche kann ich sagen, dass es nicht möglich ist, ein Programm zu erstellen, das eine eindeutige ID generiert, die die folgenden Einschränkungen beachtet.
- Die ID muss jedes Mal dieselbe sein, wenn sie auf demselben Computer generiert wird.
- Die ID muss unterschiedlich sein, wenn sie auf unterschiedlichen Computern generiert wird.
- Das Programm muss als Benutzer ausgeführt werden.
- Das Programm muss mit jeder Linux-Distribution mit einer Kernel-Version 2.6 oder höher kompatibel sein
- Die ID kann anders sein, wenn der Computer modifiziert wurde (z. B.: Hardware-Austausch)
- Das Programm sollte nicht auf Tools von Drittanbietern angewiesen sein, die auf dem Computer installiert werden müssen
Lange Antwort
Hier stelle ich meinen Versuch mit den Mac-Adressen vor.
Das Ziel war hier, einen Weg zu finden, die Adressen aller physischen Netzwerkschnittstellen abzurufen. Als normaler Benutzer habe ich festgestellt, dass der einfachste Weg, Mac-Adressen zu finden, darin besteht, die Systemdateien im Verzeichnis „/sys“ zu lesen. Diese Dateien sind seit Linux 2.6 verfügbar, also ist das perfekt.
Bei meinen Recherchen bin ich zu diesen Regelwerken gelangt: https://www.kernel.org/doc/Documentation/sysfs-rules.txt
Die Verwendung der udev-Bibliothek, wie in diesen Regeln empfohlen, ist nicht möglich, da sie extern hinzugefügt werden muss. Daher habe ich mich in die Quelle vertieft, die hier zu finden ist:http://cgit.freedesktop.org/systemd/systemd/tree/src/libudev
Was ich daraus gelernt habe, ist, dass Sie zum Abrufen der Mac-Adressen nach „sys/subsystem“ suchen sollten. Wenn vorhanden, suchen Sie darin nach einem „net“-Verzeichnis. Dort finden Sie Verzeichnisse mit jeder Netzwerkschnittstelle. Wenn kein „subsystem“-Ordner vorhanden ist, müssen Sie in den Ordnern „sys/class“, „sys/bus“ und „sys/block“ nach dem „net“-Verzeichnis suchen. Tatsächlich habe ich sie immer in „class“ gefunden, aber die Regeln besagten, dass dies nicht zu erwarten sei.
Oben habe ich gesagt, dass Sie im Ordner „net“ die Netzwerkverzeichnisse finden, das stimmt aber nicht ganz. Unter Linux 2.6 (ich habe RHEL 4 verwendet) sind es Verzeichnisse und darin finden Sie unter anderem die Datei „address“, die die Mac-Adresse enthält, einen symbolischen Link, der auf ein Verzeichnis in „sys/devices“ verweist. Unter einer höheren Linux-Version ist es direkt ein symbolischer Link zu einem Verzeichnis in „/sys/devices“, in dem Sie die Datei „address“ finden. (Ich habe es unter RHEL 6, Debian 7, Debian 8, Ubuntu 15 und Ubuntu 15 mit einem auf Linux 4.3 aktualisierten Kernel versucht.)
Ich habe das Verzeichnis „/sys/subsystem“ auch in der neuen Linux-Version (4.3) nie gesehen.
Neues Layout von Sysfs( >= Linux 3) : Um die physische Schnittstelle von der virtuellen zu unterscheiden, wollte ich mir den Gerätepfad des Geräts ansehen. Der symbolische Link, den ich in "/sys/class/net" habe, zielt auf diese Verzeichnisse:
- „/sys/devices/pci0000:00/0000:00:11.0/0000:02:01.0/net/eth0“
- „/sys/geräte/virtuell/net/eth1“
Bei eth1 handelte es sich um eine Dummy-virtuelle Netzwerkkarte, die ich gemäß diesem Thema erstellt habe:Wie kann ich auf einem Computer ohne physischen Adapter eine virtuelle Ethernet-Schnittstelle erstellen?
Sie können also sehen, dass sich die virtuellen in einem „virtuellen“ Ordner befinden. So können Sie sie unterscheiden.
Altes Layout von Sysfs(Linux 2.6):
Die virtuelle Netzwerkschnittstelle verfügt in ihren Verzeichnissen nicht über einen symbolischen „Gerätelink“.
Sie finden „/sys/class/net/eth0/device -> /sys/devices…“. Wenn es jedoch ein virtuelles eth1 gäbe, gäbe es in „/sys/class/net/eth1“ keinen solchen symbolischen Link.
Alles in allem können Sie mit „opendir“, „readdir“, „access('...',F_OK)“, „fopen“ … nur die Mac-Adressen der physischen Schnittstellen abrufen.
Sortieren Sie sie dann einfach, sodass Sie sicher sind, dass sie in der gleichen Reihenfolge kommen, hängen Sie dann alle in einen Puffer an und verwenden Sie einen SHA1 von OpenSSL, führen Sie eine kleine Analyse durch, damit es wie eine UUID aussieht, und schon kann es losgehen.
Aber die Sache ist, ich wollte mich nicht darauf verlassen, dass es irgendwo im Gerätepfad zu einem Netzwerkgerät einen „virtuellen“ Ordner gibt. In den oben verlinkten Regeln wird nirgends gesagt, dass dies immer der Fall wäre. Das Problem kann also nicht auf diese Weise gelöst werden.
Ich hoffe, dass all meine Recherchen jemandem helfen werden.