Ubuntu · Filesystem & permissions

Block USB mass storage and FireWire kernel modules

When it fails: USB storage devices and FireWire can be used on the system. Anyone with physical access can copy data to a USB disk, bring in tools, or use FireWire direct memory access.

CB-UBU-FS-002mediumactiveautomatedautomated fixprofile serverprofile desktop-hardened

Description

usb-storage is the driver for USB disks and keys, firewire-core the base of the FireWire (IEEE 1394) stack. This control blocks the modules listed in {{ modules }}: each one gets an install <module> /bin/false rule, so any load attempt fails, and a blacklist rule. A module that no installed kernel ships is compliant.

The Ubuntu generic kernel ships usb-storage in linux-modules on every release, so the check fails until the fix runs. firewire-core comes with linux-modules-extra on 20.04 to 24.04 (not installed on cloud and minimal images) and with linux-modules on 26.04. Ubuntu's own /etc/modprobe.d/blacklist-firewire.conf only names the old ieee1394 drivers (ohci1394, sbp2...), not the current FireWire stack. uas (USB Attached SCSI) depends on usb-storage and is blocked with it.

Rationale

Removable storage is a common way to take data out of a system and to bring malware in. FireWire controllers can read and write host memory directly, which lets a device extract keys or bypass the login. A server rarely needs either.

Impact

USB disks and keys are no longer usable. Keyboards, mice and other USB devices keep working. On a hardened workstation, use the network or an approved channel to exchange files, or remove usb-storage from {{ modules }} and control devices with USBGuard instead.

Setting

Location/etc/modprobe.d/60-cirsec-usb-firewire.conf
DefaultUSB storage and FireWire modules load when a device is plugged in
Recommendedinstall /bin/false and blacklist for: {{ modules }}

Parameters

ParameterCoreServerServer hardenedDesktopDesktop hardenedBounds
moduleslist. Kernel modules to block, as named by modprobe.usb-storage, firewire-coreusb-storage, firewire-coreusb-storage, firewire-coreusb-storage, firewire-coreusb-storage, firewire-core

The value used is your override (tailoring file), else the profile's, else the one of the profile it extends, else the default. Bounds limit what an override may set.

Audit

For each module of {{ modules }}:

  1. modprobe --showconfig | grep -E '^(install|blacklist) <module>' must show install <module> /bin/false and blacklist <module> (dashes appear as underscores), or find /lib/modules -name '<module>.ko*' must find nothing.
  2. grep '^<module> ' /proc/modules (with underscores) must find nothing.

Automated: every check must pass. Scanners report each check by its id.

modules

Each listed module is blocked in the modprobe configuration, or not shipped, and not loaded.

script: |
  cfg=$(modprobe --showconfig 2>/dev/null) || exit 3
  rc=0
  for m in $CB_MODULES; do
    n=$(printf '%s' "$m" | tr - _)
    if grep -q "^$n " /proc/modules; then
      echo "$m: loaded"; rc=1; continue
    fi
    if printf '%s\n' "$cfg" | grep -Eq "^install $n (/usr)?/bin/(false|true)( |\$)" &&
      printf '%s\n' "$cfg" | grep -qx "blacklist $n"; then
      echo "$m: blocked"
    elif [ -z "$(find /lib/modules/ \( -name "$m.ko*" -o -name "$n.ko*" \) 2>/dev/null | head -n 1)" ] &&
      ! grep -qs "/$n.ko\$\|/$m.ko\$" /lib/modules/*/modules.builtin; then
      echo "$m: not shipped by any installed kernel"
    else
      echo "$m: can be loaded"; rc=1
    fi
  done
  exit $rc

Remediation

  1. Create /etc/modprobe.d/60-cirsec-usb-firewire.conf with, for each module of {{ modules }}:
    install <module> /bin/false
    blacklist <module>
    
  2. Unplug the devices and unload the modules with modprobe -r <module>, or reboot.
Restartnone
Disruptionlow

Rollback

Delete /etc/modprobe.d/60-cirsec-usb-firewire.conf. The modules load again when a device is plugged in.

modprobe-conf

f=/etc/modprobe.d/60-cirsec-usb-firewire.conf
cb_backup "$f"
{
  echo '# Written by CIRSEC Baselines CB-UBU-FS-002'
  for m in $CB_MODULES; do printf 'install %s /bin/false\nblacklist %s\n' "$m" "$m"; done
} >"$f"
chmod 644 "$f"
rc=0
for m in $CB_MODULES; do
  n=$(printf '%s' "$m" | tr - _)
  grep -q "^$n " /proc/modules || continue
  modprobe -r "$n" || { echo "$m is in use, it stays loaded until reboot" >&2; rc=1; }
done
exit $rc

Handwritten code reads parameters from CB_<NAME> environment variables. Each release turns these fixes into remediate.sh and an Ansible role per profile: dry run by default, a fix runs only when its check fails.

References

Mappings

FrameworkIDRelation
NIST SP 800-53 Rev. 55.1.1MP-7partial
NIST SP 800-53 Rev. 55.1.1CM-7related

How this control relates to the other framework's: equivalent, stricter, looser, partial or related.

Threats mitigated

  • related CB-UBU-FS-001 Block kernel modules for filesystems the system does not use

People and lifecycle

Authors
Verified2026-10-19 by Sn0wAlice on 20.04, Proxmox VM 2520, Ubuntu 20.04 cloud image, kernel 5.4.0-216-generic. Fails on fresh install (usb-storage shipped); fix writes the modprobe rules, modprobe then refuses usb-storage; kept after reboot; server-hardened profile.
Verified2026-10-19 by Sn0wAlice on 22.04, Proxmox VM 2522, Ubuntu 22.04 cloud image, kernel 5.15.0-198-generic. Fails on fresh install (usb-storage shipped); fix writes the modprobe rules, modprobe then refuses usb-storage; kept after reboot; server-hardened profile.
Verified2026-10-19 by Sn0wAlice on 24.04, Proxmox VM 2524, Ubuntu 24.04 cloud image, kernel 6.8.0-147-generic. Fails on fresh install (usb-storage shipped); fix writes the modprobe rules, modprobe then refuses usb-storage; kept after reboot; server-hardened profile.
Verified2026-10-19 by Sn0wAlice on 26.04, Proxmox VM 2526, Ubuntu 26.04 cloud image, kernel 7.0.0-38-generic. Fails on fresh install (usb-storage shipped); fix writes the modprobe rules, modprobe then refuses usb-storage; kept after reboot; server-hardened profile.
Introduced inv0.1.0
Created, updated2026-10-19, 2026-10-19
Translationsfr