USBGuard

USBGuard configuration and GNOME integration guide

USBGuard configuration and GNOME integration guide

Require unlock to access new USB devices or accessories

USBGuard configuration

🚨 Caution

Do not start the service until the daemon and rules have been configured. Otherwise, all USB devices, including keyboard and mouse, will be blocked. It is suggested to set up SSH alongside to retain access.

Install the package:

sudo pacman -Syu usbguard
📝 Note

The following configuration will apply system-wide. However, after configuring the GNOME integration, it will apply to the GNOME Display Manager only. After logging in, all new USB devices will be allowed when unlocked, but blocked when locked.

Configure the daemon:

sudo nano /etc/usbguard/usbguard-daemon.conf

If you want to control the daemon via IPC, be sure to add your username to IPCAllowedUsers or your group to IPCAllowedGroups to make rules persistent. In most cases, you want this.

Configure device-specific rules to allow all currently attached USB devices:

sudo sh -c 'usbguard generate-policy -P > /etc/usbguard/rules.conf'

-P: Don’t generate port specific rules.

💡 Tip

Rerun this every time the USB peripherals are changed.

Inspect/adjust the generated rules:

sudo nano /etc/usbguard/rules.conf

Additionally, for the allowance of trusted devices to persist, note down the id, serial, name, hash, with-interface, and with-connect-type fields of them, and create allow rules in a separate file:

sudo nano /etc/usbguard/rules.d/99-known-devices.conf

Example:

# Keyboard
allow id abcd:1234 serial "98765ZYXWV" name "USB Keyboard" hash "hHI9EVQBLKHSN8MkPy1rC4mC8CIrx4WLOlGcpZttBzjc=" with-interface { 03:01:01 03:01:02 } with-connect-type "hotplug"
# Mouse
allow id efgh:5678 serial "43210UTSRQ" name "USB Mouse" hash "TH6G3gRyhZ4slGqwZVUnSv1fVE0CSrGC588tsCBCDZ1V=" with-interface { 03:01:02 } with-connect-type "hotplug"

Change the permissions:

sudo chmod 0600 /etc/usbguard/rules.d/99-known-devices.conf

Enable the service:

sudo systemctl enable usbguard.service

Start the service:

sudo systemctl start usbguard.service

Reboot:

sudo reboot

[Optional] Configure generic rules - allow a keyboard and a mouse as a failsafe in case the above rules didn’t work (e.g., if a new keyboard is used):

sudo nano /etc/usbguard/rules.d/99-keyboard-and-mouse.conf

With the following content:

## Credit https://github.com/Kicksecure/security-misc/blob/master/etc/usbguard/rules.d/30_security-misc.conf%23security-misc-shared

## We allow devices that were plugged in before the daemon starts. Everything
## is blocked as the default. Following rules apply on top of this.

## First match wins. Therefore, reject rules should be on the top.
## Quote:
## https://usbguard.github.io/documentation/rule-language
## > the daemon scans the existing rules sequentially

## Explicitly reject any interface that is not documented and/or defined by
## USB.org.
## Note: Most probably superfluous.
reject with-interface none-of { 00:*:* 01:*:* 02:*:* 03:*:* 05:*:* 06:*:* 07:*:* 08:*:* 09:*:* 0a:*:* 0b:*:* 0d:*:* 0e:*:* 0f:*:* 10:*:* 11:*:* 12:*:* 13:*:* 14:*:* 3c:*:* dc:*:* e0:*:* ef:*:* fe:*:* ff:*:* }

## Explicitly reject any device with a mouse/keyboard interface in
## combination with some other interface.
## Mice and keyboards should likely never have non-HID interfaces provided
## alongside them.
reject with-interface all-of { 03:*:* 00:*:* }
reject with-interface all-of { 03:*:* 01:*:* }
reject with-interface all-of { 03:*:* 02:*:* }
reject with-interface all-of { 03:*:* 05:*:* }
reject with-interface all-of { 03:*:* 06:*:* }
reject with-interface all-of { 03:*:* 07:*:* }
reject with-interface all-of { 03:*:* 08:*:* }
reject with-interface all-of { 03:*:* 09:*:* }
reject with-interface all-of { 03:*:* 0a:*:* }
reject with-interface all-of { 03:*:* 0b:*:* }
reject with-interface all-of { 03:*:* 0d:*:* }
reject with-interface all-of { 03:*:* 0e:*:* }
reject with-interface all-of { 03:*:* 0f:*:* }
reject with-interface all-of { 03:*:* 10:*:* }
reject with-interface all-of { 03:*:* 11:*:* }
reject with-interface all-of { 03:*:* 12:*:* }
reject with-interface all-of { 03:*:* 13:*:* }
reject with-interface all-of { 03:*:* 14:*:* }
reject with-interface all-of { 03:*:* 3c:*:* }
reject with-interface all-of { 03:*:* dc:*:* }
reject with-interface all-of { 03:*:* e0:*:* }
reject with-interface all-of { 03:*:* ef:*:* }
reject with-interface all-of { 03:*:* fe:*:* }
reject with-interface all-of { 03:*:* ff:*:* }

## Explicitly reject any device with an RNDIS interface. RNDIS is believed to
## have protocol-level buffer overflow vulnerabilities that cannot be fixed.
reject with-interface one-of { ef:04:* }

## Allow only one keyboard to be connected
allow with-interface one-of { 03:00:01 03:01:01 } if !allowed-matches(with-interface one-of { 03:00:01 03:01:01 })
## Allow only one mouse to be connected
allow with-interface one-of { 03:00:02 03:01:02 } if !allowed-matches(with-interface one-of { 03:00:02 03:01:02 })
🚨 Caution

It might be possible for a malicious device to spoof as a keyboard/mouse (ref). Avoid using this configuration if possible.

📝 Note

Unplug and replug if the keyboard/mouse does not work. If a keyboard/mouse has both the class code of a keyboard and a mouse, the rules above will block any other keyboard and mouse from connecting.

Change the permissions:

sudo chmod 0600 /etc/usbguard/rules.d/99-keyboard-and-mouse.conf

GNOME integration

Allow GNOME to communicate with USBGuard via DBUS. Enable the service:

sudo systemctl enable usbguard-dbus.service

Start the service:

sudo systemctl start usbguard-dbus.service

Authorize GNOME to access USBGuard. Create:

sudo nano /etc/polkit-1/rules.d/70-allow-usbguard.rules

With:

// Allow users in wheel group to communicate with USBGuard
polkit.addRule(function(action, subject) {
    if ((action.id == "org.usbguard.Policy1.listRules" ||
         action.id == "org.usbguard.Policy1.appendRule" ||
         action.id == "org.usbguard.Policy1.removeRule" ||
         action.id == "org.usbguard.Devices1.applyDevicePolicy" ||
         action.id == "org.usbguard.Devices1.listDevices" ||
         action.id == "org.usbguard1.getParameter" ||
         action.id == "org.usbguard1.setParameter") &&
        subject.active == true && subject.local == true &&
        subject.isInGroup("wheel")) {
            return polkit.Result.YES;
    }
});

In GNOME Settings > Privacy & Security > Screen Lock, turn on “Forbid New USB Devices”.

References

https://wiki.archlinux.org/title/Security#Protect_against_rogue_USB_devices

https://wiki.archlinux.org/title/USBGuard

https://github.com/USBGuard/usbguard

https://usbguard.github.io/

https://usbguard.github.io/documentation/configuration.html

https://usbguard.github.io/documentation/rule-language.html

https://github.com/Kicksecure/security-misc/blob/master/etc/usbguard/rules.d/30_security-misc.conf%23security-misc-shared

https://www.technotesanddadjokes.com/veeam-hardened-repository-device-is-not-authorized-for-usage/

https://forums.kicksecure.com/t/usbguard-what-should-we-allow-or-disallow-by-default/1248/1

https://www.usb.org/defined-class-codes

Code licensed under the MIT License; all other content under CC BY-SA 4.0.
Last updated on Feb 26, 2026 18:15 UTC
Built with Hugo
Theme Stack designed by Jimmy