USB-IP exports a USB device from one machine (the server, where the device is physically plugged in) and attaches it on another (the client) over TCP β the client sees it as if it were plugged in locally. Perfect for a lab: a Raspberry Pi by the bench sharing a J-Link, an oscilloscope, or a serial adapter to your workstation across the room.
No authentication, no encryption
USB-IP traffic (TCP port 3240) is plaintext and unauthenticated β anyone who can reach that port can attach your device. Run it only on a trusted LAN or over a VPN/tailnet, and open 3240 to known hosts only. And giving a remote machine a USB device is real access β treat it accordingly.
How it works β transport & integrity
USB-IP runs over TCP (port 3240), not UDP β it tunnels USB request blocks (URBs) across a TCP connection. That shapes what you can trust:
- The bytes are safe. TCP gives ordered, retransmitted, checksummed delivery, and USB adds its own CRCs on top β so data doesnβt silently corrupt, drop, or reorder in transit. This is not a lossy stream.
- The risk is the connection dropping, not corruption. The TCP session is the cable. If the network blips and it dies, the device detaches abruptly β like yanking the plug. Fine for a debugger or serial adapter; dangerous for a mounted USB drive mid-write or a firmware flash.
- Latency is the real limit. TCP guarantees what arrives, not when. Latency-sensitive/isochronous devices (webcams, USB audio) or high-throughput ones can stutter or time out over the network even with perfect data.
In practice: use a stable link (wired LAN or VPN) for write-heavy work, unmount
cleanly before detach, and prefer a physical cable for a critical flash. USB-IP
shines for debuggers, serial, dongles, and read-mostly use.
Server β export a device
# Install the usbip tools (Debian: the `usbip` package; Ubuntu: linux-tools)
sudo apt install usbip hwdata # Debian
# β or, on Ubuntu β
sudo apt install linux-tools-generic linux-tools-$(uname -r) hwdata
sudo modprobe usbip-host # server-side module (a.k.a. usbip_host)
sudo usbipd -D # start the usbip daemon
sudo usbip list -l # list LOCAL devices β note the busidExample output β pick the busid of what you want to share:
pi@server:~ $ sudo usbip list -l
- busid 1-1.2 (1366:0105)
SEGGER : unknown product (1366:0105)
- busid 1-1.3 (1ab1:044d)
Rigol Technologies : unknown product (1ab1:044d)
- busid 1-1.4 (0416:5011)
Winbond Electronics Corp. : Virtual Com Port (0416:5011)sudo usbip bind -b 1-1.4 # export that device (use your busid)The device is now bound and available to clients. Unshare it later with
sudo usbip unbind -b 1-1.4.
Linux client β attach the device
sudo apt install usbip hwdata # (or linux-tools-generic on Ubuntu)
sudo modprobe vhci-hcd # client-side virtual host controller
sudo usbip list -r <server_ip> # see what the server is offering
sudo usbip attach -r <server_ip> -b 1-1.4 # attach it β now appears as local USB
usbip port # show attached remote devices + their port
sudo usbip detach -p 00 # detach when done (port from `usbip port`)Verify with lsusb / dmesg β the device shows up exactly as if plugged in.
Windows
For the Windows side, use usbipd-win
(actively maintained; the older cezanne/usbip-win 0.3.x is largely superseded):
winget install usbipd
usbipd list # find the busid
usbipd bind --busid <busid> # share it (server role)
usbipd attach --remote <server_ip> --busid <busid> # or attach from a remote serverMake it stick + notes
- Load the modules at boot so you donβt
modprobeevery reboot:echo -e "usbip-host\nvhci-hcd" | sudo tee /etc/modules-load.d/usbip.conf - Run
usbipdas a service (a small systemd unit runningusbipd -D) so the server survives reboots; re-bindthe device(s) after start. - Firewall: open TCP 3240 on the server to the client(s) only.
- Itβs the whole device, not a copy β while attached, the client owns it; the server canβt use it at the same time.