Укротяване на USB/IP

Задачата за свързване на USB устройство към отдалечен компютър чрез локална мрежа възниква редовно. Под изрезката е изложена историята на моите търсения в тази посока и пътят към готово решение, базирано на проект с отворен код USB/IP с описание на препятствията, внимателно поставени от различни хора по този път, както и начини за заобикалянето им.

Част първа, историческа

Ако машината е виртуална - всичко това е лесно. Функционалността на USB пренасочване от хост към виртуална машина се появи във VMWare 4.1. Но в моя случай ключът за сигурност, разпознаваем като WIBU-KEY, трябваше да бъде свързан по различно време към различни машини, а не само виртуални.
Първият кръг на търсене през далечната 2009 г. ме доведе до едно парче желязо, наречено TrendNet TU2-NU4
плюсове:

  • понякога дори работи

против:

  • не винаги работи. Да предположим, че защитният ключ Guardant Stealth II не стартира през него, кълнейки се с грешката „устройството не може да се стартира“.
  • Софтуерът за управление (чети - монтиране и демонтиране на USB устройства) е жалък до краен предел. Превключватели на командния ред, автоматизация - не, не съм чувал. Всичко е само на ръка. Кошмар.
  • софтуерът за управление търси самото парче желязо в мрежата чрез излъчване, така че това работи само в рамките на един сегмент на мрежата за излъчване. Не можете да посочите на ръка IP адреса на желязото. Парче желязо в друга подмрежа? Тогава имате проблем.
  • разработчиците отбелязаха на устройството, безполезно е да се изпращат доклади за грешки.

Вторият кръг се случи в не толкова далечни времена и ме доведе до темата на статията - USB/IP проект. Привлича с откритост, особено след като момчетата от ReactOS те подписаха драйвер за Windows, така че сега всичко работи дори на x64 без никакви патерици като тестов режим. За което много благодаря на екипа на ReactOS! Всичко звучи красиво, нека се опитаме да го усетим, наистина ли е така? За съжаление, самият проект също е изоставен и не можете да разчитате на подкрепа - но където нашият не изчезна, източникът е там, ще го разберем!

Част втора, server-linux

USB/IP сървър, който споделя USB устройства по мрежа, може да бъде настроен само на базирана на Linux операционна система. Е, Linux си е Linux, ние инсталираме Debian 8 на виртуална машина в минималната конфигурация, стандартно движение на ръката:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install usbip

Уредено. Освен това интернет предполага, че ще трябва да изтеглите usbip модула, но - здравей, първият рейк. Няма такъв модул. И всичко това, защото повечето ръководства в мрежата се отнасят до по-стария клон 0.1.x, а в най-новия 0.2.0 usbip модулите имат различни имена.

Ето защо:

sudo modprobe usbip-core
sudo modprobe usbip-host
sudo lsmod | grep usbip

Е, нека добавим следните редове към /etc/modules, за да ги зареждаме автоматично при стартиране на системата:

usbip-core
usbip-host
vhci-hcd

Нека стартираме usbip сървъра:

sudo usbipd -D

Освен това, универсалният ум ни казва, че usbip идва със скриптове, които ни позволяват да управляваме сървъра - показваме кое устройство ще споделя в мрежата, виждаме състоянието и т.н. Тук ни очаква друг градински инструмент - тези скриптове в клона 0.2.x отново са преименувани. Можете да получите списък с команди с

sudo usbip

След като прочетете описанието на командите, става ясно, че за да сподели необходимото USB устройство, usbip иска да знае неговия Bus ID. Уважаеми зрители, рейк номер три е на арената: ID на автобуса, който ще ни даде lsusb (изглежда най-очевидният начин) - не й подхожда! Факт е, че usbip игнорира хардуер като USB хъбове. Затова ще използваме вградената команда:

user@usb-server:~$ sudo usbip list -l
 - busid 1-1 (064f:0bd7)
   WIBU-Systems AG : BOX/U (064f:0bd7)

Забележка: по-нататък в списъците ще опиша всичко на примера на моя конкретен USB ключ. Вашето име на хардуер и двойка VID:PID могат и ще се различават. Моят се казва Wibu-Systems AG: BOX/U, VID 064F, PID 0BD7.

Сега можем да споделим нашето устройство:

user@usb-server:~$ sudo usbip bind --busid=1-1
usbip: info: bind device on busid 1-1: complete

Ура, другари!

user@usb-server:~$ sudo usbip list -r localhost
Exportable USB devices
======================
 - 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
           : Vendor Specific Class / unknown subclass / unknown protocol (ff/00/ff)

Три пъти наздраве, другари! Сървърът сподели желязото по мрежата и можем да го свържем! Остава само да добавите автоматичното стартиране на usbip демона в /etc/rc.local

usbipd -D

Част трета, клиентска и объркваща

Опитах се да свържа споделеното устройство по мрежата към Debian машина веднага на същия сървър и всичко се свърза добре:

sudo usbip attach --remote=localhost --busid=1-1

Да преминем към Windows. В моя случай беше Windows Server 2008R2 Standard Edition. Официалното ръководство ви моли първо да инсталирате драйвера. Процедурата е описана идеално в readme-то, приложено към windows клиента, правим всичко както е написано, всичко работи. На XP също работи без проблеми.

След като разопаковаме клиента, се опитваме да монтираме нашия ключ:

C:Program FilesUSB-IP>usbip -a %server-ip% 1-1
usbip err: usbip_network.c: 121 (usbip_recv_op_common) recv op_common, -1
usbip err: usbip_windows.c: 756 (query_interface0) recv op_common
usbip err: usbip_windows.c: 829 (attach_device) cannot find device

Ох ох. Нещо се обърка. Ние използваме уменията на Google. Има откъслечни споменавания, че нещо не е наред с константите; в сървърната част разработчиците промениха версията на протокола при преминаване към версия 0.2.0, но забравиха да направят това в Win клиента. Предложеното решение е да се промени константата в изходния код и да се изгради отново клиента.

Но наистина не искам да изтеглям Visual Studio в името на тази процедура. Но имам добър стар Hiew. В изходния код константата е декларирана като двойна дума. Нека потърсим във файла 0x00000106, като го заменим с 0x00000111. Не забравяйте, че редът на байтовете е обърнат. Резултатът е две съвпадения, кръпка:

[usbip.exe]
00000CBC: 06 11
00000E0A: 06 11

Еееее... да!

C:Program FilesUSB-IP>usbip -a %server-ip% 1-1
new usb device attached to usbvbus port 1

Това можеше да сложи край на презентацията, но музиката не свири дълго. След рестартиране на сървъра установих, че устройството на клиента не е монтирано!

C:Program FilesUSB-IP>usbip -a %server-ip% 1-1
usbip err: usbip_windows.c: 829 (attach_device) cannot find device

И това е. Дори всезнаещият Google не можа да ми отговори на това. И в същото време командата за показване на устройства, налични на сървъра, показва съвсем правилно - ето го, ключът, можете да го монтирате. Опитвам се да монтирам от Linux - работи! И ако сега опитате от Windows? О, мамка му - работи!

Последният рейк: нещо не е добавено в кода на сървъра. При споделяне на устройство, то не чете броя на USB дескрипторите от него. И когато монтирате устройството от Linux, това поле се попълва. За съжаление съм запознат с разработката под Linux на ниво „make && make install“. Следователно проблемът се решава с доста мръсен хак - добавяне към /etc/rc.local

usbip attach --remote=localhost --busid=1-1
usbip port
usbip detach --port=00

Част окончателна

След известно ръчкане работи. Желаният резултат е получен, сега ключът може да бъде монтиран на всеки компютър (и демонтиран, разбира се), включително извън сегмента на излъчващата мрежа. Ако искате, можете да го направите с помощта на shell скрипт. Какво е хубаво - удоволствието е абсолютно безплатно.
Надявам се опитът ми да помогне на хабражителите да заобиколят греблото, което се отпечата на челото ми. Благодаря за вниманието!

Източник: www.habr.com

Добавяне на нов коментар