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 appendingrpi:\n enable_usb_gadget: truetouser-dataon 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_etherdriver 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.exefrom 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, leasing10.12.194.2–14to the host). SSH target is the Imager-set hostname or10.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:
- Edit
firstrun.shto copy/usr/lib/udev/rules.d/85-nm-unmanaged.rulesinto/etc/udev/rules.d/and comment out the gadget rule, so NM manages usb0. - Create two NM connection profiles in
/etc/NetworkManager/system-connections/(mode 600): oneipv4.method=auto(DHCP, high priority) and oneipv4.method=link-localfallback so the link still comes up when the host runs no DHCP server. - 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):
modprobe libcomposite,mkdir /sys/kernel/config/usb_gadget/<name>.- Set
idVendor/idProduct, device class fields, andstrings/0x409/*(serialnumber, manufacturer, product). mkdir configs/c.1/strings/0x409and set configuration string +MaxPower.- 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_addrMACs; for RNDIS set the Microsoft OS descriptorsos_desc+compatible_id "RNDIS"so Windows binds driverless). - Symlink functions into
configs/c.1/, thenls /sys/class/udc > UDCto bind. - 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.usb0functions but there is no maintained turnkey framework for 4B-class boards.
Hardening notes (carried forward, still valid)
- Bind SSH to the gadget interface only (
ListenAddresson 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
- USB gadget mode in Raspberry Pi OS: SSH over USB (raspberrypi.com)
- rpi-usb-gadget — Raspberry Pi USB Gadget package README
- Linux USB gadget configured through configfs (kernel.org)
- Pi5 USB-C Gadget — Ben’s Place (2023)
- [HOWTO] Headless configuration of a Raspberry Pi using USB Ethernet Gadget on Bookworm
- P4wnP1 A.L.O.A. README (RoganDawes fork)
- Raspberry Pi Zero W P4wnP1 A.L.O.A — Kali Linux documentation
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).