USBIP
Dieser Artikel wurde für die folgenden Ubuntu-Versionen getestet:
Ubuntu 24.04 Noble Numbat
Ubuntu 22.04 Jammy Jellyfish
Ubuntu 20.04 Focal Fossa
Du möchtest den Artikel für eine weitere Ubuntu-Version testen? Mitarbeit im Wiki ist immer willkommen! Dazu sind die Hinweise zum Testen von Artikeln zu beachten.
Zum Verständnis dieses Artikels sind folgende Seiten hilfreich:
Das Projekt USB/IP 🇬🇧 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 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 Server und Client das Dienstprogramm usbip
und für den Server zusätzlich den 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:
Abfrage des für Update des Kernels benutzen Pakets:
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]
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]
In diesem Namen ersetzt man
image
(vielleicht auch:image-unsigned
) durchtools
, 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.
hwdata (optional)
linux-tools-*generic*
Befehl zum Installieren der Pakete:
sudo apt-get install hwdata linux-tools-*generic*
Oder mit apturl installieren, Link: apt://hwdata,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.
Achtung!
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:
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:
Laden der benötigten Module des Kernels
Start des DAEMONs
Manueller Start¶
Zuerst die Kernelmodule laden[3][4]:
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:
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 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]:
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 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:
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:
lsusb | grep -v -i hub
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 2-1.1 (10c4:8105) Silicon Labs : unknown product (10c4:8105) - busid 2-4 (8087:07dc) Intel Corp. : Bluetooth wireless interface (8087:07dc)
Die Freigabe erfolgt nun mit dem 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 Kommandounbind
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:
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
sudo modprobe vhci-hcd
laden[3][4]. Der vom Modul
vhci-hcd
benötigte weitere Modulusbip-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]:
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:
usbip list --remote 192.168.178.42
Beispielausgabe:
Exportable USB devices ====================== - 192.168.178.42 1-4.2: 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:
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:
usbip port
Man benötigt diese Angabe (hier beispielhaft: 0
), wenn man ein importiertes USB-Gerät wieder trennen möchte:
sudo usbip detach --port 0
Befehle¶
Befehl | Funktion | ||||
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. | ||||
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 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:
man usbip
man usbipd
Die Projektseite enthält einige technische Details, allerdings sind einige Bezeichnungen nicht mehr aktuell.
Links¶
Projektseite 🇬🇧
USB/IP for Windows 🇬🇧 – Eine experimentelle USB/IP Implementation für Windows, für den produktiven Betrieb nicht empfohlen.
USB/IP protocol 🇬🇧 in der Kernel Dokumentation