Рэгулярна ўзнікае задача падлучэння USB-прылады да выдаленага ПК праз лакальную сетку. Пад катам выкладзена гісторыя маіх пошукаў у гэтым кірунку, і шлях да гатовага рашэння на базе open-source праекту
Частка першая, гістарычная
Калі машына віртуальная усё гэта нескладана. Функцыянал пракіду USB ад хаста ў віртуалку з'явіўся яшчэ ў VMWare 4.1. Але ў маім выпадку ключык абароны, які апазнаецца як WIBU-KEY, трэба было ў розны час падлучаць да розных машын, і не толькі віртуальным.
Першы віток пошуку ў далёкім 2009-м годзе прывёў мяне да жалязякі пад назвай
Плюсы:
- часам нават працуе
Мінусы:
- працуе не заўсёды. Дапушчальны, ключ абароны Guardant Stealth II праз яе не заводзіцца, лаючыся памылкай "прылада не можа быць запушчана".
- ПА для кіравання (чытай - мантавання і размантавання USB-прылад) убога да крайнасці. Ключы каманднага радка, аўтаматызацыя - не, не чулі. Усё толькі рукамі. Кашмар.
- кіравальнае ПА шукае саму жалязяку ў сетцы шырокавяшчаннем, таму працуе гэта толькі ў межах аднаго broadcast-сегмента сеткі. Указаць IP-адрас жалязякі рукамі нельга. Жалезка ў іншай падсетцы? Тады ў вас праблема.
- распрацоўшчыкі забілі на прыладу, слаць баг-рэпарты бескарысна.
Другі віток здарыўся ў часы ўжо не гэтак падаленыя, і прывёў мяне да тэмы артыкула.
Частка другая, серверна-лінуксавая
Сервер 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