Привет, Хабр! В прошлой статье мы рассмотрели историю и принцип работы технологии USB over IP, узнали, как ее применяют на базе готового аппаратного решения.

Для личного использования, однако, аппаратное решение скорее не подойдет: нужно приобретать дорогостоящее оборудование, что нецелесообразно. Поэтому под катом рассказываю, как организовать клиент-серверный комплекс USB over IP на современных ОС и автоматизировать этот процесс.

Итак, USBIP прекрасно работает не только на специализированном оборудовании, но и на современных операционных системах. Это позволяет недорого или вообще без денежных вложений решать небольшие кейсы.

В данной статье мы рассмотрим организацию клиент-серверного комплекса USB over IP. В качестве клиента выступит облачный сервер Selectel (ОС — Ubuntu 20.04), а сервером будет классический bare metal-сервер, с той же версией Ubuntu. Помимо облачного клиента на Linux, мы выполним проброс устройства на клиент Windows 10.

Настройка сервера


Для начала установим необходимые инструменты и модули для работы. Все необходимые модули входят в состав пакета linux-tools. Выполняем его установку (у меня версия 5.4.0-100-generic):

root@Descartes:~# apt-get install linux-tools-`uname -r`

Далее проверяем доступные для загрузки USBIP модули ядра:

root@Descartes:~# find /lib/modules/$(uname -r) -name '*.ko'| grep usbip

/lib/modules/5.4.0-100-generic/kernel/drivers/usb/usbip/usbip-core.ko
/lib/modules/5.4.0-100-generic/kernel/drivers/usb/usbip/usbip-host.ko
/lib/modules/5.4.0-100-generic/kernel/drivers/usb/usbip/vhci-hcd.ko
/lib/modules/5.4.0-100-generic/kernel/drivers/usb/usbip/usbip-vudc.ko

Для работы сервера нам потребуются:

  • usbip-core — основа USBIP-сервера,
  • usbip-host — управление USB-устройствами,
  • vhci-hcd — модуль экспорта виртуальных USB-устройств.

Выполним запуск необходимых нам модулей:

root@Descartes:~# modprobe usbip-core
root@Descartes:~# modprobe usbip-host
root@Descartes:~# modprobe vhci-hcd

Чтобы не запускать данные модули вручную каждый раз, добавим их в конфигурационный файл modules.conf:

root@Descartes:~# vi /etc/modules-load.d/modules.conf

usbip-core
usbip-host
vhci-hcd

Чтобы USB-сервер работал в фоновом режиме, мы запустим его в качестве демона, а после проверим BusID подключенного накопителя. Этот ID понадобится нам позже для проброса ключей в клиентскую часть. Запускаем USB-сервер в качестве демона:

root@Descartes:~# usbipd -D

Проверяем список подключенных устройств:

root@Descartes:~# usbip list -l

 - busid 1-1 (058f:6387)
   unknown vendor : unknown product (058f:6387)
 - busid 1-13.1 (0557:2419)
   unknown vendor : unknown product (0557:2419)

где BusID 1-1 — это наш USB-накопитель, подключенный в сервер.

Так как теперь нам известен BusID флешки, которой мы хотим поделиться с внешним миром, выполним следующую команду:

root@Descartes:~# usbip bind -b 1-1
usbip: info: bind device on busid 1-1: complete

Теперь устройство готово быть подключенным к удаленным клиентским устройствам. Далее рассмотрим настройку клиентской части.

Настройка клиента на Linux


По аналогии с сервером нам потребуется пакет linux-tools под необходимую версию ядра. Выполняем установку:

root@Racio:~# apt-get install linux-tools-`uname -r`

Подключаем удаленное устройство:

root@Racio:~# usbip attach --remote=188.124.55.21 --busid=1-1

Находим подключенный девайс среди остальных блочных устройств. В клиентской системе девайс определился как sda4-устройство:

root@Racio:~# fdisk -l
Device     Boot Start      End  Sectors  Size Id Type
/dev/sda4  *      256 31129599 31129344 14.9G  c W95 FAT32 (LBA)

Настройка клиента на Windows


Одним из вариантов подключения устройств для Windows является использование отдельного ПО — VirtualHere USB Client. Эта программа практически исключает какую-либо настройку руками.

Но мы пойдем по более интересному пути, где для Windows-клиента проброс будет осуществлен с помощью пакета usbip-client. Этот пакет содержит необходимые конфигурационные файлы для работы, в том числе каталог безопасности. Благодаря нему в будущем у нас не возникнет проблем с сертификатами. Пакет работает с Windows 7 и 10, а также с Windows Server 2008 и 2021.

Распакованный usbip-client необходимо подключить к нашей ОС как виртуальное устройство. Windows не видит старые устройства, у которых нет поддержки технологии Plug-and-Play. Чтобы добавить для них драйверы, нужно использовать утилиту ручной настройки «Мастер установки оборудования».

Для этого необходимо:

  1. Зайти в диспетчер устройств → ДействиеУстановить старое устройство.
  2. Выбрать пункт с ручной установкой оборудования и вместо конкретного типа оборудования выбрать пункт Показать все устройства. Далее выбираем Установить с диска и выбираем USBIPEnum.Inf файл из распакованного архива.
  3. Мастер установки распознает оборудование USB/IP Enumerator, его и устанавливаем.

После этого в диспетчере устройств в системных устройствах мы увидим установленный и подписанный драйвер USB/IP Enumerator.

Проверяем доступные для подключения USB-устройства:

C:\Users\usbip usbip -l 188.124.55.21
1-1: Alcor Micro Corp. : Transcend JetFlash Flash Drive (058f:6387)
        : /sys/devices/pci0000:00/0000:00:14.0/usb1/1-1
        : (Defined at Interface level) (00/00/00)
        :  0 - Mass Storage / SCSI / Bulk (Zip) (08/06/50)

где 1-1 – BusID удаленного девайса.

Подключаем девайс к системе:

C:\Users\usbip usbip -a 188.124.55.21 1-1
new usb device attached to usbvbus port 1


Автоматизация клиента и сервера


Каждый раз прописывать команды и организовывать связность устройств вручную как минимум муторно. Как максимум — невозможно: например, если конечный клиент — простой обыватель, не подозревающий о существовании подобной «магии». Поэтому в дополнение к классическому пробросу USB-ключа нам также стоит автоматизировать этот процесс и на стороне клиента, и на стороне сервера.

Рассмотрим, как реализовать это на практике.

Автоматизация серверной части


Аналогично разделу с базовой настройкой сервера необходимо добавить модули в автозапуск, без этого никуда:

root@Descartes:~# vi /etc/modules
usbip-core
usbip-host
vhci-hcd

Далее создаем юнит в systemd, который будет обращаться к скрипту usbipd и расшаривать наш USB-девайс автоматически после старта сетевых служб ОС:

root@Descartes:~# vi /etc/systemd/system/usbipd.service

[Unit]
Description=USBIPd
After=network.target

[Service]
ExecStart=/bin/sh /root/script/usbipd
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Обновляем конфигурацию systemd и добавляем юнит в автозапуск:

root@Descartes:~#systemctl daemon-reload
root@Descartes:~#systemctl enable usbipd

После чего создаем сам скрипт автообновления инструментов и расшаривания устройства usbipd:

root@Descartes:~# vi /scripts/usbipd

#!/bin/sh
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

bindID='1-1' # BusID нашего USB-устройства на сервере

kernel_version=$(uname -r) - # создание переменной, содержащей текущую версию ядра системы
apt install linux-tools-$kernel_version # установка инструментов проброса для актуальной версии ядра
usbipd -D 
sleep 1
usbip bind -b $bindID # делаем USB-устройство на сервере доступным для проброса

usbip attach --remote=localhost --busid=$bindID
sleep 3

usbip detach --port=00

Выдаем разрешение на запуск скрипта:

root@Descartes:~# chmod ugo+x usbipd

Последние три строки скрипта вынесены отдельно неслучайно. ПО на стороне сервера может работать неидеально. Иногда при попытке подключения устройства к клиенту под управлением ОС Windows может возникнуть проблема, когда клиент попросту не видит на сервере устройства с BusID 1-1:

usbip -a 188.124.55.21 1-1 
usbip err: usbip_windows.c: 829 (attach_device) cannot find device

Проблема решается путем проброса USB-девайса сервера самому себе с его последующим отключением, что и содержится в последних трех строках скрипта.

Как можно было заметить, значения параметров BindID и port в скрипте являются статичными. Это связано с тем, что сервер изначально настраивается на проброс одного единственного USB-устройства, который будет получать одни и те же значения описанных выше параметров.

Автоматизация клиентской части (Windows)


Автоматизацию клиентской машины под управлением Windows мы осуществим за счет создания исполнительного bat-файла и планировщика заданий, который будет этот файл выполнять при запуске системы. В bat-файл добавляем инструкции, необходимые для подключения:

cd C:\Users\Makson\Desktop\usbip
usbip.exe -a 188.124.55.21 1-1

Запускаем планировщик заданий, где указываем следующие параметры:

  • во вкладке Общие ставим галочку Выполнять с наивысшим приоритетом,
  • во вкладке Триггеры указываем При запуске (либо любой другой),
  • во вкладке Действия указываем путь до нашего bat-файла. В моем случае это C:\Users\Makson\Desktop\usbip\script.bat,
  • во вкладке Условия снимаем галочку с пункта Останавливать задачу, выполняемую дольше.

Остальные настройки можно оставить по умолчанию.

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

Автоматизация клиентской части (Linux)


Аналогично серверу создаем новый юнит для запуска автоматического подключения USB-устройства:

root@Descartes:~# vi /etc/systemd/system/usbip_client.service

[Unit]
Description=usbip_client
After=network.target

[Service]
ExecStart=/bin/sh /root/script/usbip_client 
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Создаем скрипт подключения:

root@Descartes:~# vi /root/script/usbip_client

#!/bin/sh
apt-get install linux-tools-`uname -r` -y
sleep 1
usbip attach --remote=188.124.55.21 --busid=1-1
sleep 1
echo "Подключенные устройства:"
usbip port 

Даем разрешение на запуск скрипта:

root@Descartes:~# chmod ugo+x usbip_client

Обновляем конфигурацию systemd и добавляем юнит в автозапуск:

root@Descartes:~#systemctl daemon-reload
root@Descartes:~#systemctl enable usbip_client

Как USBIP в очередной раз «спас мир»


Удаленный доступ к USB-устройствам по сети продолжает решать многие задачи в мире IT. Это может быть организация доступа к камере видеонаблюдения в серверной стойке современного дата-центра, где, как правило, запрещено размещать собственные точки Wi-Fi. Или же настройка удаленного доступа к аппаратным USB-ключам с дорогостоящими лицензиями проприетарного ПО, что защищает их от физического воздействия человека (поломки, утери и т.д.).

Методы, описанные в тексте, позволяют использовать USB-устройства без лишних рисков и затрат на обслуживание, а также выполнять задачи, где нет альтернативных решений.

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


  1. Worky
    31.05.2022 13:34

    Автор! Насколько эта технология устойчива к обрывам связи? нет ли подвисаний клиента в случае обрыва связи к серверу? Опишите такие ситуации. Или вот ситуация, когда связь с потерями.


    1. 13werwolf13
      31.05.2022 14:48
      +5

      отвечу за автора:
      для hasp ключей подходит прекрастно, ибо только чтение и токену плевать на то завершилось оно удачно или нет.
      а вот со флешками, принтерами, etc бывают проблемы, некоторые принтеры HP если в процессе передачи данных мигнула сеть нужно идти и обесточивать на секунд 10 чтобы он забыл о неудаче и начал работать, ну а побить ФС на флешке из-за плохого wi-fi вообще не удивительно.


      1. Kenoby
        01.06.2022 10:01

        Поддерживаю. У меня так USB ключ защиты 1с работает последние 2-3 года. Клиент удаленный виндовый сервер. на котором в шедулере запущен usbip.exe, если связь теряется приложение вылетает и перезапускается по расписанию в течение 10 минут. Этого более чем достаточно для 1с сервера чтобы не потерять лицензию. А вот для клиентских лицензий 1с проще проставить hasp lm server (конечно если есть IP связанность).


    1. Makson_Herson Автор
      31.05.2022 15:45

      На отказоустойчивость тестировать не пробовал. Обычно если что то и может пойти не так. то в момент подключения самого устройства.

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


  1. volkanin
    31.05.2022 14:18
    +3

    А что за пакет usbip-client ? Откуда он взялся и как его можно собрать самому?


    1. Makson_Herson Автор
      31.05.2022 15:36

      Свободно распространяемый пакет от USB/IP Project.

      как его можно собрать самому

      Не задавался таким вопросом. Это скорее тема для отдельной статьи :)


  1. Valser
    31.05.2022 23:44

    А как насчёт yubikey, какие функции и какие версии будут работать с usbip?


    1. 13werwolf13
      01.06.2022 06:12

      любые будут.


  1. alexandersusanin88
    01.06.2022 10:02
    +2

    Полезная штука, на предыдущем месте работы так пробрасывали единственный живой usb ключ от ПО которое уже не поддерживалось вендор-лиз и купить новые ключи было нельзя, а оставшийся перепаивали уже не раз. Правда сервером выступал роутер с openwrt.


  1. enamchuk
    01.06.2022 10:34
    +2

    А как дела с безопасностью, разграничением прав доступа?
    Если дополнительно не настраивать файрволл, кто угодно сможет подключиться к нашему устройству (о чём в статье нет упоминания).
    Есть ли возможность авторизации или управление доступом в самом сервисе?