Утаймоўваем USB/IP

Рэгулярна ўзнікае задача падлучэння USB-прылады да выдаленага ПК праз лакальную сетку. Пад катам выкладзена гісторыя маіх пошукаў у гэтым кірунку, і шлях да гатовага рашэння на базе open-source праекту USB/IP з апісаннем клапатліва ўсталяваных рознымі людзьмі на гэтым шляху перашкод, а таксама спосабаў іх абыходу.

Частка першая, гістарычная

Калі машына віртуальная усё гэта нескладана. Функцыянал пракіду USB ад хаста ў віртуалку з'явіўся яшчэ ў VMWare 4.1. Але ў маім выпадку ключык абароны, які апазнаецца як WIBU-KEY, трэба было ў розны час падлучаць да розных машын, і не толькі віртуальным.
Першы віток пошуку ў далёкім 2009-м годзе прывёў мяне да жалязякі пад назвай TrendNet TU2-NU4
Плюсы:

  • часам нават працуе

Мінусы:

  • працуе не заўсёды. Дапушчальны, ключ абароны Guardant Stealth II праз яе не заводзіцца, лаючыся памылкай "прылада не можа быць запушчана".
  • ПА для кіравання (чытай - мантавання і размантавання USB-прылад) убога да крайнасці. Ключы каманднага радка, аўтаматызацыя - не, не чулі. Усё толькі рукамі. Кашмар.
  • кіравальнае ПА шукае саму жалязяку ў сетцы шырокавяшчаннем, таму працуе гэта толькі ў межах аднаго broadcast-сегмента сеткі. Указаць IP-адрас жалязякі рукамі нельга. Жалезка ў іншай падсетцы? Тады ў вас праблема.
  • распрацоўшчыкі забілі на прыладу, слаць баг-рэпарты бескарысна.

Другі віток здарыўся ў часы ўжо не гэтак падаленыя, і прывёў мяне да тэмы артыкула. USB/IP project. Прыцягвае адкрытасцю, тым больш, што хлопцы з ReactOS падпісалі ім драйвер для Windows, так што зараз нават на x64 усё працуе без усякіх мыліц накшталт тэставага рэжыму. Завошта камандзе ReactOS вялікі дзякуй! Гучыць усё прыгожа, паспрабуем памацаць, ці так яно на справе? На жаль, сам праект таксама падзакінуты, і на падтрымку разлічваць не даводзіцца - але дзе наша не знікала, зыходнік ёсць, разбярэмся!

Частка другая, серверна-лінуксавая

Сервер USB/IP, які расшароўвае USB-дэвайсы па сетцы, можа быць падняты толькі ў Linux-based OS. Ну што ж, лінукс дык лінукс, які ўсталёўваецца на віртуалку 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. Паважаныя гледачы, на арэне граблі нумар тры: той Bus ID, які выдасць нам lsusb (здавалася б, самы відавочны шлях) - ёй не падыходзіць! Справа ў тым, што жалязякі накшталт USB-хабаў usbip ігнаруе. Таму, скарыстаемся ўбудаванай камандай:

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. Афіцыйнае кіраўніцтва просіць спачатку ўсталяваць драйвер. Працэдура выдатна апісана ў прыкладаемым да windows-кліенту readme, які робіцца ўсё як напісана, усё атрымліваецца. На 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

Ой-ой. Нешта пайшло не так. Выкарыстоўваны навык гугла. Сустракаюцца ўрыўкавыя згадванні, што нешта там не так з канстантамі, у сервернай частцы распрацоўшчыкі пры пераходзе на версію 0.2.0 змянілі версію пратакола, а вось у кліенце пад Win зрабіць гэта забыліся. Прапанаванае рашэнне - памяняйце канстанту ў зыходніку і перазбярыце кліент.

Вось толькі вельмі мне не жадаецца пампаваць Visual Studio дзеля гэтай працэдуры. Затое ў мяне есць стары-добры Hiew. У зыходніку канстанта абвешчана як падвойнае слова. Пашукаем у файле 0х00000106, замяняючы на ​​0х00000111. Не забываем, парадак байт зваротны. Вынік - два супадзенні, патчым:

[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

І ўсё. На гэта мне не змог адказаць нават усёведны гугл. А пры гэтым каманда адлюстраваць даступныя на серверы прылады цалкам карэктна паказвае - вось ён, ключ, можаце мантаваць. Спрабую прымантаваць з-пад Linux - працуе! А калі зараз паспрабаваць з-пад Windows? Аб жах - гэта працуе!

Граблі апошнія: нешта там у кодзе сервера не дапісана. Пры расшаривании прылады ён не счытвае з яго колькасць USB-дэскрыптараў. А пры мантаванні прылады з-пад Linux, гэтае поле запаўняецца. Нажаль, з распрацоўкай пад Linux я знаёмы на ўзроўні "make && make install". Таму праблема вырашана з дапамогай даволі бруднага хаку - даданнем у /etc/rc.local

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

Частка заключная

Пасля некаторых пакут, гэта працуе. Жаданае атрымана, зараз ключ можна прымантаваць да любога ПК (і размантаваць, вядома ж, таксама), у тым ліку – за межамі шырокавяшчальнага сегмента сеткі. Калі жадаецца - можна гэта зрабіць з дапамогай скрыпту каманднай абалонкі. Што прыемна - задавальненне абсалютна бясплатнае.
Спадзяюся, што мой досвед дапаможа хабражыхарам абыйсці тыя граблі, якія аддрукаваліся ў мяне на лбе. Дзякуй за ўвагу!

Крыніца: habr.com

Дадаць каментар