[[Vorlage(Getestet, noble jammy focal)]] {{{#!vorlage Wissen [:Pakete installieren: Installation von Programmen] [:Programme_starten: Starten von Programmen] [:Terminal: Ein Terminal öffnen] [:mit Root-Rechten arbeiten:] [:Editor:einen Editor öffnen] }}} [[Inhaltsverzeichnis(2)]] [[Bild(./usbip_logo.png, 75, align=left)]] Das Projekt [sourceforge2:usbip:USB/IP] {en} erstellt Software für USB-über-TCP/IP. Damit kann man die an ein Linux-System angeschlossenen USB-Geräte wie Mäuse, USB-Sticks usw. über das Netzwerk auf einem anderen System so benutzen, als wären es lokale USB-Geräte. Es gibt [#Links USB/IP Implementierungen für Windows], die auch Interoperabilität mit Linux anstreben. Diese Lösungen haben aber experimentellen Charakter und werden für den produktiven Betrieb nicht empfohlen, und daher in diesem Artikel weiter nicht behandelt. = Installation = Die Software des Projektes USB/IP ist stark vom jeweils benutzen Kernel abhängig, und daher ist ihre Installation etwas komplizierter als von anderen Paketen gewohnt. Die grundsätzliche Unterstützung für die Funktionalität USB-über-TCP/IP ist bei Kernel von Ubuntu in ladbaren Modulen enthalten und daher bei einem gepflegten System bereits enthalten – darum muss man sich selber nicht kümmern. Man benötigt zusätzlich für [#Konfiguration Server und Client] das Dienstprogramm `usbip` und für den Server zusätzlich den [:Dienste:DAEMON] `usbipd`. Diese Programme sind enthalten in einem Paket mit dem Namensmuster '''linux-tools-*''', dessen genauer Name davon abhängt, über welches Paket man die Updates für den konkret im System eingesetzten Kernel bezieht. Den für das eigene System gültigen Paketnamen kann man im Terminal[3][2] so ermitteln: 1. Abfrage des für Update des Kernels benutzen Pakets: [[Vorlage(Befehl, "apt list 'linux-image-*' --installed") ]] Beispielausgabe: {{{ linux-image-6.5.0-28-generic/jammy-updates,jammy-security,now 6.5.0-28.29~22.04.1 amd64 [Installiert,automatisch] linux-image-6.5.0-35-generic/jammy-updates,jammy-security,now 6.5.0-35.35~22.04.1 amd64 [Installiert,automatisch] linux-image-generic-hwe-22.04/jammy-updates,jammy-security,now 6.5.0.35.35~22.04.1 amd64 [Installiert,automatisch] }}} 1. Man streicht aus dieser Liste alle Pakete mit einer konkreten Kernelversion im Namen, dann sollte nur noch ein Paket verbleiben, im Beispiel: {{{ linux-image-generic-hwe-22.04/jammy-updates,jammy-security,now 6.5.0.35.35~22.04.1 amd64 [Installiert,automatisch] }}} 1. In diesem Namen ersetzt man `image` (vielleicht auch: `image-unsigned`) durch `tools`, dies ist das zu installierende Paket. Bevor man dieses Paket installiert, kann man noch das für USB/IP optionale Paket '''hwdata''' installieren, was aber standardmäßig schon installiert sein sollte. Dieses optionale Paket übersetzt einige USB-IDs in Klartext. Installiert werden muss das richtige Paket mit dem Namensmuster `linux-tools-*generic*`[1], darin sind die Sternchen systemspezifisch zu ersetzen. Wenn man keinen Kernel des Typs `generic`, sondern des Typs `lowlatency` benutzt, so ist auch dieser Namensteil zu ändern. {{{#!vorlage Paketinstallation hwdata, optional linux-tools-*generic* }}} Diese Prozedur installiert das zum aus Sicht des eigenen Systems aktuellen Kernels passende Paket '''linux-tools*''' und sorgt auch dafür, dass dies auch für alle zukünftigen im Rahmen regulärer Updates installierten Kernel zutrifft. Man muss diese Prozedur also nur einmal ausführen. Man erhält aber nicht die passenden Pakete für ältere Kernel. {{{#!vorlage Warnung Die vorstehende Installationsanweisung gilt für Ubuntu-Versionen ab [:15.04:] mit Kernel Version 3.19. Vor der Integration von USB/IP in den Kernel ab Version 3.17 gab es eigenständige Pakete. Wer diese völlig veralteten und störenden Pakete noch in seinem System hat, muss sie vor der Installation auf jeden Fall entfernen: [[Vorlage(Befehl, "sudo apt-get remove --purge usbip* libusbip*" ) ]] }}} = Konfiguration = USB/IP unterscheidet die Rollen Server und Client: * Der Server stellt eines oder mehrere seiner direkt an ihm angeschlossenen USB-Geräte zur Verfügung und exportiert diese über das Netzwerk. * Der Client greift über das Netzwerk aus den Server zu und importiert eines oder mehrere Geräte in seine eigene Konfiguration. Diese virtuellen Geräte können genau wie direkt angeschlossene reale Geräte mit einem Treiber initialisiert und dann am Client benutzt werden. In der Regel geschieht die Initialisierung automatisch. Beachte aber: Ein vom Server exportiertes Gerät kann nicht mehr lokal benutzt werden und ein über das Netzwerk verfügbares Gerät kann maximal von einem Client zeitgleich belegt werden. == Start und Stopp des Servers == Nach der Installation der Software muss man noch eine zur eigenen Aufgabenstellung passende Startmethode einrichten. Dafür werden in folgenden Text mehrere Möglichkeiten vorgestellt. Generell müssen zwei Aufgaben gelöst werden: 1. Laden der benötigten Module des Kernels 1. Start des DAEMONs === Manueller Start === Zuerst die Kernelmodule laden[3][4]: [[Vorlage(Befehl, "sudo modprobe usbip-host" ) ]] Der vom Modul `usbip-host` benötigte weitere Modul `usbip-core` wird automatisch geladen. Nun kann ein USB/IP Server gestartet werden: [[Vorlage(Befehl, "sudo usbipd --daemon" ) ]] Mit diesem Befehl startet das Programm als DAEMON, die Option `-daemon` kann man mit `-D` abkürzen. Der Server lauscht auf dem TCP-Port `3240`; das kann man wie in der [#Dokumentation Dokumentation] beschrieben ändern. Man kann zu Diagnose den Server ohne die Option `--daemon` starten und erhält das Meldungen auf das Terminal. === Halbautomatik === Alternativ kann man die beiden Module automatisch beim Systemstart laden lassen. Dazu muss [:root:] lediglich eine Systemdatei erstellen[4][5]: [[Vorlage(Befehl, "echo usbip-host | sudo tee /etc/modules-load.d/USB-over-IP-server.conf" ) ]] === Automatik === Zum Start des Servers bzw. generell zur Steuerung des Servers kann man sich selbst eine [:systemd/Units: Unit für Systemd] anlegen, die dann auch den Start der Module übernimmt: {{{ # /etc/systemd/system/USB-over-IP-server.service # 2024 – kB @ UbuntuUsers.de [Unit] Description = USB over TCP/IP host daemon %H Documentation = https://wiki.ubuntuusers.de/USBIP/ After = network-online.target Wants = network-online.target [Service] Type = simple Restart = on-failure ExecStartPre = modprobe usbip-host ExecStart = usbipd --tcp-port 3240 ExecStopPost = rmmod usbip-host ExecStopPost = rmmod usbip-core [Install] WantedBy = multi-user.target }}} Zur Steuerung des Servers nutzt man dann fallweise die Kommandos `start`, `status`, `stop` usw. von [:systemctl:] oder man aktiviert einmalig mit `enable` den automatischen Start beim Systemstart. === Manueller Stopp === Wenn man keine Unit für Systemd erstellt hat, ist der Server nur mit roher Gewalt zu stoppen, beispielsweise: [[Vorlage(Befehl, "sudo pkill usbipd" ) ]] == Konfigurierung des Servers == Der gestartete Server exportiert noch keine Geräte. Man kann grundsätzlich jedes vorhandene USB-Endgerät, aber keine USB-Hubs freigeben; die möglichen Kandidaten für eine Freigabe werden mit folgenden Befehlen angezeigt: * [[Vorlage(Befehl, "lsusb | grep -v -i hub" ) ]] * [[Vorlage(Befehl, "usbip list --local" ) ]] Die Option `--local` kann man mit `-l` abkürzen. * Zur Freigabe eines Gerätes benötigt man dessen Bus-ID, das sind die in folgender Beispielausgabe des letzten Befehls markierten Kennungen: {{{ - busid [mark]2-1.1[/mark] (10c4:8105) Silicon Labs : unknown product (10c4:8105) - busid [mark]2-4[/mark] (8087:07dc) Intel Corp. : Bluetooth wireless interface (8087:07dc) }}} * Die Freigabe erfolgt nun mit dem Befehl: [[Vorlage(Befehl, "sudo usbip bind --busid 2-1.1" ) ]] Die hier beispielhafte Bus-ID `2-1.1` ist durch eine aus dem eigenen System zu ersetzen. Die Option `--busid` kann man mit `-b` abkürzen. Ein entsprechender Befehl mit dem Kommando `unbind` widerruft die Freigabe. Das Kommando `bind` des Befehls `usbip` trennt zunächst auf dem Server das genannte USB-Gerät von seinem Treiber, d.h. das Gerät ist danach auf dem Server nicht mehr verwendbar. Dann wird dem Gerät ein Treiber von USB/IP zugeordnet und damit ist es über das Netzwerk erreichbar. Die exportierten bzw. freigegebenen Geräte zeigt auf dem Server dieser Befehl: [[Vorlage(Befehl, "usbip list --remote 127.0.0.1" ) ]] Die Option `--remote` kann man mit `-r` abkürzen. Dieser Befehl funktioniert natürlich auch auf jedem USB/IP Client mit einer nicht-lokalen IP-Adresse des Servers. == Client vorbereiten == Man kann jeden Ubuntu Rechner zum USB/IP Client ertüchtigen. Dafür sind lediglich Module des Kernels zu laden. * Die benötigten Module kann man fallweise mit dem Befehl [[Vorlage(Befehl, "sudo modprobe vhci-hcd" ) ]] laden[3][4]. Der vom Modul `vhci-hcd` benötigte weitere Modul `usbip-core` wird automatisch geladen. * Alternativ kann man die beiden Module automatisch beim Systemstart laden lassen. Dazu muss [:root:] lediglich einmalig eine Systemdatei erstellen[4][5]: [[Vorlage(Befehl, "echo vhci-hcd | sudo tee /etc/modules-load.d/USB-over-IP-client.conf" ) ]] == Bedienung des Clients == Ein USB/IP Client kann von einem oder mehreren USB/IP Servern USB-Geräte importieren. Dazu benötigt der Client lediglich die IP-Adresse (hier beispielhaft: `192.168.178.42`) und den TCP-Port des Servers (Vorgabe: `3240`) und muss die Bus-ID des Gerätes ermitteln. Die exportierten bzw. freigegebenen Geräte des Servers `192.168.178.42` zeigt auf dem Client dieser Befehl: [[Vorlage(Befehl, "usbip list --remote 192.168.178.42" ) ]] Beispielausgabe: {{{ Exportable USB devices ====================== - 192.168.178.42 [mark]1-4.2[/mark]: SanDisk Corp. : Cruzer Blade (0781:5567) : /sys/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4.2 : (Defined at Interface level) (00/00/00) : 0 - Mass Storage / SCSI / Bulk-Only (08/06/50) }}} Die zum Import benötigte Bus-ID (hier beispielhaft: `1-4.2`) des exportierten Gerätes entnimmt man der Ausgabe des vorstehenden Befehls: [[Vorlage(Befehl, "sudo usbip attach --remote 192.168.178.42 --busid 1-4.2" ) ]] Das Kommando `attach` des Befehls `usbip` reserviert das genannte Gerät zus ausschließlichen Verwendung durch diesen Client und verbindet das Gerät mit einem eigenen virtuellen USB-Port. Das System initialisiert dann automatisch das neue Gerät mit einem passenden Treiber. Die so über das Netzwerk angeschlossenen USB-Geräte werden vom Befehl [:lsusb:] genau wie direkt angeschlossene USB-Geräte behandelt und insbesondere auch angezeigt. Die mit Geräten belegten virtuellen USB-Ports listet der Befehl: [[Vorlage(Befehl, "usbip port" ) ]] Man benötigt diese Angabe (hier beispielhaft: `0`), wenn man ein importiertes USB-Gerät wieder trennen möchte: [[Vorlage(Befehl, "sudo usbip detach --port 0" ) ]] = Befehle = {{{#!vorlage Tabelle Befehl Funktion +++ <-6> '''Serverbefehle''' +++ `usbip list -l` Hiermit können alle lokalen USB-Geräte angezeigt werden, welche freigegeben werden können. +++ `usbip bind -b "Bus-ID"` Hiermit kann ein USB-Gerät mit der zugeordneten Bus-ID zu den freigegebenen USB-Geräten hinzugefügt werden. +++ `usbip unbind -b "Bus-ID"` Hiermit kann die Freigabe eines USB-Gerätes rückgängig gemacht werden. +++ <-6> '''Clientbefehle''' +++ `usbip attach -r "Serveraddresse" -b "Bus-ID"` Hiermit kann ein freigegebenes USB-Gerät ins Client-System eingehängt werden. Dies muss zwingend mit Root-Rechten erfolgen! +++ `usbip detach -p "Port"` Hiermit kann ein USB-Gerät wieder ausgehängt werden. Der Port kann mit `usbip port` ermittelt werden. +++ `usbip list -r "Serveradresse"` Hiermit können alle freigegebenen USB-Geräte eines Servers angezeigt werden. +++ `usbip port` Hiermit kann man sich alle eingehängten USB-Geräte anzeigen lassen. }}} = Sicherheit = Ein USB/IP Server verfügt selbst über keine Mechanismen zur Beschränkung von Zugriffen, sondern akzeptiert Verbindungen aus aller Welt. Oft ist dies unerwünscht. Zur Abhilfe sollte man den USB/IP Server hinter einer Firewall betreiben und damit mögliche Zugriffe auf solche aus dem eigenen LAN beschränken. Wenn dieses LAN technisch offenen Zugang für alle bietet (z.B. WLAN), ist natürlich eine Zugangsregulierung und -beschränkung unverzichtbar. = Technische Begrenzungen = Die Konfiguration der Ubuntu Kernel sieht einen virtuellen USB-Controller mit maximal 8 Ports vor. Wenn das nicht ausreicht, muss man den Linux Kernel aus dem Quellcode mit einer angepassten Konfiguration selbst übersetzen. Der Zugriff auf USB-Geräte über das Netzwerk funktioniert zwar grundsätzlich mit jedem USB-Gerät, z.B. auch wie [#Bedienung-des-Clients oben] gezeigt mit USB-Sticks, jedoch bedeutet dies nicht, dass es immer gut funktioniert. Vielmehr muss man in der Praxis über das Netzwerk stets mit schlechterer Performanz und Zeitverzögerungen rechnen als bei direktem Anschluss des USB-Gerätes, da das USB-Protokoll für Situationen entwickelt wurde, in denen Latenzen vernachlässigbar sind, während bei TCP/IP gegen Latenzen robust sein soll und selbst auch durch Speicherung und Bearbeitung der IP-Pakete in den Netzwerkgeräten unvermeidlich Latenzen erzeugt; dies kann bis zum völligen Versagen führen. Generell sollte man daher bei der Anwendung von USB-über-TCP/IP beachten: * Die zu übertragene Datenmenge auf ein Minimum reduzieren. * Eine Übertragungsstrecke mit möglichst wenigen Netzwerkgeräten (Repeater, Switch, Router, Gateway usw.) verwenden. * Medienwechsel (z.B. Wifi/WLAN <--> Ethernet) vermeiden. = Dokumentation = Die Programme `usbip` und `usbipd` haben jeweils eine eigene [:Manpage:]: * [[Vorlage(Befehl, "man usbip" ) ]] * [[Vorlage(Befehl, "man usbipd" ) ]] Die [#Links Projektseite] enthält einige technische Details, allerdings sind einige Bezeichnungen nicht mehr aktuell. = Links = * [sourceforge2:usbip:Projektseite] {en} * [https://github.com/cezanne/usbip-win USB/IP for Windows] {en} – Eine experimentelle USB/IP Implementation für Windows, für den produktiven Betrieb nicht empfohlen. * [https://www.kernel.org/doc/html/latest/usb/usbip_protocol.html USB/IP protocol] {en} in der Kernel Dokumentation #tag: Netzwerk, System, Hardware