USB/IP: различия между версиями

Материал из support.qbpro.ru
imported>Vix
imported>Vix
Нет описания правки
 
(не показаны 2 промежуточные версии этого же участника)
Строка 191: Строка 191:
ИСТОЧНИК:'''
ИСТОЧНИК:'''
<hr>
<hr>
* [https://xakep.ru/2017/12/29/remote-devices/]
* [https://xakep.ru/2017/12/29/remote-devices/ тут]
 
== remserial - проброс RS232 ==
RS232
 
Самым лаконичным решением взаимного расшаривания в Линуксе могут похвастаться COM-порты. Никакие дополнительные драйверы для этого не нужны. За все отвечает одна маленькая утилита remserial, доступная в исходниках. Подходит как для доступа из Линукса к оборудованию, подключенному через RS232 на удаленном компьютере, так и для связки двух девайсов с COM-портами, подключенных к разным машинам, связанным по сети.<br>
Расшарить RS232, указав сетевой порт (-p), скорость, режим stty (-s) и имя порта (здесь /dev/ttyS0), можно так:
$ remserial -d -p 23000 -s "9600 raw" /dev/ttyS0 &
 
Подключиться к COM-девайсу, расположенному на удаленной машине (сервере), — так:
$ remserial -d -r адрес_сервера -p 23000 -s "9600 raw" /dev/ttyS0 &
Допустимо запускать несколько экземпляров программы с разными портами и адресами подключенных девайсов.
 
* [https://xakep.ru/2017/12/29/remote-devices/ взято тут]
* [http://gaydov.blogspot.com/2013/06/linux-serial-over-ip.html Проброс последовательного порта по сети в Linux (serial over ip) ]
* [http://renat-zaripov.blogspot.com/2010/12/remserial.html remserial - работа с последовательным портом через сеть. ]


'''ПОЛЕЗНОЕ:'''
'''ПОЛЕЗНОЕ:'''
Строка 200: Строка 215:
* [https://habr.com/ru/post/177647/ Установка usbip на ubuntu 12.04 server]
* [https://habr.com/ru/post/177647/ Установка usbip на ubuntu 12.04 server]
* [https://www.dmosk.ru/miniinstruktions.php?mini=ubuntu-usbip#autostart Настройка USB-сервера Ubuntu на базе usbip]
* [https://www.dmosk.ru/miniinstruktions.php?mini=ubuntu-usbip#autostart Настройка USB-сервера Ubuntu на базе usbip]
* [https://www.virtualhere.com/home VirtualHere - Бесплатно проброс 2usb]

Текущая версия от 00:48, 12 июля 2020

источник

Регулярно возникает задача подключения 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

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

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

Альтернативная статья - Железкой по сети. Пробрасываем USB - устройства на удаленную машину

В одной из прошлых статей мы обсуждали способы подключения самых разных сущностей как файлов и каталогов: WebDAV, BitTorrent, SSH и даже память видеоадаптера. Но что, если мы хотим получить доступ не к удаленному или локальному сервису, а к устройствам удаленной машины? Скажем, пробросить на локальную машину USB-порт и использовать подключенные к нему устройства как локальные.

Особенность Unix-подобной системы — относиться к любому из своих компонентов как к файлу — давно уже стала общим местом в разговорах о ее внутреннем устройстве. И бесчисленное количество статей о том же Linux тому свидетельство. Оборудование — не исключение. Видеокарта, аудиокарта, внешний девайс, подключенный через USB, в понимании Linux не что иное, как файл.

Оттого удивительно, что из всех операционных систем только Plan 9 (если не считать пары отпочковавшихся проектов со схожей судьбой), в котором подобный подход доведен до логического конца, способен без лишних телодвижений распознавать оборудование удаленного компьютера и управлять им, как своим собственным.

В Plan 9 за проброс оборудования отвечает RPC-протокол 9P. Он обеспечивает доступ вообще к любым файлам и устройствам, как локальным, так и сетевым. К сожалению, Linux похвастать таким универсальным инструментом не может. Зато здесь есть несколько инструментов (если не сказать — костылей), обеспечивающих доступ к оборудованию удаленной машины.

USB

Когда речь заходит о пробросе оборудования на другой компьютер, возможно, первое, что приходит на ум, — это веб-камера на домашнем ноутбуке или подключенный к нему смартфон, доступ к которым нужно обеспечить с удаленного десктопа. Например, из офиса на другом конце города (в другом городе, в другой стране).

В подобном случае выручить может утилита USB/IP. Развитием утилиты уже давненько никто не занимался, но на ее работоспособности это пока не сказалось — в репозиториях большинства популярных дистрибутивов такой пакет присутствует.

Первым делом пакет USB/IP следует установить на ту машину, доступ к устройствам которой необходимо получить извне. Далее загружаем необходимые модули:

$ sudo modprobe usbip-core
$ sudo modprobe usbip-host

Проверяем, все ли корректно загрузилось:

$ sudo lsmod | grep usbip

И запускаем сервер:

$ sudo usbipd -D

Поскольку USB/IP имеет собственную, независимую от встроенной систему адресации, поиск устройств выполняется командой

$ sudo usbip list -l

Она покажет список всех устройств, подключенных в данный момент в USB-шине. Настройка утилиты USB/IP Настройка утилиты USB/IP

Теперь можно приступить непосредственно к расшариванию девайса (допустим, это будет веб-камера с индексом 2-3 из полученного списка):

$ sudo usbip bind --busid=2-3

Очередная проверка правильности выполненных действий:

$ sudo usbip list -r localhost

С исходным компьютером покончено. Далее следует настроить тот, на котором будет использоваться периферия первого.

Итак, перейдя на клиентскую машину, устанавливаем на нее USB/IP и запускаем:

$ sudo modprobe usbip-core
$ sudo modprobe vhci-hcd

Проверяем доступность расшаренного оборудования на сервере по списку:

$ sudo usbip --list АДРЕС_СЕРВЕРА

И присоединяем нашу камеру:

$ sudo usbip --attach АДРЕС_СЕРВЕРА 2-3

Проверяем результат:

$ sudo usbip --port

Теперь удаленное USB-устройство должно появиться в списке локальных, и с ним можно будет работать, как с любым другим. Для проверки корректности подключения выполняем команду lsusb:

$ lsusb ИСТОЧНИК:


remserial - проброс RS232

RS232

Самым лаконичным решением взаимного расшаривания в Линуксе могут похвастаться COM-порты. Никакие дополнительные драйверы для этого не нужны. За все отвечает одна маленькая утилита remserial, доступная в исходниках. Подходит как для доступа из Линукса к оборудованию, подключенному через RS232 на удаленном компьютере, так и для связки двух девайсов с COM-портами, подключенных к разным машинам, связанным по сети.
Расшарить RS232, указав сетевой порт (-p), скорость, режим stty (-s) и имя порта (здесь /dev/ttyS0), можно так:

$ remserial -d -p 23000 -s "9600 raw" /dev/ttyS0 &

Подключиться к COM-девайсу, расположенному на удаленной машине (сервере), — так:

$ remserial -d -r адрес_сервера -p 23000 -s "9600 raw" /dev/ttyS0 &

Допустимо запускать несколько экземпляров программы с разными портами и адресами подключенных девайсов.

ПОЛЕЗНОЕ: