Mitigating USB-based attacks within OpenShift Container Platform
Purpose
This document walks through protections that can be put in place to block USB-based attacks against OCP. These defensive measures are most appropriate for systems where implementing physical access controls is difficult or infeasible, such as a network-edge deployment. Reducing the attack surface for USB devices can significantly reduce the severity of many other vulnerabilities or eliminate their risk entirely.
This document references a Linux kernel vulnerability (CVE-2024-53104) and the associated USB Video Class driver (uvcvideo) as an example. While this example impacts the Linux kernel's, this document is generic enough to be used for any kernel module which relates to USB.
Note that if you have the OpenShift Compliance operator installed and applied the rhcos4-moderate or rhcos4-high profiles, USB access to your nodes is already restricted.
Blocking unused kernel modules via MachineConfig
If your OpenShift cluster does not use specific kernel modules (for example the uvcvideo module for CVE-2024-53104) Red Hat recommends mitigating this potential attack surface by preventing that module from loading as shown below. Utilize this solution to inspect which modules are currently loaded on a system. Note that removing a module will disable its functionality. In the case of UVC devices, removing the uvcvideo module prevents webcams or video capture devices from functioning properly.
To block a module from loading you’ll create a drop-in config in /etc/modprobe.d/ directory such as /etc/modprobe.d/ocp-deny-uvcvideo.conf based on Preventing kernel modules from being automatically loaded at system boot time as follows
blacklist uvcvideo
install uvcvideo /bin/false
To create this file on OpenShift nodes you will create a new MachineConfig object which defines the file with content similar to above, the contents section is the urlencoded, you may use the Butane tool to generate machineConfig resources in a more friendly manner. The following example would deploy the file on workers and will trigger a rolling restart. If you also wish to protect your control plane nodes, create a similar MachineConfig with this command: machineconfiguration.openshift.io/role: “master”.
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
metadata:
labels:
machineconfiguration.openshift.io/role: worker
name: 99-worker-deny-uvcvideo
spec:
config:
ignition:
version: 3.2.0
storage:
files:
- contents:
compression: ""
source: data:,blacklist%20uvcvideo%0Ainstall%20uvcvideo%20%2Fbin%2Ffalse%0A
mode: 420
overwrite: true
path: /etc/modprobe.d/ocp-deny-uvcvideo.conf
Assuming the contents above are saved as 99-worker-deny-uvcvideo.yaml, this policy could be applied by running the following command as an admin: oc apply -f 99-worker-deny-uvcvideo.yaml
oc apply -f 99-worker-deny-uvcvideo.yaml
machineconfig.machineconfiguration.openshift.io/99-worker-deny-uvcvideo created
Blocking the uvcvideo kernel module via Compliance Operator Profiles
You can choose to modify your node configurations using existing Compliance Operator profiles or by creating a tailored profile. To use this method, you must first install the Compliance Operator on your Cluster. To disable the use of USB devices, you can run the rhcos4-moderate or rhcos4-high profile. If you only want to disable a specific module such as uvcvideo you can create a tailored profile instead as shown below.
Steps to Create a TailoredProfile to check and disable a module:
1. Create a TailoredProfile
Save this file as deny-uvc-profile.yaml:
apiVersion: compliance.openshift.io/v1alpha1
kind: TailoredProfile
metadata:
name: deny-uvc-profile
namespace: openshift-compliance
annotations:
## We need to set product type to Node for rhcos4 profile rules
compliance.openshift.io/product-type: Node
spec:
description: a profile will check if uvcvideo module is disabled
enableRules:
- name: rhcos4-kernel-module-uvcvideo-disabled
rationale: CVE-2024-53104 documents a vulnerability found in the Linux kernel's USB Video Class driver. The vulnerability exists in functionality used by the USB Video Class driver to decode the format of video frames.
title: Ensure uvcvideo module is being disabled
Activate the TailoredProfile:
$ oc apply -f deny-uvc-profile.yaml
How to enable usbguard
The following rules (which enable and configure usbguard) are shipped by default in rhcos4-moderate and rhcos4-high profiles provided in Compliance Operator
- rhcos4-package-usbguard-installed
- rhcos4-service-usbguard-enabled
- rhcos4-configure-usbguard-auditbackend
- rhcos4-usbguard-allow-hid-and-hub
You can either run a scan for rhcos4-moderate and rhcos4-high profile and apply remediation or use the below tailoredProfile. Save this file as enable-usbguard-tp.yml:
apiVersion: compliance.openshift.io/v1alpha1
kind: TailoredProfile
metadata:
name: enable-usbguard-tp
namespace: openshift-compliance
annotations:
## We need to set product type to Node for rhcos4 profile rules
compliance.openshift.io/product-type: Node
spec:
description: a profile will check if uvcvideo module is disabled
enableRules:
- name: rhcos4-package-usbguard-installed
rationale: we need to check and install usbguard
- name: rhcos4-service-usbguard-enabled
rationale: usbguard will be installed after install
- name: rhcos4-configure-usbguard-auditbackend
rationale: verify that Linux Audit logging is enabled for the USBGuard daemon
- name: rhcos4-usbguard-allow-hid-and-hub
rationale: We will allow Human Interface Devices and hubs
title: Ensure USBGuard is enabled
Activating the usbguard rule will trigger multiple reboots:
$ oc get cr
NAME STATE
enable-usbguard-tp-master-package-usbguard-installed Applied
enable-usbguard-tp-master-service-usbguard-enabled MissingDependencies
enable-usbguard-tp-master-usbguard-allow-hid-and-hub MissingDependencies
enable-usbguard-tp-worker-package-usbguard-installed Applied
enable-usbguard-tp-worker-service-usbguard-enabled MissingDependencies
enable-usbguard-tp-worker-usbguard-allow-hid-and-hub MissingDependencies
USBGuard Service has to be installed before it can be enabled, so you would have to wait for the remediation to be applied and MachineConfigPool to become ready and then rerun the scan.
2. Create ScanSettingBinding that references the created TailoredProfile
Save this file as deny-uvc-ssb.yaml:
apiVersion: compliance.openshift.io/v1alpha1
kind: ScanSettingBinding
metadata:
name: deny-uvc-ssb
namespace: openshift-compliance
profiles:
- apiGroup: compliance.openshift.io/v1alpha1
kind: TailoredProfile
name: deny-uvc-profile
settingsRef:
apiGroup: compliance.openshift.io/v1alpha1
kind: ScanSetting
name: default-auto-apply
You can include this TailoredProfile with other existing profiles in a ScanSettingBinding you are already using or create a new one.
Use the default-auto-apply will automatically apply the generated remediation otherwise if you want to apply remediation manually you use default ScanSetting here adjust and create ScanSetting to let operator know what pool you want to apply the Scan and remediation to, we have master, worker role as default.
Activate the ScanSettingBinding
$ oc apply -f deny-uvc-ssb.yaml
3. Check TailoredProfile and ScanSettingBinding are in Ready States
$ oc get tp
NAME STATE
deny-uvc-profile READY
$ oc get ssb
NAME STATUS
deny-uvc-ssb READY
4. Wait for scan to finish and remediation to be applied
$ oc get scan
NAME PHASE RESULT
deny-uvc-profile-master DONE NON-COMPLIANT
deny-uvc-profile-worker DONE NON-COMPLIANT
$ oc get ccr
NAME STATUS SEVERITY
deny-uvc-profile-master-kernel-module-uvcvideo-disabled FAIL medium
deny-uvc-profile-worker-kernel-module-uvcvideo-disabled FAIL medium
We can see that the compliance remediation has been generated and applied to the cluster
$ oc get cr
NAME STATE
deny-uvc-profile-master-kernel-module-uvcvideo-disabled Applied
deny-uvc-profile-worker-kernel-module-uvcvideo-disabled Applied
We can inspect the generated compliance remediation:
$ oc get cr -o yaml
apiVersion: v1
items:
- apiVersion: compliance.openshift.io/v1alpha1
kind: ComplianceRemediation
metadata:
creationTimestamp: "2025-02-10T23:33:44Z"
generation: 2
labels:
compliance.openshift.io/scan-name: deny-uvc-profile-master
compliance.openshift.io/suite: deny-uvc-ssb
name: deny-uvc-profile-master-kernel-module-uvcvideo-disabled
namespace: openshift-compliance
spec:
apply: true
current:
object:
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
spec:
config:
ignition:
version: 3.1.0
storage:
files:
- contents:
source: data:,install%20uvcvideo%20/bin/false%0Ablacklist%20uvcvideo%0A
mode: 420
overwrite: true
path: /etc/modprobe.d/uvcvideo.conf
outdated: {}
type: Configuration
status:
applicationState: Applied
Wait for all nodes to finish updating:
$ oc get mcp
NAME CONFIG UPDATED UPDATING DEGRADED MACHINECOUNT READYMACHINECOUNT UPDATEDMACHINECOUNT DEGRADEDMACHINECOUNT AGE
master rendered-master-2d509f401a173fe88c986bbfb94443e3 True False False 3 3 3 0 63m
worker rendered-worker-c0e83d6064f20d73d77adea67e4ce254 False True False 3 1 3 0 63m
5. Rerun the ComplianceScan
To check if the remediation has taken effect:
$ oc compliance rerun-now scansettingbindings deny-uvc-ssb
Rerunning scans from 'deny-uvc-ssb': deny-uvc-profile-master, deny-uvc-profile-worker
Re-running scan 'openshift-compliance/deny-uvc-profile-master'
Re-running scan 'openshift-compliance/deny-uvc-profile-worker'
6. Verification
We can now see that all scans are in passing state:
$ oc get scan
NAME PHASE RESULT
deny-uvc-profile-master DONE COMPLIANT
deny-uvc-profile-worker DONE COMPLIANT
$ oc get ccr
NAME STATUS SEVERITY
deny-uvc-profile-master-kernel-module-uvcvideo-disabled PASS medium
deny-uvc-profile-worker-kernel-module-uvcvideo-disabled PASS medium
Optionally we can check on each node as well:
$oc debug node/<HOSTNAME-HERE>
Temporary namespace openshift-debug-24ngm is created for debugging node...
Starting pod/<HOSTNAME-HERE> ...
To use host binaries, run `chroot /host`
Pod IP: <IP-SHOWN-HERE>
If you don't see a command prompt, try pressing enter.
sh-5.1# chroot /host
sh-5.1# cat /etc/modprobe.d/uvcvideo.conf
install uvcvideo /bin/false
blacklist uvcvideo
sh-5.1# modprobe uvcvideo
modprobe: ERROR: Error running install command '/bin/false' for module uvcvideo: retcode 1
modprobe: ERROR: could not insert 'uvcvideo': Invalid argument
sh-5.1# lsmod | grep uvcvideo
Note about USBGuard
When you use the rhcos4-moderate or rhcos4-high profiles, the following rules are used to enable and configure USBGguard:
- rhcos4-package-usbguard-installed
- rhcos4-service-usbguard-enabled
- rhcos4-configure-usbguard-auditbackend
- rhcos4-usbguard-allow-hid-and-hub
You can either run a scan for one of those profiles and apply the remediations or use them in a tailoredProfile, following the example above. USBGuard could be an additional protection layer.
This would be the YAML file:
apiVersion: compliance.openshift.io/v1alpha1
kind: TailoredProfile
metadata:
name: enable-usbguard-tp
namespace: openshift-compliance
annotations:
## We need to set product type to Node for rhcos4 profile rules
compliance.openshift.io/product-type: Node
spec:
description: a profile will check if uvcvideo module is disabled
enableRules:
- name: rhcos4-package-usbguard-installed
rationale: we need to check and install usbguard
- name: rhcos4-service-usbguard-enabled
rationale: usbguard will be installed after install
- name: rhcos4-configure-usbguard-auditbackend
rationale: verify that Linux Audit logging is enabled for the USBGuard daemon
- name: rhcos4-usbguard-allow-hid-and-hub
rationale: We will allow Human Interface Devices and hubs
title: Ensure USBGuard is enabled
Applying the usbguard rule will trigger multiple reboots:
$oc get cr
NAME STATE
enable-usbguard-tp-master-package-usbguard-installed Applied
enable-usbguard-tp-master-service-usbguard-enabled MissingDependencies
enable-usbguard-tp-master-usbguard-allow-hid-and-hub MissingDependencies
enable-usbguard-tp-worker-package-usbguard-installed Applied
enable-usbguard-tp-worker-service-usbguard-enabled MissingDependencies
enable-usbguard-tp-worker-usbguard-allow-hid-and-hub MissingDependencies
The USBGuard service needs to be installed before it can be enabled, so you would have to wait for the remediation to be applied and MachineConfigPool to become ready and then rerun the scan.
How to remove mitigations
Once a fixed version of the module has been installed, consider removing the mitigation. To do so, either unapply the remediation or delete the MachineConfig resource.
Comments