Регулярно возникает задача подключения 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 Files\USB-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 Files\USB-IP>usbip -a %server-ip% 1-1
new usb device attached to usbvbus port 1

На этом можно было бы закончить изложение, но музыка играла недолго. Перезагрузив сервер, я обнаружил, что устройство на клиенте не монтируется!

C:\Program Files\USB-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

Часть заключительная


После некоторых мытарств, это работает. Желаемое получено, теперь ключ можно примонтировать к любому ПК (и размонтировать, конечно же, тоже), в том числе — за пределами широковещательного сегмента сети. Если хочется — можно это сделать с помощью скрипта командной оболочки. Что приятно — удовольствие абсолютно бесплатное.
Надеюсь, что мой опыт поможет хабражителям обойти те грабли, которые отпечатались у меня на лбу. Спасибо за внимание!
Поделиться с друзьями
-->

Комментарии (37)


  1. 0x3f00
    31.08.2016 04:21
    +2

    Весьма своевременная статья — я решил последний день лета посвятить реализации мультирума в квартире. Думаю пробросить USB-DAC по локальной сети от OPi+ и, если получится, от старого роутера с OpenWrt и доработки его паяльником.
    Сейчас компилирую модули ядра 3.4 для OPi+. Если все получится, поделюсь итогом.


    1. Potok
      31.08.2016 07:51

      На OpenWRT есть удачные примеры установки USB/IP. Именно на их форуме я нашел совет про версию протокола. Думаю, всё получится.


      1. 0x3f00
        31.08.2016 08:32

        Пробросить USB-DAC не получилось. В менеджере устройств USB Audio появился, но с кодом ошибки 10.
        Как-нибудь потом попробую с гигабитным хабом или патч-кордом.


      1. ufm
        31.08.2016 21:10

        Есть. У меня с OpenWRT отдаются 8 модемов в сторону виртуалки с астериском.
        Единственное но. Версия OpenWRT должна быть 12.09, в боле поздних нехватает нужных ipk


        1. Wedmer
          05.09.2016 02:36

          Каких конкретно не хватает? Могу их в mainline прокинуть и поддерживать.


          1. ufm
            07.09.2016 00:24

            Все usbip-*.ipk
            Причем kmod-usbip — присутствуют.


            1. Wedmer
              07.09.2016 01:26

              На текущий момент все в наличии.


              1. ufm
                07.09.2016 01:34

                Тут — https://downloads.openwrt.org/chaos_calmer/15.05.1/x86/generic/packages/ — нет. плохо искал?


                1. Wedmer
                  07.09.2016 03:16

                  https://downloads.openwrt.org/snapshots/trunk/x86/generic/packages/ — здесь уже есть. К моменту релиза CC (май 2015) эти пакеты еще не были перенесены из oldpackages


                  1. ufm
                    07.09.2016 11:21

                    10.05.1 — Released: Mon, 16 Mar 2016
                    Но если я Вас правильно понял — в более мажорной версии можно ждать.
                    Спасибо за информацию!


                    1. Wedmer
                      07.09.2016 19:20

                      Это не тот релиз) Это фиксы для существующих в релизе пакетов.


  1. eugene_brad
    31.08.2016 07:48

    Спасибо, интересный опыт. Как-то не приходила такая мысль со своим девайсом — время от времени носим от машине к машине (с виндой). Попробую у себя на Gentoo


  1. dtkbrbq
    31.08.2016 07:49

    Использую вариант проще и без танцев с бубном — usb over network. Виндовый сервер и клиент. Единственное что огорчает — ibank 2 ключи пробрасываются, но не работают (может потому что используют старую версию софтины).


    1. Daar
      31.08.2016 08:09

      Странно как раз через эту софтину пробрасываем банки, у нас ibank2, Сбер и пара других etoken работают без проблем. Причем серверная часть стоит на Hyper-V Server, от чего и покупали эту софтину, что у неё серверной части есть cli.


  1. ShadowAlexey
    31.08.2016 07:49

    Где то год назад, для дома, использовал для этого софт USB Redirector.
    Серверная часть под линукс OpenSource, но вот клиент, увы, проприетарный.
    Но работает как часы до сих пор.
    Хардварный же ЮСБ редиректор радовал не долго, то БП умрет, то сама железка, да и в работе периодические зависания с отваливанием.


  1. Openmsk
    31.08.2016 07:49
    +1

    usb redirector от некой компании incentives у меня трудится довольно давно, при этом все ключи воткнуты в один сервер (через несколько usb хабов) на клиента можно прокинуть любой «не занятый» ключ. При этом не важно ни тип машины, ни вендор виртуализации.
    Спасибо


    1. Potok
      31.08.2016 07:54
      +1

      Такое решение есть, я пробовал триал — да, работает, но они денег хотят. Поэтому и родился этот вариант.


  1. Daar
    31.08.2016 08:01
    +1

    Дааа… были времена, помню месяц тоже танцевал с бубном вокруг этой софтины, нужно было пробросить в виртуалки etoken'ы иии… модемы. Но помню что не было стабильности, ключи периодично отваливались и лечилось тупо перезагрузкой. Мы потом купили софтинку USBoverEthernet, на ней долго работали, проблем в общем не было. А потом купили железку Digi AnywhereUSB, не дешево, но зато вообще забыли о проблемах.

    Но последнее время, часто обращаются небольшие фирмы для проброски usb в облака, и многим такие железки не сильно по карману, надо достать бубен и попробовать ваш вариант. На Windows Server 2012R2 не пробовали?


    1. Potok
      31.08.2016 08:03

      Лично не пробовал, но положительный опыт на 2012R2 в сети встречал.


    1. gotch
      31.08.2016 08:59

      Digi AnywhereUSB — работает без проблем. От Windows Server 2003 до 2012 R2. Ключей — несколько десятков самых разных типов.


    1. Verdel
      31.08.2016 10:58

      Единственная проблема с Digi AnywhereUSB это отсутствие клиента для Linux.


  1. Potok
    31.08.2016 08:02

    del, ошибся веткой


  1. Inlore
    31.08.2016 09:32

    А как со стабильностью? Оно долго уже у вас работает без проблем?


    1. Potok
      31.08.2016 10:52

      Месяц трудится уже примерно.


  1. kay
    31.08.2016 10:22
    +1

    К сожалению, с разработкой под Linux я знаком на уровне «make && make install».

    Не бойтесь экспериментировать. Разработка не сильно уж и отличается от таковой под Win. Я со своими начальными знаниями программирования и то иногда умудряюсь написать правильный патч, который принимают в upstream. Так что, дерзайте.


  1. Taragolis
    31.08.2016 10:53
    +3

    В свое время намучавшись с usbip, попробовал VirtualHere.
    Плюсы:
    Минимум настроек и возни


    Минусы:
    Проприетарный софт (но было доступно без ограничений проброс двух USB девайсов)


    1. Daar
      31.08.2016 12:35

      Большое человеческое спасибо за эту софтину, скока гуглил не разу не натыкался на неё. Да она досих пор бесплатна для 2 устройств, потому что лицензирование начинается с 3 шт. И смотрю ставить можно хоть на что, даже на QNAP, как раз такой зверь стоит без дела :)


    1. savostin
      01.09.2016 14:57

      Так это оболочка над usbip


  1. zxsavage
    31.08.2016 10:53

    Пытался год назад завести USB/IP, но надежности так и не добился.
    После непродолжительных поисков выбор пал на Virtualhere как самый демократичный по цене. Стоит $49 за сервер с неограниченным количеством подключений, клиенты бесплатные. Сервер работает и не чихает уже год на OpenWRT, клиенты и виндовые и nix. По стабильности нареканий никаких.


  1. Mistique666
    31.08.2016 10:53

    + много за DIGI.
    работает в одном филиале 5to1 варинат уже 2 года стабильно.
    В головном Many2Any редакция — тоже стабильно и уже больше 5 лет. тьфу тьфу тьфу


  1. arctic-fox
    31.08.2016 12:02
    +1

    Спасибо за описание

    Желаемое получено, теперь ключ можно примонтировать к любому ПК (и размонтировать, конечно же, тоже), в том числе — за пределами широковещательного сегмента сети

    А эксперимент с задержками сигнала не проводили? До скольки миллисекунд проброс эффективен?
    Т.е. будет ли иметь смысл проброса «через океан».


    1. Potok
      31.08.2016 12:04

      А как можно задерживать пакеты на определенное, регулируемое время? Просто у меня и дом, и работа на одном провайдере, задержка минимальная.


      1. arctic-fox
        01.09.2016 15:15

        наBSD конструкция будет такого типа:
        $ sudo ipfw pipe 1 config delay 100ms
        $ sudo ipfw add 100 pipe 1 ip from $src to $dst
        как-то так…


  1. kalobyte
    31.08.2016 16:27

    есть такая штука FRITZ!Box USB-Fernanschluss
    нужен только роутер этой конторы, надо сказать — это топовый топ на рынке всех домашних роутеров
    никто больше не делает такого годного железа и софта с плюшками, но простой настройкой

    https://www.youtube.com/watch?v=BsYgqBa8zL0

    смысл в том, что на компутерах стоит софт и усб устройство подключено к одному компутеру, а не роутеру,
    но каждый клиент может перехватить устройство и подключить к себе
    для принтера это выглядит тупо, но вот с ключами вполне себе должно работать, хотя я только на принтере пробовал давно, с тех пор принтеры стали идти даже с влан за копейки, а вот расшаривать усб мне больше не требовалось

    фрицбокс можно купить за копейки в германии на ебее или https://www.ebay-kleinanzeigen.de/s-pc-zubehoer-software/fritzbox/k0c225


  1. bb80
    31.08.2016 21:08

    Я тоже исследовал эту тему. USB/IP уже давно как прекратил свое активное развитие. Если Linux версия еще как-то поддерживается Linux kernel сообществом, то Windows версия не обновлялась с 2011 года. Да и существующий функционал здесь только базовый: расшарить — подключить и больше ничего. Если цель сэкономить и функционал устраивает, то можно пробовать, но только в том случае, если вы разбираетесь хоть немного в програмировании и готовы потратить n-ное кол-во часов на настройку и поиски решения проблем в Гугле.


    Если нужно более профессиональное решение с поддержкой напр. шифрования, RDP, Citrix поротоколов и чтобы "искаропки", то здесь только за деньги. На этом рынке есть несколько ключевых игроков:


    • VirtualHere (https://www.virtualhere.com/home) — самый дешевый вариант. Там заявлена поддержка многих платформ, но вроде как разрабатывается это все одним разработчиком по имени Michael и внимания к деталям на каждую платформу по видимому не хватает. Предоставляет только базовый функционал как и USB/IP но в более удобной форме. Работает все не всегда стабильно, а так же можно наткнутся на проблемы с установкой.


    • Далее по цене идет USB Redirector (http://www.incentivespro.com/products.html) — поддерживает Windows и Linux, RDP, шифрование, аутентификация по паролю.


    • Так же есть еще USB Network Gate (http://www.eltima.com/products/usb-over-ethernet/) — здесь есть поддежка Windows, Linux, Mac, протоколов RDP и ICA (Citrix) + шифрование, аутентификация по паролю… У этой компании так же есть смежное решение распространяемое по подписке Flexihub (http://www.flexihub.com/)


    • Ну и еще один активный игрок на этом рынке — это USB over Network (http://www.fabulatech.com/usb-over-network.html) — самые дорогие лицензии. Поддерживает Windows и Linux, RDP и ICA + все прочие "плюшки" что и предыдущие решения.

    Так что выбирать есть из чего :)


  1. tell3
    31.08.2016 21:09

    на debian сервер поднимается 0.2-й версии, в ubuntu 0.1.7. Кто-нибуть на убунте запускал сервер версии 2?


  1. tell3
    01.09.2016 00:50

    Спасибо за статью, связка debian — debian и debian — ubuntu получилась и работает. Но вот связка debian — windows7 выдает следующее:

    c:\Program Files\usbip>usbip -D -a 192.168.3.22 2-2.1
    usbip dbg: usbip_network.c: 223 (tcp_connect ) trying 192.168.3.22 port 3240

    usbip dbg: usbip_network.c: 243 (tcp_connect ) connected to 192.168.3.22:3240
    usbip dbg: usbip_windows.c: 767 (query_interface0) exportable 1 devices
    usbip dbg: usbip_windows.c: 784 (query_interface0) 2-2.1: Feitian Technologie
    s, Inc.: unknown product (096e:0001)
    usbip dbg: usbip_windows.c: 785 (query_interface0): /sys/devices/pci000
    0:00/0000:00:11.0/0000:02:04.0/usb2/2-2/2-2.1
    usbip dbg: usbip_windows.c: 786 (query_interface0): Vendor Specific Cla
    ss / unknown subclass / unknown protocol (ff/00/00)
    usbip dbg: usbip_windows.c: 806 (query_interface0): 0 — Vendor Specifi
    c Class / unknown subclass / unknown protocol (ff/00/00)
    usbip dbg: usbip_windows.c: 809 (query_interface0)
    usbip dbg: usbip_network.c: 223 (tcp_connect ) trying 192.168.3.22 port 3240

    usbip dbg: usbip_network.c: 243 (tcp_connect ) connected to 192.168.3.22:3240
    usbip err: usbip_windows.c: 660 (import_device) no free port
    usbip err: usbip_windows.c: 840 (attach_device) query

    кто вкурсе как это победить?