4.12. Using USBGuard

The USBGuard software framework provides system protection against intrusive USB devices by implementing basic whitelisting and blacklisting capabilities based on device attributes. To enforce a user-defined policy, USBGuard uses the Linux kernel USB device authorization feature. The USBGuard framework provides the following components:
  • The daemon component with an inter-process communication (IPC) interface for dynamic interaction and policy enforcement.
  • The command-line interface to interact with a running USBGuard instance.
  • The rule language for writing USB device authorization policies.
  • The C++ API for interacting with the daemon component implemented in a shared library.

4.12.1. Installing USBGuard

To install the usbguard package, enter the following command as root:
~]# yum install usbguard
To create the initial rule set, enter the following command as root:
~]# usbguard generate-policy > /etc/usbguard/rules.conf

Note

To customize the USBGuard rule set, edit the /etc/usbguard/rules.conf file. See the usbguard-rules.conf(5) man page for more information. Additionally, see Section 4.12.3, “Using the Rule Language to Create Your Own Policy” for examples.
To start the USBGuard daemon, enter the following command as root:
~]# systemctl start usbguard.service
~]# systemctl status usbguard
● usbguard.service - USBGuard daemon
   Loaded: loaded (/usr/lib/systemd/system/usbguard.service; disabled; vendor preset: disabled)
   Active: active (running) since Tue 2017-06-06 13:29:31 CEST; 9s ago
     Docs: man:usbguard-daemon(8)
 Main PID: 4984 (usbguard-daemon)
   CGroup: /system.slice/usbguard.service
           └─4984 /usr/sbin/usbguard-daemon -k -c /etc/usbguard/usbguard-daem...
To ensure USBGuard starts automatically at system start, use the following command as root:
~]# systemctl enable usbguard.service
Created symlink from /etc/systemd/system/basic.target.wants/usbguard.service to /usr/lib/systemd/system/usbguard.service.
To list all USB devices recognized by USBGuard, enter the following command as root:
~]# usbguard list-devices
1: allow id 1d6b:0002 serial "0000:00:06.7" name "EHCI Host Controller" hash "JDOb0BiktYs2ct3mSQKopnOOV2h9MGYADwhT+oUtF2s=" parent-hash "4PHGcaDKWtPjKDwYpIRG722cB9SlGz9l9Iea93+Gt9c=" via-port "usb1" with-interface 09:00:00
...
6: block id 1b1c:1ab1 serial "000024937962" name "Voyager" hash "CrXgiaWIf2bZAU+5WkzOE7y0rdSO82XMzubn7HDb95Q=" parent-hash "JDOb0BiktYs2ct3mSQKopnOOV2h9MGYADwhT+oUtF2s=" via-port "1-3" with-interface 08:06:50
To authorize a device to interact with the system, use the allow-device option:
~]# usbguard allow-device 6
To deauthorize and remove a device from the system, use the reject-device option. To just deauthorize a device, use the usbguard command with the block-device option:
~]# usbguard block-device 6
USBGuard uses the block and reject terms with the following meaning:
  • block - do not talk to this device for now
  • reject - ignore this device as if did not exist
To see all options of the usbguard command, enter it with the --help directive:
~]$ usbguard --help

4.12.2. Creating a White List and a Black List

The usbguard-daemon.conf file is loaded by the usbguard daemon after it parses its command-line options and is used to configure runtime parameters of the daemon. To override the default configuration file (/etc/usbguard/usbguard-daemon.conf), use the -c command-line option. See the usbguard-daemon(8) man page for further details.
To create a white list or a black list, edit the usbguard-daemon.conf file and use the following options:

USBGuard configuration file

RuleFile=<path>
The usbguard daemon use this file to load the policy rule set from it and to write new rules received through the IPC interface.
IPCAllowedUsers=<username> [<username> ...]
A space-delimited list of user names that the daemon will accept IPC connections from.
IPCAllowedGroups=<groupname> [<groupname> ...]
A space-delimited list of group names that the daemon will accept IPC connections from.
IPCAccessControlFiles=<path>
Path to a directory holding the IPC access control files.
ImplicitPolicyTarget=<target>
How to treat devices that do not match any rule in the policy. Accepted values: allow, block, reject.
PresentDevicePolicy=<policy>
How to treat devices that are already connected when the daemon starts:
  • allow - authorize every present device
  • block - deauthorize every present device
  • reject - remove every present device
  • keep - just sync the internal state and leave it
  • apply-policy - evaluate the ruleset for every present device
PresentControllerPolicy=<policy>
How to treat USB controllers that are already connected when the daemon starts:
  • allow - authorize every present device
  • block - deauthorize every present device
  • reject - remove every present device
  • keep - just sync the internal state and leave it
  • apply-policy - evaluate the ruleset for every present device

Example 4.4. USBGuard configuration

The following configuration file orders the usbguard daemon to load rules from the /etc/usbguard/rules.conf file and it allows only users from the usbguard group to use the IPC interface:
RuleFile=/etc/usbguard/rules.conf
IPCAccessControlFiles=/etc/usbguard/IPCAccessControl.d/
To specify the IPC Access Control List (ACL), use the usbguard add-user or usbguard remove-user commands. See the usbguard(1) for more details. In this example, to allow users from the usbguard group to modify USB device authorization state, list USB devices, listen to exception events, and list USB authorization policy, enter the following command as root:
~]# usbguard add-user -g usbguard --devices=modify,list,listen --policy=list --exceptions=listen

Important

The daemon provides the USBGuard public IPC interface. In Red Hat Enterprise Linux, the access to this interface is by default limited to the root user only. Consider setting either the the IPCAccessControlFiles option (recommended) or the IPCAllowedUsers and IPCAllowedGroups options to limit access to the IPC interface. Do not leave the ACL unconfigured as this exposes the IPC interface to all local users and it allows them to manipulate the authorization state of USB devices and modify the USBGuard policy.
For more information, see the IPC Access Control section in the usbguard-daemon.conf(5) man page.

4.12.3. Using the Rule Language to Create Your Own Policy

The usbguard daemon decides whether to authorize a USB device based on a policy defined by a set of rules. When a USB device is inserted into the system, the daemon scans the existing rules sequentially and when a matching rule is found, it either authorizes (allows), deauthorizes (blocks) or removes (rejects) the device, based on the rule target. If no matching rule is found, the decision is based on an implicit default target. This implicit default is to block the device until a decision is made by the user.
The rule language grammar is the following:
rule ::= target device_id device_attributes conditions.

target ::= "allow" | "block" | "reject".

device_id ::= "*:*" | vendor_id ":*" | vendor_id ":" product_id.

device_attributes ::= device_attributes | attribute.
device_attributes ::= .

conditions ::= conditions | condition.
conditions ::= .
For more details about the rule language such as targets, device specification, or device attributes, see the usbguard-rules.conf(5) man page.

Example 4.5. USBguard example policies

Allow USB mass storage devices and block everything else
This policy blocks any device that is not just a mass storage device. Devices with a hidden keyboard interface in a USB flash disk are blocked. Only devices with a single mass storage interface are allowed to interact with the operating system. The policy consists of a single rule:
allow with-interface equals { 08:*:* }
The blocking is implicit because there is no block rule. Implicit blocking is useful to desktop users because a desktop applet listening to USBGuard events can ask the user for a decision if an implicit target was selected for a device.
Allow a specific Yubikey device to be connected through a specific port
Reject everything else on that port.
allow 1050:0011 name "Yubico Yubikey II" serial "0001234567" via-port "1-2" hash "044b5e168d40ee0245478416caf3d998"
reject via-port "1-2"
Reject devices with suspicious combination of interfaces
A USB flash disk which implements a keyboard or a network interface is very suspicious. The following set of rules forms a policy which allows USB flash disks and explicitly rejects devices with an additional and suspicious interface.
allow with-interface equals { 08:*:* }
reject with-interface all-of { 08:*:* 03:00:* }
reject with-interface all-of { 08:*:* 03:01:* }
reject with-interface all-of { 08:*:* e0:*:* }
reject with-interface all-of { 08:*:* 02:*:* }

Note

Blacklisting is the wrong approach and you should not just blacklist a set of devices and allow the rest. The policy above assumes that blocking is the implicit default. Rejecting a set of devices considered as "bad" is a good approach how to limit the exposure of the system to such devices as much as possible.
Allow a keyboard-only USB device
The following rule allows a keyboard-only USB device only if there is not a USB device with a keyboard interface already allowed.
allow with-interface one-of { 03:00:01 03:01:01 } if !allowed-matches(with-interface one-of { 03:00:01 03:01:01 })
After an initial policy generation using the usbguard generate-policy command, edit the /etc/usbguard/rules.conf to customize the USBGuard policy rules.
~]$ usbguard generate-policy > rules.conf
~]$ vim rules.conf
To install the updated policy and make your changes effective, use the following commands:
~]# install -m 0600 -o root -g root rules.conf /etc/usbguard/rules.conf

4.12.4. Additional Resources

For additional information on USBGuard, see the following documentation:
  • usbguard(1) man page
  • usbguard-rules.conf(5) man page
  • usbguard-daemon(8) man page
  • usbguard-daemon.conf(5) man page