Domando USB/IP

Con frecuencia surge la necesidad de conectar un dispositivo USB a una PC remota a través de la red local. A continuación, relato mi búsqueda en esta dirección y el camino hacia una solución lista basada en un proyecto de código abierto. USB/IP con la descripción de los obstáculos impuestos por diversas personas en este camino, así como de las maneras de evitarlos.

Parte uno, histórica

Si la máquina es virtual, no es complicado. La funcionalidad de redirección de USB desde el host a la máquina virtual apareció ya en VMWare 4.1. Pero en mi caso, la llave de protección, identificada como WIBU-KEY, debía ser conectada en diferentes momentos a distintas máquinas, y no solo virtuales.
La primera vuelta de búsqueda en el lejano 2009 me llevó a un dispositivo llamado TrendNet TU2-NU4
Pros:

  • a veces incluso funciona

Desventajas:

  • no siempre funciona. Supongamos que la llave de protección Guardant Stealth II no se activa a través de ella, mostrando el error "el dispositivo no puede ser iniciado".
  • El software para gestionarlo (es decir, montar y desmontar dispositivos USB) es increíblemente rudimentario. Los comandos de línea, la automatización — no, nunca lo oímos. Todo se debe hacer manualmente. Un caos.
  • El software de gestión busca el hardware en la red mediante broadcasting, por lo que solo funciona dentro de un mismo segmento de red. No se puede especificar la dirección IP del hardware manualmente. ¿El hardware está en otra subred? Entonces, tiene un problema.
  • Los desarrolladores se olvidaron del dispositivo, enviar informes de errores es inútil.

La segunda vuelta ocurrió en tiempos no tan lejanos y me llevó al tema del artículo — proyecto USB/IP. Atrae por su apertura, sobre todo porque los chicos de ReactOS firmaron su controlador para Windows, así que ahora incluso en x64 todo funciona sin ningún tipo de parches como el modo de prueba. ¡Gracias al equipo de ReactOS! Suena genial, ¿intentaremos comprobar si es así en realidad? Desafortunadamente, el proyecto también ha sido descuidado, y no hay que esperar soporte — pero ¿dónde nos quedaríamos sin ello? ¡Tenemos el código fuente, resolveremos!

Parte dos, servidor y Linux

El servidor USB/IP que comparte dispositivos USB a través de la red solo puede ser levantado en un sistema operativo basado en Linux. Bueno, si es Linux, entonces Linux, instalamos en una máquina virtual Debian 8 en configuración mínima, lo habitual:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install usbip

Se ha instalado. A continuación, Internet nos indica que deberíamos cargar el módulo usbip, pero — hola, el primer tropiezo. No hay tal módulo. Y todo esto se debe a que la mayoría de las guías en la red se refieren a una rama más antigua, 0.1.x, mientras que en la última 0.2.0 los módulos usbip tienen otros nombres.

Por lo tanto:

sudo modprobe usbip-core
sudo modprobe usbip-host
sudo lsmod | grep usbip

Y añadiremos las siguientes líneas en /etc/modules para que se carguen automáticamente al iniciar el sistema:

usbip-core
usbip-host
vhci-hcd

Iniciaremos el servidor usbip:

sudo usbipd -D

A continuación, la sabiduría colectiva nos indica que junto con usbip vienen scripts que nos permiten gestionar el servidor — mostrar qué dispositivo compartirá por la red, ver el estado, y así sucesivamente. Aquí nos espera otra trampa — estos scripts en la rama 0.2.x, de nuevo, han sido renombrados. Podemos obtener una lista de comandos con:

sudo usbip

Al leer la descripción de los comandos, se entiende que para poder compartir el dispositivo USB requerido, usbip quiere conocer su Bus ID. Distinguidos espectadores, en el escenario aparece el tropiezo número tres: ¡el Bus ID que nos proporcionará lsusb (que, aparentemente, es el camino más obvio) — ¡no le sirve! El hecho es que hardware como los concentradores USB son ignorados por usbip. Por lo tanto, utilizaremos el comando incorporado:

user@usb-server:~$ sudo usbip list -l
 - busid 1-1 (064f:0bd7)
   WIBU-Systems AG : BOX/U (064f:0bd7)

Nota: de aquí en adelante, en los listados, describiré todo con el ejemplo de mi específico pen drive USB. Los nombres de tu hardware y los pares VID:PID pueden diferir. El mío se llama Wibu-Systems AG: BOX/U, VID 064F, PID 0BD7.

Ahora podemos compartir nuestro dispositivo:

user@usb-server:~$ sudo usbip bind --busid=1-1
usbip: info: bind device on busid 1-1: complete

¡Hurra, camaradas!

user@usb-server:~$ sudo usbip list -r localhost
Dispositivos USB exportables
======================
 - 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
           : Clase específica del vendedor / subclase desconocida / protocolo desconocido (ff/00/ff)

¡Triple hurra, camaradas! ¡El servidor ha compartido el hardware por la red, y podemos conectarlo! Solo queda añadir el inicio automático del demonio usbip en /etc/rc.local

usbipd -D

Parte tres, el cliente, y confusa

Intenté conectar el dispositivo compartido por la red a una máquina con Debian de inmediato en el mismo servidor, y todo se conectó a la perfección:

sudo usbip attach --remote=localhost --busid=1-1

Pasamos a Windows. En mi caso, se trataba de Windows Server 2008R2 Standard Edition. El manual oficial solicita primero instalar el controlador. El procedimiento está bien descrito en el archivo readme adjunto al cliente de Windows, lo hacemos tal como está escrito y todo funciona. También funciona en XP sin ninguna dificultad.

Descomponiendo el cliente, intentamos montar nuestra llave:

C:Program FilesUSB-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) no se puede encontrar el dispositivo

Uy. Algo salió mal. Usamos nuestras habilidades de búsqueda en Google. Encontramos menciones esporádicas de que algo no está bien con las constantes, en el servidor los desarrolladores cambiaron la versión del protocolo en la versión 0.2.0, pero en el cliente para Win se olvidaron de hacerlo. La solución propuesta es cambiar la constante en el código fuente y recompilar el cliente.

Pues no quiero descargar Visual Studio solo para esto. Pero tengo el viejo y querido Hiew. En el código fuente, la constante se declara como una palabra doble. Buscaremos en el archivo 0х00000106, reemplazando por 0х00000111. No olvidemos que el orden de los bytes es inverso. Resulta que hay dos coincidencias, parcheamos:

[usbip.exe]
00000CBC: 06 11
00000E0A: 06 11

Y… ¡sí!

C:Program FilesUSB-IP>usbip -a %server-ip% 1-1
nuevo dispositivo usb conectado al puerto usbvbus 1

En este punto, podría haber terminado la exposición, pero la música no duró mucho. Al reiniciar el servidor, descubrí que el dispositivo no se monta en el cliente.

C:Program FilesUSB-IP>usbip -a %server-ip% 1-1
usbip err: usbip_windows.c: 829 (attach_device) no se puede encontrar el dispositivo

Y eso es todo. Ni siquiera Google, que todo lo sabe, pudo responderme. Mientras tanto, el comando para mostrar los dispositivos disponibles en el servidor se muestra correctamente: ahí está, la llave, puedes montarla. Intento montarla desde Linux — ¡funciona! ¿Y si ahora intento desde Windows? Oh, horror — ¡eso funciona!

Últimos tropiezos: algo en el código del servidor no está escrito. Al compartir el dispositivo, no se lee la cantidad de descriptores USB. Pero al montar el dispositivo desde Linux, este campo se llena. Desafortunadamente, estoy familiarizado con el desarrollo en Linux sólo a nivel de "make && make install". Así que el problema se resolvió con un hack bastante sucio — añadiendo en /etc/rc.local

usbip attach --remote=localhost --busid=1-1
usbip port
usbip detach --port=00

Parte final

Después de algunas tribulaciones, esto funciona. Se ha obtenido lo deseado, ahora la clave se puede montar en cualquier PC (y desmontar, por supuesto, también), incluso fuera del segmento de difusión de la red. Si se desea, se puede hacer mediante un script de línea de comandos. Lo mejor de todo es que la experiencia es completamente gratuita.
Espero que mi experiencia ayude a los usuarios de Habr a evitar los tropiezos que yo mismo he enfrentado. ¡Gracias por su atención!

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster