Raspberry Pi USB Gadget Mode

USB gadget mode turns a Raspberry Pi’s OTG-capable USB port into a device rather than a host: plugged into a laptop or tablet, the Pi enumerates as one or more USB peripherals — an Ethernet adapter (RNDIS / CDC-ECM / NCM), a serial console, a mass storage device, or a HID keyboard/mouse. The Ethernet-gadget variant gives you a point-to-point network link over a single cable: power in, SSH out, no Wi-Fi, no IP scanning, no captive portals. This is the foundation of the “Pi as a portable pentest accessory” pattern, and pairs naturally with a raspberry-pi-network-tap for field intercept work.

Fast-moving field warning. This area churns with every Raspberry Pi OS release (the dhcpcd → NetworkManager switch in Bookworm broke most pre-2023 guides; Trixie changed things again). This page reflects known-good methods as of mid-2026 — verify against current docs before following any older tutorial, including the broken 2021 Kali-based spell this page was mined from.

Hardware prerequisites

  • The port must support OTG device mode. On Pi 4B / 5 that is the USB-C power port; on Zero models, the micro-USB port labeled USB (not PWR IN). Once gadget mode is on, that port can no longer act as a USB host — no keyboard or storage on it while active.
  • Power is the classic failure on Pi 4B: a host’s USB-A port may only supply 900 mA, far under the 4B’s demands, causing brownouts and USB link drops. Prefer a host USB-C port, a powered hub, or external power (with data still routed via the host). 1

Current method 1: rpi-usb-gadget (Raspberry Pi OS Trixie, easiest)

Since Raspberry Pi OS Trixie images dated 2025-10-20, the official `rpi-usb-gadget` package ships by default and makes the old hand-rolled setup obsolete for the Ethernet use case:

  • Enable via Raspberry Pi Imager 2.0 (“Interfaces & Features” → “USB Gadget mode”), via rpi-imager-cli --usb-gadget, or via cloud-init on fresh images by appending rpi:\n enable_usb_gadget: true to user-data on the boot partition.
  • On an existing Trixie install: sudo apt install rpi-usb-gadget && sudo rpi-usb-gadget on && sudo reboot.
  • It uses the kernel g_ether driver and negotiates RNDIS for Windows hosts and CDC-ECM for macOS/Linux automatically from USB descriptors. Windows needs the project’s signed driver installer (rpi-usb-gadget-driver-setup.exe from the GitHub releases) for full speed.
  • A watcher service toggles between CLIENT mode (host ICS gateway detected — Pi gets DHCP from the host’s shared connection) and SHARED mode (Pi serves DHCP/NAT at 10.12.194.1/28, leasing 10.12.194.2–14 to the host). SSH target is the Imager-set hostname or 10.12.194.1. 2

Current method 2: manual g_ether + NetworkManager (Bookworm)

On Bookworm the kernel side is unchanged (dtoverlay=dwc2 in /boot/firmware/config.txt, modules-load=dwc2,g_ether in /boot/firmware/cmdline.txt), but the switch from dhcpcd to NetworkManager is what broke most 2019–2022 tutorials: NM marks gadget interfaces unmanaged and never brings usb0 up. The working fix, done entirely from the boot partition before first boot:

  1. Edit firstrun.sh to copy /usr/lib/udev/rules.d/85-nm-unmanaged.rules into /etc/udev/rules.d/ and comment out the gadget rule, so NM manages usb0.
  2. Create two NM connection profiles in /etc/NetworkManager/system-connections/ (mode 600): one ipv4.method=auto (DHCP, high priority) and one ipv4.method=link-local fallback so the link still comes up when the host runs no DHCP server.
  3. Boot; mDNS (hostname.local) plus the link-local address give you SSH even with zero host-side configuration. 3

Current method 3: libcomposite / configfs (full control, multi-function)

For anything beyond a plain Ethernet gadget — combined RNDIS+ECM for cross-platform hosts, HID, mass storage, serial — use the kernel’s libcomposite configfs interface (/sys/kernel/config/usb_gadget/). The durable workflow (stable since 2013, documented at kernel.org):

  1. modprobe libcomposite, mkdir /sys/kernel/config/usb_gadget/<name>.
  2. Set idVendor/idProduct, device class fields, and strings/0x409/* (serialnumber, manufacturer, product).
  3. mkdir configs/c.1/strings/0x409 and set configuration string + MaxPower.
  4. Create functions: functions/ecm.usb0, functions/rndis.usb0, functions/hid.usb0, functions/mass_storage.usb0, etc.; set per-function attributes (e.g. host_addr/dev_addr MACs; for RNDIS set the Microsoft OS descriptors os_desc + compatible_id "RNDIS" so Windows binds driverless).
  5. Symlink functions into configs/c.1/, then ls /sys/class/udc > UDC to bind.
  6. Tear down by writing "" to UDC, removing symlinks, and removing directories in reverse order — teardown is the part most tutorials omit, and a half-down gadget confuses hosts (notably iPadOS) across reboots. 4

Ben Hardill’s Pi5/Bookworm recipe is the current reference for a dual ECM+RNDIS gadget: both usb0 and usb1 are enslaved to a br0 bridge (nmcli con add type bridge ifname br0 + two bridge-slave connections) with one static IP and dnsmasq serving DHCP on the bridge, so whichever driver the host picks lands on the same network. 5

Offensive-security framing

Gadget mode is the transport layer for USB attack platforms:

  • P4wnP1 A.L.O.A. (MaMe82; maintained fork RoganDawes/P4wnP1_aloa) composes RNDIS + CDC-ECM + HID keyboard/mouse + mass storage + serial gadgets at runtime, bridges the two Ethernet functions, and fires JavaScript “HIDScript” keystroke- injection payloads via TriggerActions when a host enumerates the device. It is Kali-based and ships as a current Kali ARM image (kali-linux-…raspberry-pi-zero-w-p4wnp1-aloa), but Pi Zero W only — the Zero 2 W’s different Wi-Fi chip is unsupported, and upstream source has been dormant since 2020; treat it as a reference architecture rather than a going concern. 6 7
  • On a Pi 4B the realistic 2026 pattern is: Raspberry Pi OS (or Kali ARM) + gadget Ethernet for control-plane access + the Pi’s own tools over SSH/RDP, with the encrypted-root and dropbear-initramfs tricks from the old spell replaced by current distro tooling. HID attacks from a 4B are possible via configfs hid.usb0 functions but there is no maintained turnkey framework for 4B-class boards.

Hardening notes (carried forward, still valid)

  • Bind SSH to the gadget interface only (ListenAddress on the usb0/br0 IP) and firewall everything else; the gadget link is a two-node network, so this is cheap.
  • The old guide’s reasoning still holds: a host-only USB link justifies pragmatism (e.g. reused host keys between dropbear and OpenSSH) that would be unacceptable on a real network — but RDP/VNC must never escape the gadget interface.
  • If the Pi will be dropped on unknown networks, disable NetworkManager’s auto-connect on the wired interface so it doesn’t gleefully DHCP onto the target LAN.

Sources

Related: raspberry-pi-network-tap, ntlm-relay-attacks (credential capture is a common payload once a gadget device is on the wire), opc-ua-security (another domain where built-in security is off by default).

Footnotes

  1. USB gadget mode in Raspberry Pi OS: SSH over USB (raspberrypi.com)

  2. rpi-usb-gadget — Raspberry Pi USB Gadget package README

  3. [HOWTO] Headless configuration of a Raspberry Pi using USB Ethernet Gadget on Bookworm

  4. Linux USB gadget configured through configfs (kernel.org)

  5. Pi5 USB-C Gadget — Ben’s Place (2023)

  6. P4wnP1 A.L.O.A. README (RoganDawes fork)

  7. Raspberry Pi Zero W P4wnP1 A.L.O.A — Kali Linux documentation