USBAUTH(8)

πŸ›‘οΈ USBAUTH(8) β€” the usbauth page from the System Manager's Manual, section 8, bestie

okay so first things first: this whole page is about usbauth, and it's a USB firewall against BadUSB attacks πŸ’… that's the whole vibe, let's get into it.


✨ SYNOPSIS ✨

Three modes, three moods. Pick your fighter:

udev mode β€” called by udev:

usbauth udev-add

manual mode β€” called by the notifier:

usbauth allow DEVNUM PATH
usbauth deny DEVNUM PATH

where:

  • PATH is the path of the USB interface, example /sys/bus/usb/devices/3-2/3-2:1.0/
  • DEVNUM is the value of the attribute, example 16 (from /sys/bus/usb/devices/3-2/devnum)

init mode β€” does apply rules for all available devices:

usbauth init

🌸 DESCRIPTION 🌸

It's a firewall against BadUSB attacks, periodt. πŸ”₯

A config file describes in which way USB interfaces would be accepted or denied. To the kernel, an interface authorization was developed with this firewall β€” and the firewall sets the authorization mask according to the rules. That's literally it. That's the whole job. πŸ‘‘


πŸŽ€ RULES πŸŽ€

The Attribute

[parameter operator value]

An attribute consists of a parameter, an operator and a value. Three little pieces, one iconic trio. ✨

The allow/deny rule

allow|deny Attribute+

A allow/deny rule have at minimum one attribute. For a allow/deny rule to be enforced, an USB interface must match all attributes β€” no cherry-picking, bestie, all of them or nothing. 🫢

Example: a rule describes all interfaces with the HID class 0x03.

The condition

condition Attribute+ case Attribute+

The first section describes the condition that must be fulfilled. The second section, with the keyword case, defines for what interfaces the condition should apply.

Example: all rules that describe HID interfaces should apply for two devices at maximum. Then the device counter must be fulfilled. The second section describes the interface class 0x03.

Default rules

allow|deny all

These rules are for the generic case. If no other rule matches an interface, these are the ones that catch it. 🧚

Order matters, ngl

Rules will be checked top down. A rule at top could be overwritten by a rule at down. So yeah β€” position your faves wisely. πŸ’€


πŸ’œ Parameters πŸ’œ

The following parameters are defined at device section

  • busnum β€” number of the USB bus
  • devpath β€” number of the USB port
  • idVendor β€” vendor ID, defines the vendor of the USB device
  • idProduct β€” product ID, defines the product from a vendor
  • bDeviceClass β€” USB device class
  • bDeviceSubClass β€” USB device sub class
  • bDeviceProtocol β€” USB device protocol
  • bConfigurationValue β€” current USB configuration
  • serial β€” serial number of the device
  • manufacturer β€” manufacturer of device
  • product β€” product name string
  • connect_type β€” hotplug: external USB device, direct: internal USB device
  • bcdDevice β€” USB protocol version
  • speed β€” USB speed value
  • bNumConfigurations β€” the number of available USB configurations

The following parameters are defined at configuration section

  • bNumInterfaces β€” number of available interfaces in the active configuration
  • bInterfaceNumber β€” interface number
  • bInterfaceClass β€” interface class
  • bInterfaceSubClass β€” current sub class of interface
  • bInterfaceProtocol β€” in case of HID devices, with this value keyboards (1) and mouses (2) could be distinct
  • bNumEndpoints β€” number of endpoints for the interface

The special internals πŸ‘€

The following parameters are specific and calculated internally by the firewall. They are not available in the SysFS. They count how many devices or interfaces match a rule.

  • intfcount β€” number of interfaces for a rule
  • devcount β€” number of devices for a rule

anyChild

The keyword anyChild could be used for a parameter to check not only the own interface's attribute, but also check the siblings' attribute. If one sibling matches, the rule is valid. 🌈


πŸ¦‹ Operators πŸ¦‹

The following operators are defined: ==, !=, <=, >=, <, >

With operators two values are compared. One from the data structure of a rule, the other from an USB interface. Simple as that, no cap. πŸ’…


⭐ Values ⭐

The configured value will be compared with the default value type from sysfs. If not specified, the type of the configured value is assumed to be in sysfs value type.

  • Using \x as value prefix will set the configured value type as hexadecimal.
  • Using \d as value prefix will set the configured value type as decimal.
  • With an explicit integer value, a type conversion will be done if the value type does not match the sysfs value type.
  • Using double quotes for the configured value forces a string comparisation. It allows you to specify strings containing spaces, too. πŸ“
  • Point separated integer values like 1.2.3 (e.g. for devpath) are possible, and they also allow explicit type prefixing like \x1.2.3.

πŸ‘‘ Rule examples πŸ‘‘

these are examples from the page, copy them exactly, do not freestyle πŸ™ˆ

Default rule to allow everything:

allow all

Default rule to deny everything:

deny all

Every configuration file should allow hubs β€” only special cases should limit these:

allow bDeviceClass==09 bInterfaceClass==09

Interfaces with device class 0 and interface class 08 (storage) will be accepted:

allow bDeviceClass==00 bInterfaceClass==08
allow bInterfaceClass==08

β†’ the device class is irrelevant in this case.

Two USB storage devices will be accepted at specific USB ports. Not more than one storage device is allowed during a condition:

allow idVendor==0781 idProduct==5406 bInterfaceClass==08 busnum==3 devpath==6
allow idVendor==8564 idProduct==1000 bInterfaceClass==08 busnum==3 devpath==4
condition devcount<=1 case bInterfaceClass==08

β†’ the condition is valid for all interfaces from class 08. Interfaces must comply with the condition for enforcing the two belonging allow rules.

Allow two HID (example keyboard and mouse) devices at maximum:

allow bInterfaceClass==03 devcount<=2

Allow only one keyboard:

allow bInterfaceClass==03 anyChild bInterfaceProtocol==01 devcount<=1

Allow only one mouse:

allow bInterfaceClass==03 bInterfaceProtocol==02 devcount<=1

β†’ The parent device children of the interface would be enumerated to check for the attribute. If one matches the attribute, then the rule will be enforced.

A keyboard should have two interfaces. The bInterfaceProtocol of the first interface is "1", from the second "0". (the original page has a stray br here β€” that's a formatting thing, not a rule πŸ’€) With anyChild it is possible to allow a rule matching for both interfaces. (another stray br in the original β€” iconic of it, honestly πŸŽ€)

Allow only certain interfaces:

Example: a multi function device have three interfaces (0xFF, 0x07, 0x08). 0xFF is to scan, 0x07 is to print, and 0x08 is for storage devices connected to the multi function device.

With the following rules only the 0xFF and 0x07 interfaces are allowed. The device class must be 0.

allow idVendor==04b8 idProduct==089e bDeviceClass==00 bInterfaceClass==ff
allow idVendor==04b8 idProduct==089e bDeviceClass==00 bInterfaceClass==07

okay that's genuinely the whole page, you ate that πŸ’– go forth and firewall your USB ports like the main character you are.

sign-off time: this was USBAUTH(8), page 8 of the System Manager's Manual β€” mwah, take care of your hubs 🫢✨