Accéder à un périphérique USB à l’autre bout du monde…

Accéder à un périphérique USB à l’autre bout du monde…

    Parfois il peut arriver que vous ayez un périphérique USB qui soit connecté sur un ordinateur, mais vous aimeriez bien le partager pour l’exploiter sur un autre ordinateur.

    Et bien, sachez que cela est tout à fait possible !!!
    Il existe plusieurs solutions permettant cela, majoritairement payantes, mais certaines comme le projet « USBip » disponible sous Linux et Windows, permettent ce genre de partage.

    La description suivante est proposée pour partager un périphérique USB Bluetooth entre deux machines Linux; la machine serveur aura le périphérique USB connecté sur son connecteur USB tandis que le client accèdera virtuellement au périphérique au travers le réseau qui les relie.

    Références :

    • https://usbip.sourceforge.net/
    • https://sourceforge.net/p/usbip/git-windows/ci/master/tree/trunk/userspace/README
    • https://bbs.archlinux.org/viewtopic.php?id=233424
    • https://github.com/dorssel/usbipd-win

    La solution USBip est à l’origine le projet d’un japonnais et s’appuie sur l’architecture suivante :

    Installation et configuration coté SERVEUR

    La documentation disponible sur le site du projet n’est pas tout à fait à jour; je reprend le descriptif d’installation tout en commentant la méthode d’installation et son utilisation.

    Commencer par installer le paquet « USB IP » :

    # Sur RedHat, CentOS, RockyLinux, etc...
    sudo yum install usbip
    
    # Sur Debian, Ubuntu, etc...
    sudo apt-get install usbip
    
    Lecture des listes de paquets... Fait
    Construction de l'arbre des dépendances... Fait
    Lecture des informations d'état... Fait
    Les paquets supplémentaires suivants seront installés :
      usb.ids
    Les NOUVEAUX paquets suivants seront installés :
      usb.ids usbip
    0 mis à jour, 2 nouvellement installés, 0 à enlever et 0 non mis à jour.
    Il est nécessaire de prendre 790 ko dans les archives.
    Après cette opération, 1 442 ko d'espace disque supplémentaires seront utilisés.
    Souhaitez-vous continuer ? [O/n]
    Réception de :1 http://deb.debian.org/debian bullseye/main amd64 usb.ids all 2022.05.20-0+deb11u1 [205 kB]
    Réception de :2 http://deb.debian.org/debian-security bullseye-security/main amd64 usbip amd64 2.0+5.10.162-1 [585 kB]
    790 ko réceptionnés en 1s (1 162 ko/s)
    Sélection du paquet usb.ids précédemment désélectionné.
    (Lecture de la base de données... 45887 fichiers et répertoires déjà installés.)
    Préparation du dépaquetage de .../usb.ids_2022.05.20-0+deb11u1_all.deb ...
    Dépaquetage de usb.ids (2022.05.20-0+deb11u1) ...
    Sélection du paquet usbip précédemment désélectionné.
    Préparation du dépaquetage de .../usbip_2.0+5.10.162-1_amd64.deb ...
    Dépaquetage de usbip (2.0+5.10.162-1) ...
    Paramétrage de usb.ids (2022.05.20-0+deb11u1) ...
    Paramétrage de usbip (2.0+5.10.162-1) ...
    Traitement des actions différées (« triggers ») pour man-db (2.9.4-2) ...

    Maintenant que le paquet applicatif est installé, il faut activer le service…. sauf que le paquet n’apporte aucun système de démarrage. Comme nous sommes actuellement en plein « SystemD », je vous propose de démarrer le service en créant le fichier « /etc/systemd/system/usbip.service » avec votre éditeur de texte préféré :

    [Unit]
          Description=Partage de périphérique USB
          After=network.target
    [Service]
          User=root
          Group=root
          ExecStart=/usr/sbin/usbipd -D
          Restart=on-failure
          RestartSec=1m
          #StandardOutput=null
    [Install]
          WantedBy=multi-user.target
    

    Une fois le fichier créé, il est possible de lancer le service sur SERVEUR :

    root@hyperviseur:/etc/systemd/system# systemctl start usbip.service
    root@hyperviseur:/etc/systemd/system#
    root@hyperviseur:/etc/systemd/system# systemctl status usbip.service
    ● usbip.service - Partage de périphérique USB
       Loaded: loaded (/etc/systemd/system/usbip.service; disabled; vendor preset: enabled)
       Active: deactivating (stop-sigterm) since Sat 2023-04-15 16:16:22 CEST; 3s ago
      Process: 646 ExecStart=/usr/sbin/usbipd -D (code=exited, status=0/SUCCESS)
     Main PID: 646 (code=exited, status=0/SUCCESS)
        Tasks: 1 (limit: 4915)
       Memory: 756.0K
       CGroup: /system.slice/usbip.service
               └─647 /usr/sbin/usbipd -D
    
    avril 15 16:16:22 hyperviseur systemd[1]: Started Partage de périphérique USB.
    avril 15 16:16:22 hyperviseur usbipd[647]: usbipd: info: starting usbipd (usbip-utils 2.0)
    avril 15 16:16:22 hyperviseur usbipd[647]: usbipd: info: listening on 0.0.0.0:3240
    avril 15 16:16:22 hyperviseur usbipd[647]: usbipd: info: listening on :::3240
    
    root@hyperviseur:~# systemctl enable usbip.service
    Created symlink /etc/systemd/system/multi-user.target.wants/usbip.service → /etc/systemd/system/usbip.service.
    

    La commande « systemctl status usbip.service » permet de voir ainsi que le binaire est bien lancé, mais qu’en plus, il écoute sur le port 3240. C’est en effet le port TCP quis era utilisé par le service pour faire communiquer les machines et ainsi partager, les périphériques USB.

    Faites donc attention à vos Firewall, ils doivent laisser passer ce port TCP sous peine d’avoir des problèmes de laisons avec le client par la suite…

    Avant d’aller plus loin :

    • Vérifier que vos périphériques USB sont bien connectés sur votre SERVEUR
    • Vérifier que votre machine SERVEUR est sur la même plage d’adresse IP que votre machine CLIENTE (normalement le cas pour une utilisation sur réseau local)
    • Lancer les commandes suivantes pour s’assurer que les modules kernel sont correctement installés et chargés :

    root@hyperviseur:~# modprobe vhci_hcd usbip_host usbip_core
    
    # Vérification que les modules USBip sont bien chargés en mémoire sur Linux
    root@hyperviseur:~# lsmod | grep usbip
    usbip_host             36864  0
    usbip_core             32768  2 usbip_host,vhci_hcd
    usbcore               299008  7 xhci_hcd,ehci_pci,ehci_hcd,btusb,xhci_pci,usbip_host,vhci_hcd
    usb_common             16384  3 usbip_core,usbcore,vhci_hcd
    

    Il ne reste plus qu’à regarder comment son vu les périphérique USB par « USBip » sur le SERVEUR :

    root@hyperviseur:/usr# <strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">usbip version</mark></strong>
    <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-luminous-vivid-orange-color">usbip (usbip-utils 2.0)</mark>
    root@hyperviseur:/usr# <strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">usbip list -l</mark></strong>
    <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-luminous-vivid-orange-color"> - busid <strong>3-1.7</strong> (0a12:0001)
       Cambridge Silicon Radio, Ltd : Bluetooth Dongle (HCI mode) (0a12:0001)</mark>
    
    root@hyperviseur:/usr# <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">lsusb</mark>
    Bus 020 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
    Bus 019 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-green-cyan-color">Bus 003 Device 003: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)</mark>
    Bus 003 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
    Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
    Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    

    En utilisant la commande standard Linux « lsusb« , on trouve ainsi tous les périphériques et Hub USB connectés à la machine : dans mon cas, je n’ai qu’un seul périphérique USB connecté, un dongle USB Bluetooth… Mais on pourrait trouver un clavier, une sourie, un disque dur, un lecteur de carte ou de DVD, etc… Et tout cela aurait pu être « exportable » !!!

    Remarquez bien le résultat de la commande « usbip list -l » : elle renvoie l’ID du bus qui détermine le périphérique USB que nous souhaitons partager; ici, l’ID est : 3-1.7
    Il ne nous reste plus qu’à indiquer que nous partageons ce périphérique sur le réseau :

    root@hyperviseur:~# <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">usbip bind -b 3-1.7</mark>
    usbip: info: bind device on busid 3-1.7: complete

    Si vous rencontrez un message du type « usbip: error: device on busid 3-1.7 is already bound to usbip-host » cela signifie que vous avez déjà partagé le périphérique USB; il faut alors le supprimer de la liste des périphériques partagés :

    root@hyperviseur:~# <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">usbip unbind -b 3-1.7</mark>
    usbip: info: unbind device on busid 3-1.7: complete

    Installation et configuration coté CLIENT

    L’installation du service est presque pareil, mais cette fois, nous ne sommes pas « serveur » et nous n’aurons pas à créer un service SystemD pour lancer un démon « USBip »…

    Installons et recherchons les périphériques partagés :

    # Sur RedHat, CentOS, RockyLinux, etc...
    <strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">sudo yum install usbip</mark></strong>
    
    # Sur Debian, Ubuntu, etc...
    <strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">sudo apt-get install usbip</mark></strong>
    
    Lecture des listes de paquets... Fait
    Construction de l'arbre des dépendances... Fait
    Lecture des informations d'état... Fait
    Les paquets supplémentaires suivants seront installés :
      usb.ids
    Les NOUVEAUX paquets suivants seront installés :
      usb.ids usbip
    0 mis à jour, 2 nouvellement installés, 0 à enlever et 0 non mis à jour.
    Il est nécessaire de prendre 790 ko dans les archives.
    Après cette opération, 1 442 ko d'espace disque supplémentaires seront utilisés.
    Souhaitez-vous continuer ? [O/n]
    Réception de :1 http://deb.debian.org/debian bullseye/main amd64 usb.ids all 2022.05.20-0+deb11u1 [205 kB]
    Réception de :2 http://deb.debian.org/debian-security bullseye-security/main amd64 usbip amd64 2.0+5.10.162-1 [585 kB]
    790 ko réceptionnés en 1s (1 162 ko/s)
    Sélection du paquet usb.ids précédemment désélectionné.
    (Lecture de la base de données... 45887 fichiers et répertoires déjà installés.)
    Préparation du dépaquetage de .../usb.ids_2022.05.20-0+deb11u1_all.deb ...
    Dépaquetage de usb.ids (2022.05.20-0+deb11u1) ...
    Sélection du paquet usbip précédemment désélectionné.
    Préparation du dépaquetage de .../usbip_2.0+5.10.162-1_amd64.deb ...
    Dépaquetage de usbip (2.0+5.10.162-1) ...
    Paramétrage de usb.ids (2022.05.20-0+deb11u1) ...
    Paramétrage de usbip (2.0+5.10.162-1) ...
    Traitement des actions différées (« triggers ») pour man-db (2.9.4-2) ...
    
    # On n'oublie SURTOUT pas le modprobe sur nos 3 modules sous peine que rien ne fonctionne
    root@HomeAssistant:~# <strong><mark style="background-color:#fcb900" class="has-inline-color has-vivid-red-color">modprobe vhci_hcd usbip_host usbip_core</mark></strong>
    
    # Recherche des périphériques partagés sur la machine SERVEUR (192.168.1.190)
    root@HomeAssistant:~# usbip list -r 192.168.1.190
    Exportable USB devices
    ======================
     - 192.168.1.190
          3-1.7: Cambridge Silicon Radio, Ltd : Bluetooth Dongle (HCI mode) (0a12:0001)
               : /sys/devices/pci0000:00/0000:00:1d.0/usb3/3-1/3-1.7
               : Wireless / Radio Frequency / Bluetooth (e0/01/01)
    

    Comme on peut le voir, on retrouve notre ID (3-1.7) du périphérique USB partagé – le dongle Bluetooth.

    Maintenant que l’on sait qu’il est accessible, il ne reste plus qu’à le faire reconnaitre par la machine cliente; pour cela, on va attacher l’ID du périphérique à la machine :

    # Connexion sur la machine CLIENTE "HomeAssistant" (machine virtuelle)
    root@HomeAssistant:~# <strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">usbip attach -r 192.168.1.190 -b 3-1.7</mark></strong>
    
    # Petit coup de "lsusb" pour voir si notre périphérique est bien monté ?
    root@HomeAssistant:~# <strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">lsusb</mark></strong>
    Bus 018 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
    Bus 017 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 016 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
    Bus 015 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    <strong>Bus 003 Device 003: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)</strong>
    

    Parfait !
    Notre périphérique est maintenant monté sur la machine CLIENTE… Vous n’avez plus qu’à l’exploiter 😉

    Vérifications et problèmes / résolutions

    Parmi tous les problèmes que j’ai pu rencontrer dans mon environement (un peu spécial !), on peut compter sur :

    • Sécurité SELinux
    • Firewall
    • Oublie d’import des modules Kernel

    Sur le client, pour valider que le périphérique est bien monté, vous pouvez également lancer la commande qui valide votre configuration :

    root@HomeAssistant:~# <strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">usbip port</mark></strong>
    Imported USB devices
    ====================
    Port 00: <port in="" use=""> at Full Speed(12Mbps)
           Cambridge Silicon Radio, Ltd : Bluetooth Dongle (HCI mode) (0a12:0001)
           3-1 -> usbip://192.168.1.190:3240/3-1.7
               -> remote bus/dev 003/003
    </port>

    Comments

    No comments yet. Why don’t you start the discussion?

    Laisser un commentaire

    Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.