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. 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
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 — . Atrae por su apertura, sobre todo porque los chicos de 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 usbipSe 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 usbipY añadiremos las siguientes líneas en /etc/modules para que se carguen automáticamente al iniciar el sistema:
usbip-core
usbip-host
vhci-hcdIniciaremos el servidor usbip:
sudo usbipd -DA 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 usbipAl 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 -DParte 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-1Pasamos 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 dispositivoUy. 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 11Y… ¡sí!
C:Program FilesUSB-IP>usbip -a %server-ip% 1-1
nuevo dispositivo usb conectado al puerto usbvbus 1En 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 dispositivoY 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=00Parte 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
