USB/IP zÀhmen

RegelmĂ€ĂŸig steht die Aufgabe an, ein USB-GerĂ€t ĂŒber ein lokales Netzwerk mit einem entfernten PC zu verbinden. Im Folgenden schildere ich meine Suche in diesem Bereich und den Weg zu einer fertigen Lösung basierend auf einem Open-Source-Projekt USB/IP mit der Beschreibung der verschiedenen Hindernisse, die von vielen Menschen auf diesem Weg sorgsam installiert wurden, sowie der Möglichkeiten, sie zu umgehen.

Erster Teil, historisch

Wenn die Maschine virtuell ist, ist das alles nicht schwierig. Die FunktionalitĂ€t fĂŒr das Durchreichen von USB vom Host zur virtuellen Maschine wurde bereits in VMWare 4.1 eingefĂŒhrt. Aber in meinem Fall musste der SchutzschlĂŒssel, der als WIBU-KEY erkannt wird, zu unterschiedlichen Zeiten an verschiedenen Maschinen angeschlossen werden, und nicht nur an virtuellen.
Die erste Phase meiner Suche im fernen Jahr 2009 fĂŒhrte mich zu einem GerĂ€t namens TrendNet TU2-NU4
Vorteile:

  • manchmal funktioniert es sogar

Nachteile:

  • es funktioniert nicht immer. Zum Beispiel wird der SchutzschlĂŒssel Guardant Stealth II darĂŒber nicht erkannt und zeigt den Fehler „Das GerĂ€t kann nicht gestartet werden“ an.
  • Die Software zur Verwaltung (Sprich: zum Einbinden und Entfernen von USB-GerĂ€ten) ist extrem spĂ€rlich. Befehlszeilenparameter, Automatisierung – nein, davon haben sie nicht gehört. Alles nur von Hand. Ein Albtraum.
  • Die Verwaltungssoftware sucht das GerĂ€t im Netzwerk ĂŒber Broadcast, daher funktioniert das nur innerhalb eines Broadcast-Segments des Netzwerks. Die IP-Adresse des GerĂ€ts kann nicht manuell eingegeben werden. GerĂ€t in einem anderen Subnetz? Dann haben Sie ein Problem.
  • Die Entwickler haben das GerĂ€t aufgegeben, Bug-Reports zu senden, ist sinnlos.

Die zweite Phase fand in nicht allzu ferner Zeit statt und fĂŒhrte mich zum Thema des Artikels – USB/IP-Projekt. Es fasziniert durch seine Offenheit, zumal die Leute von ReactOS ihnen einen Treiber fĂŒr Windows zur VerfĂŒgung gestellt haben, sodass jetzt sogar auf x64 alles ohne irgendwelche Hacks wie den Testmodus funktioniert. DafĂŒr ein riesiges Dankeschön an das ReactOS-Team! Klingt alles schön, probieren wir es aus, ob es so funktioniert? Leider ist das Projekt selbst auch etwas vernachlĂ€ssigt, und damit ist kein Support zu erwarten – aber woher kommt unsere HartnĂ€ckigkeit, der Quellcode ist da, wir werden es herausfinden!

Zweiter Teil, server-basiert und Linux-orientiert

Ein USB/IP-Server, der USB-GerĂ€te ĂŒber das Netzwerk freigibt, kann nur auf einem Linux-basierten Betriebssystem eingerichtet werden. Na gut, wenn Linux, dann Linux, ich installiere Debian 8 in minimaler Konfiguration auf der virtuellen Maschine, normales Vorgehen:

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

Wir haben uns eingerichtet. Weiterhin zeigt das Internet an, dass wir das Modul usbip laden sollten, aber – willkommen, die ersten Probleme. Solch ein Modul existiert nicht. Das liegt daran, dass die meisten Anleitungen im Netz sich auf eine Ă€ltere Version 0.1.x beziehen, wĂ€hrend in der neuesten Version 0.2.0 die usbip-Module andere Namen tragen.

Deshalb:

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

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

usbip-core
usbip-host
vhci-hcd

Starten wir den usbip-Server:

sudo usbipd -D

Weiterhin zeigt uns das globale Wissen, dass mit usbip Skripte geliefert 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. Hier wartet ein weiteres Problem auf uns – diese Skripte wurden in der Version 0.2.x, wieder einmal, umbenannt. Die Liste der Befehle erhĂ€lt man mit

sudo usbip

Nachdem wir die Beschreibung der Befehle gelesen haben, wird klar, dass usbip, um das benötigte USB-GerĂ€t freizugeben, dessen Bus-ID wissen möchte. Sehr geehrte Zuschauer, das dritte Problem: die Bus-ID, die uns ausgegeben wird, lsusb (scheinbar der offensichtlichste Weg) – passt nicht! Der Grund ist, dass usbip GerĂ€te wie USB-Hubs ignoriert. Daher nutzen wir den eingebauten Befehl:

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

Hinweis: Hier und in den folgenden Listings werde ich alles anhand meines speziellen USB-Sticks beschreiben. Die Bezeichnung Ihres GerĂ€ts 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: complete

Hurra, Genossen!

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, Genossen! Der Server hat das GerĂ€t im Netzwerk freigegeben, und wir können es anschließen! Es bleibt nur noch, den automatischen Start des usbip-Daemons in /etc/rc.local hinzuzufĂŒgen.

usbipd -D

Teil drei, der klientseitige und verworrene Teil

Ich habe versucht, das freigegebene GerĂ€t ĂŒber das Netzwerk an eine Maschine mit Debian anzuschließen, und es hat alles wunderbar funktioniert:

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

Kommen wir zu Windows. In meinem Fall war es Windows Server 2008R2 Standard Edition. Das offizielle Handbuch fordert zuerst die Installation des Treibers. Das Verfahren ist ausfĂŒhrlich im mitgelieferten Readme des Windows-Clients beschrieben, wir machen alles wie beschrieben und es funktioniert alles. Auf XP funktioniert es ebenfalls problemlos.

Nachdem wir den Client entpackt haben, versuchen wir, unseren SchlĂŒssel anzuschließen:

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) GerÀt nicht gefunden

Oh-oh. Da ist etwas schiefgelaufen. Lassen Sie uns die Google-FÀhigkeiten nutzen. Es gibt sporadische ErwÀhnungen, dass einige Konstanten in der Server-Teils nicht stimmen; die Entwickler haben beim Wechsel auf Version 0.2.0 die Protokollversion geÀndert, aber im Windows-Client haben sie das vergessen. Die empfohlene Lösung ist, die Konstante im Quellcode zu Àndern und den Client neu zu kompilieren.

Ich möchte jedoch nicht Visual Studio nur fĂŒr dieses Verfahren herunterladen. Aber ich habe den guten alten Hiew. Die Konstante ist im Quellcode als Double Word deklariert. Wir suchen in der Datei 0x00000106 und Ă€ndern sie in 0x00000111. Nicht vergessen, die Byte-Reihenfolge ist umgekehrt. Ergebnis – zwei Übereinstimmungen, wir patchen:

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

Jaaaa


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

An dieser Stelle könnte man die ErzÀhlung beenden, aber die Musik spielte nicht lange. Nach dem Neustart des Servers stellte ich fest, dass das GerÀt am Client nicht montiert wird!

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

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

Letzte Stolpersteine: irgendetwas ist im Servercode nicht richtig implementiert. Beim Teilen des GerĂ€ts wird die Anzahl der USB-Descriptoren nicht ausgelesen. Beim Mounten des GerĂ€ts unter Linux wird dieses Feld ausgefĂŒllt. Leider kenne ich mich mit der Entwicklung unter Linux nur auf dem Niveau von „make && make install“ aus. Daher wurde das Problem mit einem eher groben Hack gelöst – durch HinzufĂŒgen in /etc/rc.local

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

Der Schluss

Nach einigen MĂŒhen funktioniert es. Das GewĂŒnschte wurde erhalten, jetzt kann der SchlĂŒssel an jeden PC angeschlossen (und natĂŒrlich auch wieder getrennt) werden, auch außerhalb des Broadcast-Segments des Netzwerks. Wenn gewĂŒnscht, kann dies mit einem Shell-Skript durchgefĂŒhrt werden. Schön ist, dass der Spaß völlig kostenlos ist.
Ich hoffe, dass meine Erfahrung den Nutzern hilft, die Stolpersteine zu umgehen, die mir auf die Stirn gedruckt wurden. Vielen Dank fĂŒr Ihre Aufmerksamkeit!

Quelle: habr.com

60GB SSD 8Gb DDR4