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 busid

Example 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 server

Make it stick + notes

  • Load the modules at boot so you don’t modprobe every reboot:
    echo -e "usbip-host\nvhci-hcd" | sudo tee /etc/modules-load.d/usbip.conf
  • Run usbipd as a service (a small systemd unit running usbipd -D) so the server survives reboots; re-bind the 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.