Регулярно возникает задача подключения USB-устройства к удаленному ПК через локальную сеть.
Ниже под катом история моих поисков в этом направлении, и путь к готовому решению на базе open-source проекта.
USB/IP с описанием препятствий, заботливо установленных различными людьми на этом пути, а также способов их обхода.
Часть первая, историческая.
Если машина виртуальная, все это легко.
Функционал проброса USB с хоста на виртуальную машину появился в VMWare 4.1. Но в моем случае ключ безопасности, идентифицированный как WIBU-KEY, нужно было в разное время подключать к разным машинам, причем не только виртуальным.
Первый раунд поиска еще в 2009 году привел меня к аппаратному обеспечению под названием ТрендНет ТУ2-НУ4 Плюсы:
- иногда это даже работает
- не всегда работает. Допустим, ключ защиты Guardant Stealth II через него не запускается, ругается с ошибкой «невозможно запустить устройство».
- Программное обеспечение для управления (читай: монтирования и размонтирования USB-устройств) крайне плохое.
Переключатели командной строки, автоматизация - нет, не услышали.
Все сделано своими руками.
Кошмар.
- Управляющее программное обеспечение ищет само оборудование в сети посредством широковещательной рассылки, поэтому оно работает только в пределах одного широковещательного сегмента сети.
Вы не можете указать IP-адрес железки вручную.
Аппаратное обеспечение находится в другой подсети? Тогда у вас есть проблема.
- Разработчики отказались от устройства, отправлять отчеты об ошибках бесполезно.
Привлекает своей открытостью, тем более что ребята из РеактОС Подписали драйвера для винды, так что теперь даже на х64 все работает без всяких костылей типа тестового режима.
За что огромное спасибо команде ReactOS! Все звучит красиво, попробуем почувствовать, так ли это на самом деле? К сожалению, сам проект тоже заброшен, и на поддержку рассчитывать не приходится - а где наша не пропала, там исходники, разберемся!
Часть вторая, сервер-Linux
Сервер USB/IP, который совместно использует USB-устройства по сети, можно установить только в ОС на базе Linux. Что ж, Linux есть Linux, устанавливаем Debian 8 на виртуальную машину в минимальной конфигурации, стандартное движение руки:Учредил.sudo apt-get update sudo apt-get upgrade sudo apt-get install usbip
Потом интернет подсказывает, что нужно скачать модуль usbip, но - здравствуйте, первые грабли.
Нет такого модуля.
Это связано с тем, что большинство мануалов в сети относятся к более старой ветке 0.1.х, а в последней 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. Дорогие зрители, грабли номер три на арене: ID автобуса, который нам даст lsusb (казалось бы, самый очевидный способ) - ей не подходит! Дело в том, что usbip игнорирует такое оборудование, как USB-концентраторы.
Поэтому воспользуемся встроенной командой: 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. Официальное руководство просит сначала установить драйвер.
Процедура прекрасно описана в readme, прилагаемом к Windows-клиенту, делаем все как написано, все получается.
На 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
Ой ой.
Что-то пошло не так.
Давайте воспользуемся навыками Google. Встречаются отрывочные упоминания о том, что с константами что-то не так; в серверной части разработчики изменили версию протокола при переходе на версию 0.2.0, а вот в Win клиенте это сделать забыли.
Предлагаемое решение — изменить константу в исходном коде и пересобрать клиент. Но мне очень не хочется скачивать Visual Studio для этой процедуры.
Но у меня есть старый добрый Hiew. В исходном коде константа объявлена как двойное слово.
Поищем в файле 0x00000106, заменив его на 0x00000111. Не забывайте, порядок байтов обратный.
Результат — два совпадения, патчим: [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
Вот и все.
Даже всезнающий Google не смог мне ответить на этот вопрос.
И при этом команда отображения доступных на сервере устройств совершенно корректно показывает — вот он, ключ, можно его монтировать.
Пробую монтировать из Linux - работает! Что, если мы попробуем сейчас из Windows? О ужас - работает! Последние грабли: что-то не было написано в коде сервера.
При совместном использовании устройства оно не считывает с него количество USB-дескрипторов.
А при монтировании устройства из Linux это поле заполняется.
К сожалению, я знаком с разработкой Linux на уровне «make&& make install».
Поэтому проблема решилась довольно грязным хаком — добавлением в /etc/rc.local usbip attach --remote=localhost --busid=1-1
usbip port
usbip detach --port=00
Заключительная часть
После некоторых испытаний это работает. Желаемое достигнуто, теперь ключ можно смонтировать на любой ПК (и размонтировать, конечно, тоже), в том числе и за пределами широковещательного сегмента сети.Если хотите, вы можете сделать это с помощью сценария командной оболочки.
Что приятно, удовольствие абсолютно бесплатное.
Надеюсь, что мой опыт поможет хакерам обойти грабли, которые отпечатались у меня на лбу.
Спасибо за внимание! Теги: #*nix #Системное администрирование #usbip #usb over ip
-
Три Бабочки
19 Oct, 24 -
Хм-Хм
19 Oct, 24 -
Список Интернет-Сайтов
19 Oct, 24 -
Amd Brook+: Сразу С Места В Карьер
19 Oct, 24 -
Как Вам Креативность Сайта Visual Studio?
19 Oct, 24 -
За Кулисами Cybersoft
19 Oct, 24 -
Почему Я Ненавижу Eloquent Orm
19 Oct, 24