usbip-go

module
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 18, 2026 License: Apache-2.0

README

usbip-go

CI CodeQL Trivy OpenSSF Scorecard OpenSSF Best Practices codecov Go Reference

What it is

Pure-Go USB/IP userspace for Linux.

usbip-go gives you a single binary for USB/IP client, exporter, daemon, and operator workflows — plus an embeddable Go library for building USB/IP-aware tools.

  • ✅ Wire-compatible with upstream usbip / usbipd peers.
  • ✅ No cgo and no runtime dependency on usbip-utils.
  • ✅ One flat CLI for importers, exporters, daemon ops, and completions.
  • ✅ Go API under pkg/usbip and domain values under pkg/domain.
  • ✅ Reconnect, graceful drain, status socket, health checks, and WAN TCP tuning.

[!WARNING] USB/IP is plaintext and unauthenticated. Use usbip-go only on trusted networks or inside WireGuard, Tailscale, SSH, or equivalent tunnels. Do not expose TCP/3240 to the public internet.

Comparison

Legend: ✅ built in · ⚠️ varies by distro/package · ❌ not provided

Capability usbip-utils usbip-go
USB/IP wire compatibility
Linux kernel USB/IP modules
Single client/exporter/daemon binary
Flat command set
Embeddable Go library
Typed Go domain model
Pure Go, no cgo
Non-Linux build stubs
JSON output with versioned schema
Shell completion installer ⚠️
Active port inspection
Auto-reconnect
Event stream
Bind safety guardrails ⚠️
Graceful drain + status UDS
Health/readiness endpoints
systemd socket activation ⚠️
CIDR/rate/session limits
WAN TCP tuning
Release SBOM + cosign + SLSA provenance ⚠️
OpenSpec behavior specs
TLS/auth on the USB/IP wire

Installation

Release archive

Choose the latest non-retracted stable tag listed in SECURITY.md and on the GitHub Releases page. If no such tag is present, there is no supported archive to install.

VERSION=X.Y.Z # replace with a supported release version
curl -LO "https://github.com/abilisoft/usbip-go/releases/download/v${VERSION}/usbip-go_${VERSION}_linux_amd64.tar.gz"
tar xzf "usbip-go_${VERSION}_linux_amd64.tar.gz"
sudo install -m 0755 usbip-go /usr/local/bin/usbip-go

Archives are published for Linux amd64, arm64, and armv7. Releases also include .deb and .rpm packages, checksums, SBOMs, Sigstore bundles, and SLSA provenance. See docs/security-posture.md for release integrity details.

Go install
VERSION=vX.Y.Z # replace with a supported release tag
go install "github.com/abilisoft/usbip-go/cmd/usbip-go@${VERSION}"

Use an explicit supported tag rather than @latest so installation follows the support policy. Building the current development branch requires Go 1.26.5 or newer.

Kernel modules

Load modules for the role each machine plays:

Machine Needs Why
exporter/server usbip_core, usbip_host shares physical USB devices
importer/client usbip_core, vhci_hcd attaches remote devices locally

The .deb and .rpm packages install persistent module-loading configuration. For archive or go install setups, load modules before running commands:

Copy/paste for an exporter/server:

sudo modprobe usbip_core usbip_host

Copy/paste for an importer/client:

sudo modprobe usbip_core vhci_hcd

If a host does both:

sudo modprobe usbip_core vhci_hcd usbip_host

The systemd service also runs modprobe usbip_core usbip_host before starting the exporter daemon.

Usage

USB/IP has two sides:

  • exporter/server — owns the physical USB device and runs the daemon.
  • importer/client — attaches that remote device to a local VHCI port.
Export a local USB device

Manual foreground flow on the machine with the physical USB device:

sudo modprobe usbip_core usbip_host
usbip-go list
sudo usbip-go bind 1-1.2
sudo usbip-go serve --status-socket=

By default, serve listens on 0.0.0.0:3240; use --listen HOST:PORT to override it. The manual foreground example disables the status socket because packaged/systemd installs create /run/usbip-go for that socket. Keep usbip-go serve running while clients are attached. When you are done:

sudo usbip-go unbind 1-1.2
Import that device from another machine
sudo modprobe usbip_core vhci_hcd
usbip-go list 10.0.0.5
sudo usbip-go attach 10.0.0.5 1-1.2
usbip-go port
sudo usbip-go detach 0

The kernel retains the numeric port and importer-local busid after the one-shot attach process exits, so a later port/detach invocation still works. VHCI does not retain the exporter endpoint or remote busid; those fields are empty when port runs in a fresh process.

Run as a daemon with systemd

Use the .deb or .rpm package when you want systemd. Packages install the binary, socket/service units, module-loading config, and runtime-directory wiring.

sudo systemctl daemon-reload
sudo systemctl enable --now usbip-go.socket

Socket activation starts usbip-go serve on the first inbound connection. See docs/ops.md for package install commands, status, readiness, health checks, logs, and graceful usbip-go drain rollouts.

After enabling the socket, bind the devices you want to export:

sudo modprobe usbip_core usbip_host
sudo usbip-go bind 1-1.2
JSON for scripts
usbip-go list 10.0.0.5 --output json
usbip-go port --output json
usbip-go watch --output json

The JSON contract is documented in docs/json-schema.md. watch exits non-zero if it cannot establish the kernel-event subscription or if that source closes unexpectedly. Embedders that need the same monitoring assurance should use Importer.WatchWithErrors; the original Watch method remains available as an event-only compatibility iterator.

Go example

package main

import (
    "context"
    "log/slog"

    "github.com/abilisoft/usbip-go/pkg/domain"
    "github.com/abilisoft/usbip-go/pkg/usbip"
)

func main() {
    imp, err := usbip.NewImporter(usbip.WithImporterLogger(slog.Default()))
    if err != nil {
        panic(err)
    }
    defer imp.Close()

    remote, err := domain.ParseRemote("10.0.0.5:3240")
    if err != nil {
        panic(err)
    }

    busid, err := domain.ParseBusID("1-1.2")
    if err != nil {
        panic(err)
    }

    port, err := imp.Attach(context.Background(), remote, busid, usbip.AttachOptions{
        AutoReconnect: true,
    })
    if err != nil {
        panic(err)
    }

    _ = port // later: imp.Detach(ctx, port.ID)
}

More examples:

Public API lifecycle details
  • Use WithImporterBackoffFactory for a stateful custom reconnect strategy. The factory creates one strategy per logical attachment and that strategy remains with the attachment across reconnect generations. The legacy WithImporterBackoff option remains supported and serializes calls to a shared custom strategy.
  • WithExporterAcceptRateLimit(0) explicitly disables accept-rate limiting; omitting the option selects the library default. NaN and infinity are rejected with ErrAcceptRateLimitInvalid.
  • ProbeKernelModules always returns usbip_core, vhci_hcd, and usbip_host. If cancellation prevents an observation, that entry is ModuleStateUnknown and the returned error preserves the context cause.
  • ListenAndServe reserves the Exporter lifecycle before binding. Calls after Shutdown or during another Serve return the lifecycle sentinel without opening a listener.

Documentation

License

Apache-2.0. See LICENSE.

Directories

Path Synopsis
cmd
usbip-go command
Package main is the usbip-go client CLI entrypoint (cli-interface OpenSpec).
Package main is the usbip-go client CLI entrypoint (cli-interface OpenSpec).
examples
client command
Example client demonstrates attaching a remote USB/IP device via pkg/usbip.Importer and detaching it cleanly after a brief hold.
Example client demonstrates attaching a remote USB/IP device via pkg/usbip.Importer and detaching it cleanly after a brief hold.
events command
Example events demonstrates iterating over the v1-compatible Importer.Watch and Exporter.WatchSessions event-only sequences.
Example events demonstrates iterating over the v1-compatible Importer.Watch and Exporter.WatchSessions event-only sequences.
reconnect command
Example reconnect demonstrates AttachOptions.AutoReconnect with a custom backoff and an OnReconnect callback.
Example reconnect demonstrates AttachOptions.AutoReconnect with a custom backoff and an OnReconnect callback.
server command
Example server demonstrates embedding pkg/usbip.Exporter in a custom process: listen on TCP, bind a local device for export, then serve the USB/IP accept loop until SIGINT/SIGTERM.
Example server demonstrates embedding pkg/usbip.Exporter in a custom process: listen on TCP, bind a local device for export, then serve the USB/IP accept loop until SIGINT/SIGTERM.
internal
adapter/kernel
Package kernel implements the Linux kernel adapter: sysfs reads/writes, netlink uevent listener, and the fd-passing handshake for usbip-host and vhci_hcd.
Package kernel implements the Linux kernel adapter: sysfs reads/writes, netlink uevent listener, and the fd-passing handshake for usbip-host and vhci_hcd.
adapter/transport
Package transport provides context-aware TCP dial and listen primitives for USB/IP sessions.
Package transport provides context-aware TCP dial and listen primitives for USB/IP sessions.
adapter/wire
Package wire implements the USB/IP OP-level protocol codec: opcodes, header layout, device descriptor (312 bytes), OP_REQ_DEVLIST / OP_REP_DEVLIST, and OP_REQ_IMPORT / OP_REP_IMPORT.
Package wire implements the USB/IP OP-level protocol codec: opcodes, header layout, device descriptor (312 bytes), OP_REQ_DEVLIST / OP_REP_DEVLIST, and OP_REQ_IMPORT / OP_REP_IMPORT.
app
Package app holds the USB/IP use-case services (importer, exporter, session lifecycle, reconnect loop) and the adapter interfaces they depend on.
Package app holds the USB/IP use-case services (importer, exporter, session lifecycle, reconnect loop) and the adapter interfaces they depend on.
netopts
Package netopts holds the TransportOptions value type and its validation.
Package netopts holds the TransportOptions value type and its validation.
protocol
Package protocol defines USB/IP protocol values shared by the application ports and wire adapter without making the application depend on an adapter.
Package protocol defines USB/IP protocol values shared by the application ports and wire adapter without making the application depend on an adapter.
testutil
Package testutil centralises deterministic test helpers used across the repository: fake clock, fake random source, goleak integration, and shared fixture loaders.
Package testutil centralises deterministic test helpers used across the repository: fake clock, fake random source, goleak integration, and shared fixture loaders.
pkg
domain
Package domain defines the pure value objects, entities, events, and sentinel errors shared by the usbip-go library.
Package domain defines the pure value objects, entities, events, and sentinel errors shared by the usbip-go library.
usbip
Package usbip is the public facade for the usbip-go library.
Package usbip is the public facade for the usbip-go library.
test
integration/killable command
Package main is the test-only subprocess that exercises Importer.Attach against a fake server and pauses at controllable checkpoints so the parent test can SIGKILL it at an exact instant.
Package main is the test-only subprocess that exercises Importer.Attach against a fake server and pauses at controllable checkpoints so the parent test can SIGKILL it at an exact instant.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL