USB/IP im Griff

Es stellt sich regelmĂ€ĂŸig die Aufgabe, ein USB-GerĂ€t ĂŒber das lokale Netzwerk mit einem Remote-PC zu verbinden. Im Folgenden berichte ich ĂŒber meine Suche in diesem Bereich und den Weg zu einer fertigen Lösung auf Basis eines Open-Source-Projekts. USB/IP mit einer Beschreibung der verschiedenen Hindernisse, die mir dabei von verschiedenen Leuten in den Weg gelegt wurden, sowie der Methoden, diese zu umgehen.

Teil eins, die Geschichte

Wenn die Maschine virtuell ist, ist das alles nicht schwierig. Die Möglichkeit, USB vom Host in die virtuelle Maschine weiterzuleiten, existiert seit VMWare 4.1. In meinem Fall musste jedoch der SicherheitsschlĂŒssel, der als WIBU-KEY erkannt wird, zu unterschiedlichen Zeiten an verschiedene Maschinen angeschlossen werden, und das nicht nur an virtuelle.
Die erste Runde meiner Suche im fernen Jahr 2009 fĂŒhrte mich zu einem GerĂ€t namens TrendNet TU2-NU4
Vorteile:

  • funktioniert manchmal sogar

Nachteile:

  • funktioniert nicht immer. Der SicherheitsschlĂŒssel Guardant Stealth II wird beispielsweise nicht darĂŒber erkannt und gibt den Fehler "Das GerĂ€t kann nicht gestartet werden" aus.
  • Die Software zur Verwaltung (d.h. zum Mounten und Unmounten von USB-GerĂ€ten) ist extrem schlicht. Kommandozeilenoptionen, Automatisierung – nein, davon haben sie noch nie gehört. Alles nur von Hand. Ein Albtraum.
  • Die Software sucht das GerĂ€t im Netzwerk ĂŒber Broadcast, daher funktioniert das nur innerhalb eines Broadcast-Segments des Netzwerks. Eine manuelle IP-Adresse fĂŒr das GerĂ€t anzugeben, ist nicht möglich. Ist das GerĂ€t in einem anderen Subnetz? Dann haben Sie ein Problem.
  • Die Entwickler haben das GerĂ€t aufgegeben, Bug-Reports sind nutzlos.

Eine zweite Runde fand in der nicht allzu fernen Vergangenheit statt und brachte mich zum Thema des Artikels — USB/IP-Projekt. Es ist besonders attraktiv durch seine Offenheit, vor allem, da die Jungs von ReactOS ihnen einen Treiber fĂŒr Windows signiert haben, sodass nun sogar auf x64 alles ohne seltsame Workarounds wie den Testmodus funktioniert. Ein großes Dankeschön an das ReactOS-Team! Es klingt alles sehr vielversprechend, lass uns herausfinden, ob es in der Praxis genauso funktioniert. Leider wurde auch das Projekt etwas vernachlĂ€ssigt, und man kann nicht auf UnterstĂŒtzung hoffen – aber wo ein Wille ist, ist auch ein Weg, der Quellcode ist vorhanden, wir werden das hinbekommen!

Teil zwei, serverseitig fĂŒr Linux

Der USB/IP-Server, der USB-GerĂ€te ĂŒber das Netzwerk freigibt, kann nur in Linux-basierten Betriebssystemen eingerichtet werden. Na gut, wenn Linux, dann setzen wir es auf einer Debian 8-VM in minimaler Konfiguration auf, die ĂŒblichen Schritte:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install usbip

Es hat geklappt. Der nĂ€chste Schritt, den das Internet empfiehlt, ist, das Modul usbip zu laden, aber — hallo, hier kommt die erste Stolperfalle. Dieses Modul existiert nicht. Das liegt daran, dass die meisten Anleitungen im Internet sich auf die Ă€ltere Version 0.1.x beziehen, wĂ€hrend in der neuesten Version 0.2.0 die Module usbip andere Namen haben.

Deshalb:

sudo modprobe usbip-core
sudo modprobe usbip-host
sudo lsmod | grep usbip

Und wir fĂŒgen in /etc/modules die folgenden Zeilen hinzu, um sie automatisch beim Start des Systems zu laden:

usbip-core
usbip-host
vhci-hcd

Lass uns den usbip-Server starten:

sudo usbipd -D

Dann zeigt uns das globale Wissen, dass zusammen mit usbip Skripte bereitgestellt werden, die es uns ermöglichen, den Server zu verwalten — zu zeigen, welches GerĂ€t er im Netzwerk freigeben wird, den Status zu ĂŒberprĂŒfen und so weiter. Doch hier wartet ein weiteres Hindernis — diese Skripte in der Version 0.2.x wurden wieder umbenannt. Eine Liste der Befehle erhalten wir mit

sudo usbip

Nach dem Lesen der Befehlsbeschreibungen wird klar, dass usbip die Bus-ID des gewĂŒnschten USB-GerĂ€ts benötigt, um es freizugeben. Sehr geehrte Zuschauer, hier kommt die dritte Stolperfalle: die Bus-ID, die wir von lsusb (scheint der offensichtlichste Weg zu sein) — es passt nicht! Tatsache ist, dass GerĂ€te wie USB-Hubs von usbip ignoriert werden. Daher verwenden wir den integrierten Befehl:

user@usb-server:~$ sudo usbip list -l
 - busid 1-1 (064f:0bd7)
   WIBU-Systems AG : BOX/U (064f:0bd7)

Hinweis: In den folgenden Listings beschreibe ich alles am Beispiel meines spezifischen USB-Sticks. Ihre GerĂ€tebezeichnung und die VID:PID können abweichen. Meiner heißt Wibu-Systems AG: BOX/U, VID 064F, PID 0BD7.

Jetzt können wir unser GerÀt freigeben:

user@usb-server:~$ sudo usbip bind --busid=1-1
usbip: info: bind device on busid 1-1: abgeschlossen

Hurra, Kameraden!

user@usb-server:~$ sudo usbip list -r localhost
Exportierbare USB-GerÀte
======================
 - localhost
        1-1: WIBU-Systems AG : BOX/U (064f:0bd7)
           : /sys/devices/pci0000:00/0000:00:11.0/0000:02:00.0/usb1/1-1
           : Vendor-spezifische Klasse / unbekannte Unterklasse / unbekanntes Protokoll (ff/00/ff)

Dreifaches Hurra, Kameraden! Der Server hat das GerĂ€t im Netzwerk freigegeben, und wir können es anschließen! Es bleibt nur noch, den Autostart des usbip-Demons in /etc/rc.local hinzuzufĂŒgen.

usbipd -D

Teil drei, der klientenseitige und verwirrende Teil

Ich habe das freigegebene GerÀt sofort auf dem gleichen Server, der mit Debian betrieben wird, angeschlossen, und alles hat wunderbar funktioniert:

sudo usbip attach --remote=localhost --busid=1-1

Lassen Sie uns zu Windows ĂŒbergehen. In meinem Fall handelte es sich um Windows Server 2008R2 Standard Edition. Das offizielle Handbuch verlangt zunĂ€chst die Installation des Treibers. Die Vorgehensweise ist im mitgelieferten Readme des Windows-Clients gut beschrieben, wir machen alles wie angegeben und es funktioniert einwandfrei. Auch unter XP lĂ€uft es ohne Schwierigkeiten.

Nachdem wir den Client entpackt haben, versuchen wir unseren SchlĂŒssel zu montieren:

C:Program FilesUSB-IP>usbip -a %server-ip% 1-1
usbip err: usbip_network.c: 121 (usbip_recv_op_common) recv op_common, -1
usbip err: usbip_windows.c: 756 (query_interface0) recv op_common
usbip err: usbip_windows.c: 829 (attach_device) kann GerÀt nicht finden

Oh-oh. Irgendetwas ist schiefgelaufen. Wir nutzen unsere Google-FĂ€higkeiten. Es gibt sporadische Hinweise, dass etwas mit den Konstanten nicht stimmt; die Entwickler haben in der Serverversion bei der Umstellung auf Version 0.2.0 das Protokoll geĂ€ndert, im Windows-Client jedoch vergessen, dies zu tun. Die empfohlene Lösung ist – Ă€ndern Sie die Konstante im Quellcode und kompilieren Sie den Client neu.

Ich habe jedoch wirklich keine Lust, Visual Studio nur fĂŒr dieses Verfahren herunterzuladen. Aber ich habe noch das alte, bewĂ€hrte Hiew. Im Quellcode ist die Konstante als Doppelwort deklariert. Wir suchen im File 0x00000106 und ersetzen es durch 0x00000111. Denken Sie daran, die Byte-Reihenfolge ist umgekehrt. Ergebnis – zwei Übereinstimmungen, wir patchen:

[usbip.exe]
00000CBC: 06 11
00000E0A: 06 11

Und... ja!

C:Program FilesUSB-IP>usbip -a %server-ip% 1-1
Neues USB-GerÀt an den USB-VBus-Port 1 angeschlossen

An dieser Stelle könnte man die AusfĂŒhrungen beenden, aber die Musik spielte nicht lange. Nach einem Neustart des Servers stellte ich fest, dass das GerĂ€t auf dem Client nicht gemountet wird!

C:Program FilesUSB-IP>usbip -a %server-ip% 1-1
usbip Fehler: usbip_windows.c: 829 (attach_device) kann das GerÀt nicht finden

Und das war's. Darauf konnte mir nicht einmal der allwissende Google eine Antwort geben. Dabei zeigt der Befehl zur Anzeige der auf dem Server verfĂŒgbaren GerĂ€te durchaus korrekt an – da ist der SchlĂŒssel, Sie können ihn mounten. Ich versuche es unter Linux zu mounten – es funktioniert! Und wenn ich es jetzt unter Windows versuche? Oh Grauen – es klappt!

Letzte Stolpersteine: Irgendetwas im Servercode ist nicht ganz richtig. Beim Teilen des GerĂ€ts liest er nicht die Anzahl der USB-Descriptors. Beim Mounten des GerĂ€ts unter Linux wird dieses Feld ausgefĂŒllt. Leider bin ich mit der Entwicklung unter Linux nur auf dem Niveau 'make && make install' vertraut. Daher wurde das Problem mit einem ziemlich groben Hack gelöst – durch HinzufĂŒgen zu /etc/rc.local

usbip attach --remote=localhost --busid=1-1
usbip port
usbip detach --port=00

Abschließender Teil

Nach einigen MĂŒhen funktioniert es nun. Das GewĂŒnschte ist erreicht, jetzt kann der SchlĂŒssel an jeden PC angeschlossen (und natĂŒrlich auch wieder abgezogen) werden, sogar außerhalb des Broadcast-Segments des Netzwerks. Wenn gewĂŒnscht, kann dies mithilfe eines Shell-Skripts erfolgen. Das Beste daran – es ist vollkommen kostenlos.
Ich hoffe, dass meine Erfahrung den Lesern hilft, die Stolpersteine zu umgehen, die mir begegnet sind. Vielen Dank fĂŒr Ihre Aufmerksamkeit!

Quelle: habr.com

Kaufen Sie zuverlĂ€ssiges Hosting fĂŒr Websites mit DDoS-Schutz, VPS VDS-Server đŸ”„ Kaufen Sie zuverlĂ€ssiges Hosting fĂŒr Websites mit DDoS-Schutz, VPS VDS-Server | ProHoster