Często pojawia się zadanie podłączenia urządzenia USB do zdalnego komputera przez lokalną sieć. Poniżej znajduje się historia moich poszukiwań w tym kierunku oraz droga do gotowego rozwiązania opartego na projekcie open-source. z opisem starannie zainstalowanych przez różnych ludzi przeszkód na tej drodze, a także sposobów ich obejścia.
Część pierwsza, historyczna
Jeśli maszyna jest wirtualna — wszystko jest proste. Funkcjonalność przekazywania USB z hosta do wirtualki pojawiła się już w VMWare 4.1. Ale w moim przypadku klucz zabezpieczający, rozpoznawany jako WIBU-KEY, musiał być w różnym czasie podłączany do różnych maszyn, i nie tylko wirtualnych.
Pierwsza runda poszukiwań w odległym 2009 roku zaprowadziła mnie do urządzenia o nazwie
Zalety:
- czasami nawet działa
Wady:
- działa nie zawsze. Na przykład klucz zabezpieczający Guardant Stealth II przez nią się nie uruchamia, zgłaszając błąd „urządzenie nie może być uruchomione”.
- Oprogramowanie do zarządzania (czytaj — montowania i demontowania urządzeń USB) jest skrajnie ubogie. Klucze wiersza poleceń, automatyzacja — nie, nie słyszeli. Wszystko tylko ręcznie. Koszmar.
- oprogramowanie zarządzające wyszukuje samo urządzenie w sieci przez broadcast, więc działa to tylko w obrębie jednego segmentu broadcastowego sieci. Nie można ręcznie wskazać adresu IP urządzenia. Urządzenie w innej podsieci? Wtedy masz problem.
- programiści zignorowali urządzenie, wysyłanie raportów o błędach jest bezsensowne.
Druga runda wydarzyła się w nie tak odległych czasach i zaprowadziła mnie do tematu artykułu — . Przyciąga swoją otwartością, tym bardziej, że chłopaki z podpisali dla niego sterownik dla Windows, więc teraz nawet na x64 wszystko działa bez żadnych obejść, jak tryb testowy. Za co ogromne podziękowania dla zespołu ReactOS! Brzmi to pięknie, spróbujemy sprawdzić, czy tak jest w rzeczywistości? Niestety, sam projekt również został nieco porzucony, więc nie ma co liczyć na wsparcie — ale gdzie nasza nie zginęła, źródło jest, poradzimy sobie!
Część druga, serwerowo-linuxowa
Serwer USB/IP, który dzieli urządzenia USB w sieci, może być uruchomiony tylko w systemach operacyjnych opartych na Linuksie. Cóż, linuks to linuks, instalujemy na wirtualce Debian 8 w minimalnej konfiguracji, standardowe ręczne ruchy:
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install usbipZainstalowano. Następnie internet podpowiada, że należy załadować moduł usbip, ale oto pierwsza przeszkoda. Tego modułu nie ma. Wszystko przez to, że większość poradników w sieci odnosi się do starszej wersji 0.1.x, a w najnowszej 0.2.0 moduły usbip mają inne nazwy.
Dlatego:
sudo modprobe usbip-core
sudo modprobe usbip-host
sudo lsmod | grep usbipA teraz dodamy do /etc/modules takie linie, aby ładować je automatycznie przy starcie systemu:
usbip-core
usbip-host
vhci-hcdUruchomimy serwer usbip:
sudo usbipd -DNastępnie wszechwiedzący internet podpowiada nam, że razem z usbip dostarczane są skrypty, które pozwalają na zarządzanie serwerem — pokazują, jakie urządzenie będzie udostępniane w sieci, sprawdzają status i tak dalej. Czeka nas jeszcze jedna przeszkoda — te skrypty w wersji 0.2.x zostały ponownie nazwane. Możemy uzyskać listę poleceń za pomocą
sudo usbipPo przeczytaniu opisu poleceń staje się jasne, że aby udostępnić wymagane urządzenie USB, usbip chce poznać jego Bus ID. Szanowni widzowie, na scenie trzecia przeszkoda: ten Bus ID, który otrzymamy lsusb (wydawałoby się, że najoczywistsza droga) — nie będzie odpowiedni! Chodzi o to, że urządzenia takie jak huby USB są ignorowane przez usbip. Dlatego skorzystamy z wbudowanego polecenia:
user@usb-serwer:~$ sudo usbip list -l
- busid 1-1 (064f:0bd7)
WIBU-Systems AG : BOX/U (064f:0bd7)Uwaga: w dalszych listingach będę wszystko opisywał na przykładzie mojego konkretnego klucza USB. Nazwy twoich urządzeń i pary VID:PID mogą się różnić. Mój nosi nazwę Wibu-Systems AG: BOX/U, VID 064F, PID 0BD7.
Teraz możemy udostępnić nasze urządzenie:
user@usb-serwer:~$ sudo usbip bind --busid=1-1
usbip: info: bind device on busid 1-1: completeHurra, towarzysze!
user@usb-serwer:~$ sudo usbip list -r localhost
Eksportowane urządzenia USB
=========================
- 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
: Klasa specyficzna dla producenta / nieznany podtyp / nieznany protokół (ff/00/ff)Trzykrotne hurra, towarzysze! Serwer udostępnił urządzenie w sieci, możemy je podłączyć! Pozostaje tylko dopisać autostart demona usbip w /etc/rc.local
usbipd -DCzęść trzecia, kliencka i zagmatwana
Spróbowałem podłączyć udostępnione urządzenie w sieci do maszyny z systemem Debian od razu na tym samym serwerze, i wszystko świetnie się podłączyło:
sudo usbip attach --remote=localhost --busid=1-1Przechodzimy do Windows. W moim przypadku był to Windows Server 2008R2 Standard Edition. Oficjalny poradnik prosi najpierw o zainstalowanie sterownika. Procedura jest dobrze opisana w załączonym do klienta windows readme, robimy wszystko jak napisano i wszystko wychodzi. Na XP również działa bez jakichkolwiek trudności.
Rozpakowując klienta, próbujemy zamontować nasz klucz:
C:Program FilesUSB-IP>usbip -a %server-ip% 1-1
usbip err: usbip_network.c: 121 (usbip_recv_op_common) odbierz op_common, -1
usbip err: usbip_windows.c: 756 (query_interface0) odbierz op_common
usbip err: usbip_windows.c: 829 (attach_device) nie można znaleźć urządzeniaOjej. Coś poszło nie tak. Używamy umiejętności googlowania. Napotykam fragmentaryczne wzmianki, że coś jest nie tak z stałymi, w serwerowej części programiści przy przejściu na wersję 0.2.0 zmienili wersję protokołu, a w kliencie pod Win zapomniano to zrobić. Proponowane rozwiązanie - zmień stałą w źródle i przebuduj klienta.
Jednak bardzo nie chcę pobierać Visual Studio na tę procedurę. Mam za to dobrego, starego Hiewa. W źródle stała jest zadeklarowana jako podwójne słowo. Poszukajmy w pliku 0x00000106, zamieniając na 0x00000111. Nie zapominajmy, że kolejność bajtów jest odwrotna. Efekt - dwa dopasowania, łata:
[usbip.exe]
00000CBC: 06 11
00000E0A: 06 11Iiiiii... tak!
C:Program FilesUSB-IP>usbip -a %server-ip% 1-1
nowe urządzenie USB podłączone do portu usbvbus 1Na tym mogłoby się skończyć moje wywody, ale muzyka nie grała długo. Po ponownym uruchomieniu serwera odkryłem, że urządzenie na kliencie się nie montuje!
C:Program FilesUSB-IP>usbip -a %server-ip% 1-1
usbip err: usbip_windows.c: 829 (attach_device) nie można znaleźć urządzeniaI to wszystko. Na to nie potrafił odpowiedzieć nawet wszystko wiedzący Google. A przy tym polecenie wyświetlenia dostępnych urządzeń na serwerze całkiem poprawnie pokazuje — oto klucz, możecie montować. Próbuję zamontować z poziomu Linuxa — działa! A teraz spróbujmy z poziomu Windows? O zgrozo — to działa!
Ostatni problem: coś tam w kodzie serwera nie jest dopisane. Przy udostępnianiu urządzenia nie odczytuje liczby opisów USB. A przy montowaniu urządzenia z poziomu Linuxa, to pole się wypełnia. Niestety, z programowaniem pod Linuxem znam się na poziomie „make && make install”. Dlatego problem został rozwiązany przy użyciu dość brudnego hacka — dodając do /etc/rc.local
usbip attach --remote=localhost --busid=1-1
usbip port
usbip detach --port=00Część końcowa
Po kilku zawirowaniach wszystko działa. Oczekiwany rezultat uzyskany, teraz klucz można zamontować na dowolnym komputerze (i oczywiście również odmontować), w tym — poza segmentem sieci rozgłoszeniowej. Jeśli chcesz — możesz to zrobić za pomocą skryptu powłoki. Co ważne — przyjemność jest całkowicie darmowa.
Mam nadzieję, że moje doświadczenie pomoże użytkownikom Habr unikać tych pułapek, które odcisnęły się na moim czole. Dziękuję za uwagę!
Źródło: habr.com
