Für einen Kunden arbeite ich gerade an einem Thin-Client-Netzwerk: Dünne, unter Linux laufende Clients sollen per RDP-Client auf Windows-7-Pro-Instanzen zugreifen, die gesammelt auf einem Xen-Host ausgeführt werden. Für die Nicht-Verwendung von Windows Server 2008 mit Terminaldiensten gibt es den simplen Grund, dass einige der eingesetzten Anwendungen nicht in Terminalserverumgebungen lauffähig sind. Der Haken an der Geschichte: Es muss ein komfortabler Zugriff auf lokale USB-Geräte – Speichersticks, Chipkartenleser und ähnliches – möglich sein.
Wir haben daher zunächst mit USB-Servern fürs Netz experimentiert, derartige Geräte gibt es für netto 30 Euro (Ein-Port-Versionen mit unbekanntem chinesischen Hersteller, z.B. bei Conrad) bis 300 Euro (zwei oder vier Ports, Hutschienenmontage, Industriequalität, PoE, z.B. bei WuT). Mir gefiel aber nicht, neben dem Thinclient ein weiteres Gerät mit eigenem Netzteil (günstige Geräte können kein PoE) am Arbeitsplatz zu haben und habe daher nach Softwarelösungen für Linux gesucht. Gestoßen bin ich zunächst auf die kommerzielle Software USB Redirector, die jedoch für unser Szenario mit 75 oder 89US$ je Arbeitsplatz zu Buche schlagen würde. Gelandet bin ich schließlich beim freien Projekt USBIP, das jedoch nicht ganz trivial zur Zusammenarbeit zu bewegen ist. Geschafft habe ich es dennoch, Testsystem ist ein Ubuntu 12.04, die im nachfolgenden Text beschriebenen Schritte dürften so auch auf andere Systeme mit Kernel 3.1 oder höher anzuwenden sein. Als Client habe ich bislang nur Windows probiert über meine Erfahrungen mit Linux werde ich ggf. später berichten.
Auf der Serverseite
Mich machte bereits stutzig, dass das Projekt seit 2009 keine Aktualisierungen für Linux veröffentlicht hat. Dennoch gibt es einen recht aktuellen Client für Windows und Screenshots, die diesen bei der Arbeit zeigen. Ich ging daher davon aus, dass die Version 0.1.7 stabil und erprobt war (USB- in IP-Pakete zu kapseln ist schließlich so aufwendig nicht). Zumal usbip 0.1.7 in den Repositories von Ubuntu 12.04 enthalten ist. Ich installierte es und stieß bereits beim Start des Daemons auf Fehlermeldungen:
root@caesium:~# usbipd --debug usbipd: symbol lookup error: usbipd: undefined symbol: stub_driver
Den Grund zu finden erforderte eine ausgiebige Suche: Tatsächlich wird der Quellcode des USB-IP-Projektes seit einer Weile im Git-Repository des Linux-Kernels gepflegt – und das gilt auch für die Userlandwerkzeuge. Warum Ubuntu das veraltete Paket mitbringt, welches zwar unter neueren Kernel kompiliert, aber darüber hinaus nicht nutzbar ist, ist mir nicht ganz klar. Also: usbip-0.1.7-3 wieder deinstalliert und zurück auf Los.
Ubuntu 12.04 verwendet Linux 3.2 mit eigener Minor-Versionierung. Ich entschied mich daher für 3.2.23, natürlich können Sie auch Ubuntus Quellen verwenden. Entpacken Sie den Kernel und wechseln Sie in das Verzeichnis mit den Userland-Tools und bereiten Sie dort die Kompilation vor:
tar xvjf linux-3.2.23.tar.bz2 cd linux-3.2.23/drivers/staging/usbip/userspace bash autogen.sh ./configure --prefix=/usr --sysconfdir=/etc
Kleine Anpassungen erforderlich
Möchte man den Windows-Client 0.2.0.0 zusammen mit einem Kernel >3.0 verwenden, ist es gegebenenfalls erforderlich, die Protokollversion anzupassen: Aktuelle Linuxe sind derzeit bei 0x111, der Windows-Treiber kommuniziert nur mit 0x106. Ich habe daher die config.h abgeändert:
sed -i 's%USBIP_VERSION 0x00000111%USBIP_VERSION 0x00000106%g' config.h
Nehmen Sie diese Änderung nur vor, wenn Sie ausschließlich mit Windows-Clients der Version 0.2.0.0 auf den USB-IP-Server zugreifen wollen! Ich vermute, dass bald Windows-Clients erscheinen, welche diese Anpassung nicht erfordern.
Jetzt wird gebaut und installiert:
make && make install
Start des Daemons
Startet man den Daemon, gibt er möglicherweise eine Fehlermeldung aus:
root@caesium:~# usbipd --debug libusbip: debug: usbip_host_driver.c:244:[open_sysfs_host_driver] sysfs_open_driver_path failed usbipd: error: please load usbip-core.ko and usbip-host.ko!
Die erforderlichen Module aus dm Staging-Zweig müssen natürlich vorhanden sein (sind sie bei Ubuntu), im Zweifel mal nach USBIP in der Kernel-Config greppen:
root@caesium:~# modprobe -v usbip-host insmod /lib/modules/3.2.0-24-generic/kernel/drivers/staging/usbip/usbip-core.ko insmod /lib/modules/3.2.0-24-generic/kernel/drivers/staging/usbip/usbip-host.ko root@caesium:~# usbipd --debug & libusbip: debug: usbip_host_driver.c:189:[refresh_exported_devices] bind usbip-host.ko to a usb device to be exportable! usbipd: info: starting usbipd (usbip-utils 1.1.1) usbipd: info: listening on 0.0.0.0:3240 usbipd: debug: usbipd.c:394:[listen_all_addrinfo] listening on 1 address
Lassen wir uns lokale Geräte anzeigen…
root@caesium:~# usbip list -l Local USB devices ================= - busid 2-4 (0951:1603) 2-4:1.0 -> usb-storage - busid 4-1 (0a12:0001) 4-1:1.0 -> btusb 4-1:1.1 -> btusb 4-1:1.2 -> unknown
…und exportieren dann einen USB-Stick (den sollte man vorher übrigens unmounten):
root@caesium:~# usbip bind -b 2-4 bind device on busid 2-4: complete
Und nun der Windows-Client
Nun werden die Treiber gemäß der im Zip enthaltenen Installationsanleitung eingerichtet. Zum Verbinden mit dem Server dient das Programm usbip.exe, welches im Zip beiliegt, Caesium hat die IP 10.76.23.55, schauen wir mal nach den freigegebenen Geräten…

…und verbinden dann mit dem USB-Stick:

Kommando zurück: Verbindung trennen
Trennen erfordert etwas mehr Aufwand, zunächst muss unter Windows die Hardware sicher entfernt werden, dann folgt das Lösen der Verbindung zum Server (1 ist die virtuelle Portnummer, welche im zweiten screen beim Verbinden angezeigt wird):
usbip.exe -d 1
Auf Serverseite ist das Gerät noch verbunden:
root@caesium:~# usbip list -l Local USB devices ================= - busid 2-4 (0951:1603) 2-4:1.0 -> usbip-host
Es folgt die Trennung:
root@caesium:~# usbip unbind -b 2-4 unbind device on busid 2-4: complete root@caesium:~# usbip list -l Local USB devices ================= - busid 2-4 (0951:1603) 2-4:1.0 -> usb-storage
Trennt man nicht, verabschiedet sich Windows beim Shutdown möglicherweise mit einem Bluescreen. Dass USB-Fernzugriff zwischen Linux und Windows möglich ist, wäre damit bewiesen. In meinen kleinen Tests war die Verbindung stets zuverlässig. Wie sich Webcams und DVB-T-Sicks verhalten, probiere ich noch aus. Der weit aufwendigere Teil steht uns allerdings noch vor: Scripting und evtl. Erstellung eines Daemons für Windows, der neu an den Thinclient angeschlossene USB-Geräte, welche keine Drucker, Tastaturen und Mäuse sind, automatisch im Windows verfügbar macht, ohne das der Nutzer allzuviel interagieren muss.
Sehr interessant. Wirst du das Skript oder Teile davon veröffentlichen?
Ja, definitiv. Soweit fühle ich mich dem OSS-Gedanken verpflichtet. Vielleicht entsteht eine (temporär) kommerzielle Lösung mit mehr Komfort und “Enterprise”-Features, aber ich strebe schon an, den Komfort der billigen USB-Server auf Basis des freien usbip zu matchen oder zu übertreffen.
Danke, dass du mich an dieses Projekt erinnerst! Als ich das letzte mal schaute, gab es leider noch keinen Windows client. Damit war das für mich nicht so sehr interessant (auch wenn ich privat nur Linux einsetze).
Hi,
Echt gut das du deine Erfahrungen hier postest!
Ich will einen Raspberry pi als Server dafür einsetzten, die Sache ist aber schwieriger als ich gehofft hatte. Ich will auch einen Dvb-c stick darüber teilen, deswegen bin ich mal sehr gespannt auf deine Tests mit dem Dvb-t Stick!
Grüße
Cubii