ubuntuusers.de

USBIP

Dieser Artikel wurde für die folgenden Ubuntu-Versionen getestet:


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.

./usbip_logo.png 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:

  1. 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]
  2. 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]
  3. 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.

  • 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:

  1. Laden der benötigten Module des Kernels

  2. 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 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:

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 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]:

    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.

Diese Revision wurde am 23. Juni 2024 16:01 von kB erstellt.
Die folgenden Schlagworte wurden dem Artikel zugewiesen: Netzwerk, System, Hardware