USBGuard is a security framework for Linux that controls which USB devices are permitted to interact with the system. It sits above the kernel’s native USB authorisation subsystem — a per-device authorisation flag in the USB core that determines whether a device can be configured and begin sending data — and enforces a policy defined in a rule file against every device that connects or is present at startup. The threat model USBGuard addresses is both insider threat (unauthorised storage devices, data exfiltration) and hardware attack: BadUSB devices — malicious firmware embedded in devices that present themselves as HID keyboards, network adapters, or other trusted classes — can be blocked by a sufficiently specific USBGuard policy that restricts which USB interface classes are permitted. A USB device that claims to be a keyboard (03:01:01) but was not explicitly authorised cannot send keystrokes; a USB storage device plugged into a workstation with a policy that only allows a specific keyboard and mouse is blocked outright. USBGuard cannot protect against devices present at boot (before the daemon starts), so it is a defence-in-depth control for the running OS rather than a substitute for physical port security.
The daemon (usbguard-daemon) watches for USB events via the kernel’s uevent subsystem and evaluates each connecting device against an ordered set of rules in /etc/usbguard/rules.conf (or individual files under /etc/usbguard/rules.d/ loaded in alphanumeric order). Each rule specifies a verdict — allow, block, or reject — and a set of match conditions: USB vendor and product ID (id 04f2:0833), serial number, device name, port (via-port "7-2" — the physical port the device is plugged into), and interface classes (with-interface { 03:01:01 03:00:00 } for a composite HID keyboard/mouse device). Interface-class matching is the most security-relevant attribute: it is not forgeable at the USB protocol level, unlike the vendor/product ID and serial number fields which a rogue device’s firmware can set to any value. The ImplicitPolicyTarget setting in usbguard-daemon.conf controls what happens to devices that match no rule: block (silently prevent configuration) is the safe default for locked-down servers; allow is appropriate for workstations during initial policy capture. The standard onboarding workflow is usbguard generate-policy --no-hashes > /etc/usbguard/rules.conf with all permitted devices already connected, which snapshots the current device set as the allowed baseline; any subsequently connected device is blocked until an administrator explicitly adds a rule. At runtime, usbguard list-devices shows all connected devices and their current authorisation state, and usbguard allow-device <id> or usbguard block-device <id> makes temporary runtime changes that can be permanently promoted to the rules file.
The IPC interface that the usbguard CLI uses to communicate with the daemon is a significant attack surface: any process that can reach the IPC socket can change device authorisation state and modify policy. The access to this interface is limited to the root user only by default on RHEL; the IPCAllowedUsers and IPCAllowedGroups settings in usbguard-daemon.conf must be explicitly configured to restrict this to a minimal set of administrators. Leaving the ACL unconfigured exposes the IPC to all local users. USBGuard integrates with the Linux audit subsystem: policy events (device allowed, blocked, or rejected) are logged to the kernel audit log and queryable with ausearch -m USER_DEVICE, providing an immutable record of every USB device interaction. On RHEL, USBGuard is a CIS Benchmark Level 2 requirement for workstations and servers that handle sensitive data, and pairs naturally with fapolicyd (which controls what software a connected USB device might have introduced) and IMA (which can measure and attest the integrity of files accessed from a USB-backed filesystem). USBGuard itself mitigates its own attack surface by using a seccomp syscall allowlist and dropping unnecessary Linux capabilities at startup.
