Укрощаем 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 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

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


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

    Комментарии 45

      +2
      Весьма своевременная статья — я решил последний день лета посвятить реализации мультирума в квартире. Думаю пробросить USB-DAC по локальной сети от OPi+ и, если получится, от старого роутера с OpenWrt и доработки его паяльником.
      Сейчас компилирую модули ядра 3.4 для OPi+. Если все получится, поделюсь итогом.
        0
        На OpenWRT есть удачные примеры установки USB/IP. Именно на их форуме я нашел совет про версию протокола. Думаю, всё получится.
          0
          Пробросить USB-DAC не получилось. В менеджере устройств USB Audio появился, но с кодом ошибки 10.
          Как-нибудь потом попробую с гигабитным хабом или патч-кордом.
            0
            Есть. У меня с OpenWRT отдаются 8 модемов в сторону виртуалки с астериском.
            Единственное но. Версия OpenWRT должна быть 12.09, в боле поздних нехватает нужных ipk
              0
              Каких конкретно не хватает? Могу их в mainline прокинуть и поддерживать.
                0
                Все usbip-*.ipk
                Причем kmod-usbip — присутствуют.
                  0
                  На текущий момент все в наличии.
                    0
                    Тут — https://downloads.openwrt.org/chaos_calmer/15.05.1/x86/generic/packages/ — нет. плохо искал?
                      0
                      https://downloads.openwrt.org/snapshots/trunk/x86/generic/packages/ — здесь уже есть. К моменту релиза CC (май 2015) эти пакеты еще не были перенесены из oldpackages
                        0
                        10.05.1 — Released: Mon, 16 Mar 2016
                        Но если я Вас правильно понял — в более мажорной версии можно ждать.
                        Спасибо за информацию!
                          0
                          Это не тот релиз) Это фиксы для существующих в релизе пакетов.
          0
          Спасибо, интересный опыт. Как-то не приходила такая мысль со своим девайсом — время от времени носим от машине к машине (с виндой). Попробую у себя на Gentoo
            0
            Использую вариант проще и без танцев с бубном — usb over network. Виндовый сервер и клиент. Единственное что огорчает — ibank 2 ключи пробрасываются, но не работают (может потому что используют старую версию софтины).
              0
              Странно как раз через эту софтину пробрасываем банки, у нас ibank2, Сбер и пара других etoken работают без проблем. Причем серверная часть стоит на Hyper-V Server, от чего и покупали эту софтину, что у неё серверной части есть cli.
              0
              Где то год назад, для дома, использовал для этого софт USB Redirector.
              Серверная часть под линукс OpenSource, но вот клиент, увы, проприетарный.
              Но работает как часы до сих пор.
              Хардварный же ЮСБ редиректор радовал не долго, то БП умрет, то сама железка, да и в работе периодические зависания с отваливанием.
                +1
                usb redirector от некой компании incentives у меня трудится довольно давно, при этом все ключи воткнуты в один сервер (через несколько usb хабов) на клиента можно прокинуть любой «не занятый» ключ. При этом не важно ни тип машины, ни вендор виртуализации.
                Спасибо
                  +1
                  Такое решение есть, я пробовал триал — да, работает, но они денег хотят. Поэтому и родился этот вариант.
                  +1
                  Дааа… были времена, помню месяц тоже танцевал с бубном вокруг этой софтины, нужно было пробросить в виртуалки etoken'ы иии… модемы. Но помню что не было стабильности, ключи периодично отваливались и лечилось тупо перезагрузкой. Мы потом купили софтинку USBoverEthernet, на ней долго работали, проблем в общем не было. А потом купили железку Digi AnywhereUSB, не дешево, но зато вообще забыли о проблемах.

                  Но последнее время, часто обращаются небольшие фирмы для проброски usb в облака, и многим такие железки не сильно по карману, надо достать бубен и попробовать ваш вариант. На Windows Server 2012R2 не пробовали?
                    0
                    Лично не пробовал, но положительный опыт на 2012R2 в сети встречал.
                      0
                      Digi AnywhereUSB — работает без проблем. От Windows Server 2003 до 2012 R2. Ключей — несколько десятков самых разных типов.
                        0
                        Единственная проблема с Digi AnywhereUSB это отсутствие клиента для Linux.
                        0
                        del, ошибся веткой
                          0
                          А как со стабильностью? Оно долго уже у вас работает без проблем?
                            0
                            Месяц трудится уже примерно.
                            +1
                            К сожалению, с разработкой под Linux я знаком на уровне «make && make install».

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

                              +3

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


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

                                0
                                Большое человеческое спасибо за эту софтину, скока гуглил не разу не натыкался на неё. Да она досих пор бесплатна для 2 устройств, потому что лицензирование начинается с 3 шт. И смотрю ставить можно хоть на что, даже на QNAP, как раз такой зверь стоит без дела :)
                                  0
                                  Так это оболочка над usbip
                                  0
                                  Пытался год назад завести USB/IP, но надежности так и не добился.
                                  После непродолжительных поисков выбор пал на Virtualhere как самый демократичный по цене. Стоит $49 за сервер с неограниченным количеством подключений, клиенты бесплатные. Сервер работает и не чихает уже год на OpenWRT, клиенты и виндовые и nix. По стабильности нареканий никаких.
                                    0
                                    + много за DIGI.
                                    работает в одном филиале 5to1 варинат уже 2 года стабильно.
                                    В головном Many2Any редакция — тоже стабильно и уже больше 5 лет. тьфу тьфу тьфу
                                      +1
                                      Спасибо за описание
                                      Желаемое получено, теперь ключ можно примонтировать к любому ПК (и размонтировать, конечно же, тоже), в том числе — за пределами широковещательного сегмента сети

                                      А эксперимент с задержками сигнала не проводили? До скольки миллисекунд проброс эффективен?
                                      Т.е. будет ли иметь смысл проброса «через океан».
                                        0
                                        А как можно задерживать пакеты на определенное, регулируемое время? Просто у меня и дом, и работа на одном провайдере, задержка минимальная.
                                          0
                                          наBSD конструкция будет такого типа:
                                          $ sudo ipfw pipe 1 config delay 100ms
                                          $ sudo ipfw add 100 pipe 1 ip from $src to $dst
                                          как-то так…
                                        0
                                        есть такая штука FRITZ!Box USB-Fernanschluss
                                        нужен только роутер этой конторы, надо сказать — это топовый топ на рынке всех домашних роутеров
                                        никто больше не делает такого годного железа и софта с плюшками, но простой настройкой

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

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

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

                                          Я тоже исследовал эту тему. 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 + все прочие "плюшки" что и предыдущие решения.

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

                                            0
                                            А подскажите, пожалуйста, по своему богатому опыту можно ли вообще пробросить так по сети на несколько машин HID UPS Battery? Или это гиблая затея. Мне просто нужно чтобы несколько машин знали что они от бесперебойника работают, он умеет в HID, но вот как это расшарить на несколько машин не понятно. Спрашиваю ибо в другом месте виртуалка видит такой же UPS подцепленный к хосту, а тут жопа какая то нескончаемая.
                                              0
                                              Полагаю, что так не получится. В один момент времени устройство может быть подключено только к одному хосту. В вашем случае я бы посмотрел в сторону больших и красивых ИБП, которые можно оснастить платой расширения SNMP.
                                            0
                                            на debian сервер поднимается 0.2-й версии, в ubuntu 0.1.7. Кто-нибуть на убунте запускал сервер версии 2?
                                              0
                                              Спасибо за статью, связка 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

                                              кто вкурсе как это победить?
                                                0
                                                Тоже пришлось прикрутить к Thinstation, вот и статейку обновил заодно.
                                                  0
                                                  Доброго времени суток!

                                                  Подскажите как с помощью USB/IP с Windows машины расшарить USB устройство, а то в этом месте дно какое то, ни утилит, ничего и не понятно.
                                                    0
                                                    Хотя, вопрос снят ибо под Windows это просто не живое глючное поделие.
                                                      0
                                                      С хоста под управлением Windows расшарить USB-устройство с помочью USB/IP нельзя. Сервер должен быть Linux-based.
                                                      0
                                                      Как вариант VirtualHere.
                                                        0

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

                                                        Самое читаемое