Утилита USBIP.

 

   В какой-то момент количество ЭЦП пользователей достигло критической массы. Для наведения порядка было принято решение организовать сервер ключей и раздавать их пользователям по сети с одного устройства. Все это должно было работать на OpenSUSE.
   Выбор пал на утилиту USBIP. И для сервера, и для клиента требуется один и тот же rpm пакет usbip, скачать можно
здесь: https://software.opensuse.org/package/usbip.

Сервер.
   После установки usbip нам потребуется включить необходимые модули ядра:

usbip-core - основной компонент USBIP, предназначенный для реализации технологии проброса USB-устройств через сеть;
usbip-host - управление и экспорт устройств;
vhci-hcd - виртуальный хост-контроллер к которому подключаются клиенты.

Можно их включать при каждой загрузке:

# modprobe usbip-core # modprobe usbip-host # modprobe vhci-hcd

Если хотим автоматическое подключение модулей ядра при старте системы - необходимо в конфигурационный файл

/etc/modules-load.d/usbip.conf (файл создаем руками) добавить строки:

usbip-core usbip-host vhci-hcd

Запускаем наш сервер:

# systemctl start usbipd.service

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

# systemctl enable usbipd.service

Проверить состояние можно командой:

# systemctl status usbipd.service

Готово, наш сервер работает. Теперь необходимо опубликовать наше usb-устройство. Смотрим доступные устройства:

# usbip list -l  - busid 1-1.3 (0a89:0025)    Aktiv : Rutoken lite (0a89:0025)

Мы видим наш ЭЦП busid 1-1.3, его мы и будем публиковать. Чтобы опубликовать необходимо выполнить команду:

# usbip bind -b 1-1.3

В выводе появится сообщение об успешном выполнении.
Usbip: info: bind device on busid 1-1.3: complete

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

# usbip unbind -b 1-1.3

Клиент.
   Сначала делаем все то же самое, что и на сервере. Ставим usbip и включаем модули ядра (usbip-core, usbip-host, vhci-hcd).
Смотрим расшаренные на хосте USB устройства, допустим наш сервер имеет ip 192.168.0.1:

# usbip list -r 192.168.0.1

Получаем:

Exportable USB devices ======================  - 192.168.0.1         1-1.3: ktiv : Rutoken lite (0a89:0025) 
: /sys/devices/pci0000:00/0000:00:14.0/usb1/1-1.3
: (Defined at Interface level) (00/00/00)

Видим, что на сервере есть доступное для подключения устройство 1-1.3. Подключаем его:

# usbip attach --remote=192.168.0.1 --busid=1-1.3

Проверяем:

# lsusb Bus 006 Device 002: ID 0a89:0025 Aktiv Rutoken lite

или

# usbip port  Imported USB devices  ====================  Port 00: <Port in Use> at Full Speed(12Mbps)        Aktiv : Rutoken lite (0a89:0025) 
6-1 -> usbip://192.168.0.1:3240/1-1.3 -> remote bus/dev 001/003

Готово, устройство доступно на клиенте.
Для того чтобы отключить устройство на клиенте, смотрим порт из вывода команды
usbip port, в моем примере это 00. Отключаем:

# usbip detach --port=00

Подводные камни.
   Если ключ был выдернут и вставлен снова, он не появится на клиенте автоматически. Чтобы восстановить работу, нужно отключить устройство на клиенте и подключить его снова. Это связано с тем, что при физическом переподключении меняется номер устройства на порту: busid 1-1.3 сохраняется, а вот параметры remote bus/dev будут уже другими, поэтому старое подключение перестает работать.

Кроме того, важно учитывать, что USBIP не шифрует трафик. Если сервер и клиент находятся в разных сетях, рекомендуется использовать VPN или SSH-туннель для безопасного доступа к устройствам.

Итог.
   Использование USBIP в нашей организации позволило навести порядок в работе с ЭЦП: все ключи теперь централизованы и доступны пользователям по сети. Это решение не требует дорогого оборудования или сложного ПО, а базируется на стандартных возможностях Linux.

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