Утилита 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.
Несмотря на некоторые нюансы в эксплуатации, технология показала себя надежной и полностью закрыла наши потребности.