OpenWRTをUSB/IPのサーバとして使う

投稿者: | 10月 30, 2026

きっかけ

Proxmoxを使い始めて物理PCとしていたサブのUbuntu機をVMとすることにしました。これに伴ってマイコンの開発等に必須なUSBがなくなってしまいました。そこでUSB/IPを使ってみることにしました。

OpenWRT(サーバ)側の準備

機材は
WZR-1750DHP2としました。USB2.0が1ポート、USB3.0(3.2 Gen1)が1ポートの計2ポートがついています。残念ながらUSB3.0のポートは正常に認識されず、2.0しか使用できません。OpenWRTは25.12.5を入れました。

直接接続ではなく、Softetherを使ったVPN経由でVMとローカルネットワークでつながっています。

USB/IP関係でLuciのSoftwareから
usbip-client
usbip-server
usbutils
をインストールしました。usbip-clientをインストールしないとusbipのコマンドが使用できないらしいです。

Ubuntu(クライアント)側の準備

linux-tools-common
をインストールします。自分の環境では既にインストール済みでした。

sudo modprobe vhci_hcd
で仮想USBコントローラのモジュールをロードします。
lsmod | grep vhci
でロード済みか確認できます。
echo vhci_hcd | sudo tee /etc/modules-load.d/usbip.conf
で起動時に自動でモジュールが読み込まれるように設定されます。

試しの接続

試しに接続できるかどうか確認します。

サーバ側で
usbip list -l
でbusidを把握します。1-1や2-2などの形式です。
usbip bind -b さっき確認したbusid
でUSB/IPへバインドします。

クライアント側で
usbip list -r サーバのIPアドレス
でサーバ側でbindしたデバイスが確認できます。
sudo usbip attach -r サーバのIPアドレス -b 確認したbusid
これでアタッチ完了です。
lsusb -tvとかで確認するとちゃんと認識されているはずです。

自動接続

サーバ側ではUSB/IPへ自動でバインド
クライアント側ではバインドされたデバイスを自動でアタッチ
を行う必要があります。

サーバ側
OpenWRT「USB over IP tunnel」を参考にするといい感じです。しかし、そちらのスクリプトはリストに書いてある機器だけをバインドするものです。今回はすべてをバインドしたいので、スクリプトの内容を変えています。
mkdir /etc/hotplug.d/usb
USBのホットプラグ時に自動実行されるディレクトリの作成
touch /etc/hotplug.d/usb/90-usbip
90-usbipファイルを作成
tee /etc/hotplug.d/usbb/90-usbip
文字の書き込み開始(ctrl+cで終了) 以下をコピペ

#!/bin/sh

bind_usb() {
    BUSID="$1"
    DEV="/sys/bus/usb/devices/$BUSID"

    [ -f "$DEV/bDeviceClass" ] || return 0

    # USBハブを除外
    [ "$(cat "$DEV/bDeviceClass")" = "09" ] && return 0

    # すでにUSB/IPにbindされている場合はスキップ
    if [ -L "$DEV/driver" ]; then
        DRIVER="$(readlink "$DEV/driver")"
        case "$DRIVER" in
            */usbip-host) return 0 ;;
        esac
    fi

    if usbip bind -b "$BUSID"; then
        logger -t usbip "Bound USB device: $BUSID"
    else
        logger -t usbip "Failed to bind USB device: $BUSID"
    fi
}

# 起動時の全デバイス走査
if [ "$1" = "scan" ]; then
    for DEV in /sys/bus/usb/devices/*; do
        [ -f "$DEV/bDeviceClass" ] || continue
        bind_usb "${DEV##*/}"
    done
    exit 0
fi

# Hotplug処理
[ "$ACTION" = "add" ] || exit 0
[ "$DEVTYPE" = "usb_device" ] || exit 0

BUSID="${DEVPATH##*/}"
[ -n "$BUSID" ] || exit 0

bind_usb "$BUSID"

chmod +x /etc/hotplug.d/usb/90-usbip
実行権限の追加
vim /etc/rc.local
起動時に実行されるスクリプトファイルを開く
exit 0よりも上に/etc/hotplug.d/usb/90-usbip scan &を追加

クライアント側
サーバを確認して新しいデバイスがあったら接続するという物が必要です。
andrewleech/usbip-auto-attachはbusidかデバイスIDで自動的に接続するツールです。
vk6flab/usbip.hotplug.serviceは10秒ごとに確認して接続をするツールです。
今回自分は、busidの一番上の数字(2-1なら2)のみを指定してアタッチするツールが欲しいです。そのため、andrewleech/usbip-auto-attachをベースにbusidにワイルドカードを追加した物を(AIが)作成しました。
UnagiDojyou/usbip-auto-attachにあります。実行している間は、自動でattachを行ってくれます。

問題点

ネットワークが切断されて、再度接続されたときの動作が不安定な感じがします。追々修正が必要かもしれません。

おわりに

SilexのUSBデバイスサーバなどを使用していましたが、イマイチの動作(自動接続が遅かったり変な挙動をしたり)でしたが、USB/IPはかなり良さそうな感じです。これでVM上でもコーティングエージェントでバリバリ開発ができます。

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)