Controlling access to USB storage devices is a foundational practice for maintaining data integrity and preventing unauthorized data exfiltration in enterprise environments. As threats from removable media persist—ranging from insider data leaks to malware-laden USB drives—IT administrators and Managed Service Providers (MSPs) must enforce strict policies on USB usage. One effective and scalable method is scripting control at the kernel module level. This blog post dives deep into a robust shell script designed to enable, disable, or configure USB storage devices on Linux with shell scripting.
Background
On Linux systems, USB storage access is governed by kernel modules—specifically, usb-storage and uas (USB Attached SCSI). These modules can be automatically loaded when devices are connected (implicit loading) or manually invoked (explicit loading). By blocking or permitting these modules at the system level, IT professionals can effectively control USB storage device behavior across fleets of Linux endpoints.
The script in question is built for automation, policy enforcement, and compatibility with RMM platforms like NinjaOne. It creates and manages configuration files in /etc/modprobe.d/, updates the initial RAM filesystem (initramfs), and can optionally trigger a system reboot—making it a complete solution for USB device governance.
The Script:
#!/usr/bin/env bash
# Description: Enable or disable USB storage devices on Linux.
# By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://www.ninjaone.com/terms-of-use.
# Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms.
# Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party.
# Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider.
# Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations.
# Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks.
# Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script.
# EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).
#
# There are two methods of loading USB storage drivers that allow mounting of USB storage devices:
# 1. Implicit loading: The USB storage driver is loaded automatically when a USB storage device is connected.
# 2. Explicit loading: The USB storage driver is loaded manually by a user, program, or script.
#
# Release Notes: Initial Release
#
# Notes: This will create config files in /etc/modprobe.d/ as needed to block USB storage devices.
#
# Usage: [-Enable | -Disable] [-Reboot]
#
# Preset Parameter: --help
# Displays the help menu.
#
# Preset Parameter: -Enable
# Enables USB storage devices.
#
# Preset Parameter: -Disable
# Disables USB storage devices.
#
# Preset Parameter: -Reboot
# Reboots the system, if needed, after enabling or disabling USB storage devices.
# Functions
# Print an error message and exit with a specific status code
die() {
local _ret="${2:-1}"
test "${_PRINT_HELP:-no}" = yes && print_help >&2
echo "$1" >&2
exit "${_ret}"
}
print_help() {
printf '\n\n%s\n\n' 'Usage: [-Enable | -Disable]'
printf ' %s\n' '-Enable'
printf ' Enables USB storage devices'
printf ' %s\n' '-Disable'
printf ' Disables USB storage devices'
}
# Set the default values
_arg_reboot="false"
# Parse the command-line arguments
parse_commandline() {
while test $# -gt 0; do
_key="$1"
case "$_key" in
-Enable | --Enable | -enable | --enable | -e | --e)
_arg_action="Enable"
;;
-Disable | --Disable | -disable | --disable | -d | --d)
_arg_action="Disable"
;;
--Reboot | --reboot | -Reboot | -reboot | -r | --r)
_arg_reboot="true"
;;
--help | -help | -h | --h)
_PRINT_HELP=yes die "" 0
;;
*)
_PRINT_HELP=yes die "[Error] Got an unexpected argument '$1'" 1
;;
esac
shift
done
}
parse_commandline "$@"
# Exit if not running as root
if [[ $EUID -ne 0 ]]; then
die "[Error] This script must be run as root or SYSTEM from NinjaRMM" 1
fi
# If script form variables are used, replace the command line parameters with their value.
if [[ -n "${action}" ]] && [[ "${action}" == "Enable" ]]; then
_arg_action="Enable"
elif [[ -n "${action}" ]] && [[ "${action}" == "Disable" ]]; then
_arg_action="Disable"
fi
if [[ "${reboot}" == "true" ]]; then
_arg_reboot="true"
fi
# Check if action is empty
if [[ -z "${_arg_action}" ]]; then
die "Invalid action. Use Enable or Disable" 1
fi
# Variables
# Modprobe.d folder
modprobFolder="/etc/modprobe.d"
# Config file
configFile="${modprobFolder}/ninja-usb-block.conf"
# Check if modprobe.d folder does not exists
if ! [ -d "${modprobFolder}" ]; then
die "[Error] Modprobe folder does not exist" 1
fi
# Check if usb-storage and uas kenel drivers are modules
if ! modprobe -n uas >/dev/null 2>&1; then
die "[Error] USB Attached SCSI driver(uas) must be compiled as a kernel module" 1
fi
if ! modprobe -n usb-storage >/dev/null 2>&1; then
die "[Error] USB storage(usb-storage) driver must be compiled as a kernel module" 1
fi
if [[ "${_arg_action}" == "Enable" ]]; then
# Enable USB storage
# Check if our file exists
if [ -f "${configFile}" ]; then
echo "[Info] Enabling USB storage devices"
# Remove our config file
rm "${configFile}"
echo "[Info] Enabled USB storage devices"
else
echo "[Info] USB storage devices are already enabled"
fi
# Remove other blocks USB storage in other files
for file in "${modprobFolder}"/*; do
# Remove implicit USB Storage block
if grep -q "blacklist usb_storage" "${file}"; then
echo "[Info] Removing implicit USB Storage block in ${file}"
sed -i '/blacklist usb_storage/d' "${file}"
echo "[Info] Removed implicit USB Storage block in ${file}"
fi
# Remove implicit USB Attached SCSI block
if grep -q "blacklist uas" "${file}"; then
echo "[Info] Removing implicit USB Attached SCSI block in ${file}"
sed -i '/blacklist uas/d' "${file}"
echo "[Info] Removed implicit USB Attached SCSI block in ${file}"
fi
# Remove explicit USB Storage driver block
if grep -q "install usb-storage /bin/true" "${file}"; then
echo "[Info] Removing explicit USB Storage block in ${file}"
sed -i '/install usb-storage \/bin\/true/d' "${file}"
echo "[Info] Removed explicit USB Storage block in ${file}"
fi
# Remove explicit USB Attached SCSI driver block
if grep -q "install uas /bin/true" "${file}"; then
echo "[Info] Removing explicit USB Attached SCSI block in ${file}"
sed -i '/install uas \/bin\/true/d' "${file}"
echo "[Info] Removed explicit USB Attached SCSI block in ${file}"
fi
done
# Check that update-initramfs command exists
if command -v update-initramfs >/dev/null 2>&1; then
# Update the initramfs
echo "[Info] Updating initramfs"
update-initramfs -u >/dev/null 2>&1
echo "[Info] Updated initramfs"
fi
if [[ "${_arg_reboot}" == "true" ]]; then
echo "[Info] Rebooting the system to enable USB storage devices"
# Shutdown in 1 minute
shutdown -r +1
else
echo "[Info] USB storage devices are enabled, please reboot the system"
fi
elif [[ "${_arg_action}" == "Disable" ]]; then
# Disable USB storage
# Variables to determine if we should block the drivers
blacklist_uas="false"
blacklist_usb_storage="false"
block_uas="false"
block_usb_storage="false"
# Check if usb_storage or uas is blocked in other files
for file in "${modprobFolder}"/*; do
# Check if implicit loading is already blocked
if grep -q "blacklist uas" "${file}"; then
echo "[Info] USB Attached SCSI drivers are already implicitly blocked in ${file}"
else
blacklist_uas="true"
fi
# Check if implicit loading is already blocked
if grep -q "blacklist usb_storage" "${file}"; then
echo "[Info] USB storage drivers are already implicitly blocked in ${file}"
else
blacklist_usb_storage="true"
fi
# Check if explicit loading is already blocked
if grep -q "install uas /bin/true" "${file}"; then
echo "[Info] USB Attached SCSI drivers are already explicitly blocked in ${file}"
else
block_uas="true"
fi
# Check if explicit loading is already blocked
if grep -q "install uas /bin/true" "${file}"; then
echo "[Info] USB storage drivers are already explicitly blocked in ${file}"
else
block_usb_storage="true"
fi
done
if [ "${blacklist_uas}" == "true" ]; then
echo "[Info] Implicitly Disabling USB Attached SCSI driver"
# Check if config file exists
if ! [ -f "${configFile}" ]; then
echo "[Info] Creating blocklist config file (${configFile})"
touch "${configFile}"
fi
# Write the line to the file
echo "blacklist uas" >>"${configFile}"
fi
if [ "${blacklist_usb_storage}" == "true" ]; then
echo "[Info] Implicitly Disabling USB storage driver"
# Check if config file exists
if ! [ -f "${configFile}" ]; then
echo "[Info] Creating blocklist config file (${configFile})"
touch "${configFile}"
fi
# Write the line to the file
echo "blacklist usb_storage" >>"${configFile}"
fi
if [ "${block_uas}" == "true" ]; then
echo "[Info] Explicitly Disabling USB Attached SCSI driver"
# Check if uas config file exists
if ! [ -f "${modprobFolder}" ]; then
echo "[Info] Creating UAS config file (${modprobFolder}/uas.conf)"
touch "${modprobFolder}/uas.conf"
fi
# Write the line to the file
echo "install uas /bin/true" >>"${modprobFolder}/uas.conf"
fi
if [ "${block_usb_storage}" == "true" ]; then
echo "[Info] Explicitly Disabling USB storage driver"
# Check if usb-storage config file exists
if ! [ -f "${modprobFolder}" ]; then
echo "[Info] Creating USB storage config file (${modprobFolder}/usb-storage.conf)"
touch "${modprobFolder}/usb-storage.conf"
fi
# Write the line to the file
echo "install usb-storage /bin/true" >>"${modprobFolder}/usb-storage.conf"
fi
# Unload the modules
echo "[Info] Unloading USB storage modules"
modprobe -r uas >/dev/null 2>&1
modprobe -r usb_storage >/dev/null 2>&1
rmmod uas >/dev/null 2>&1
rmmod usb_storage >/dev/null 2>&1
# Check if the modules are still loaded
modules_unloaded="true"
if lsmod | grep -q uas; then
modules_unloaded="false"
fi
if lsmod | grep -q usb_storage; then
modules_unloaded="false"
fi
# Check that update-initramfs command exists
if command -v update-initramfs >/dev/null 2>&1; then
# Update the initramfs
echo "[Info] Updating initramfs"
update-initramfs -u >/dev/null 2>&1
echo "[Info] Updated initramfs"
# Set to false so we can reboot or warn that a reboot is needed
modules_unloaded="false"
if [[ "${_arg_reboot}" == "false" ]]; then
echo "[Warn] USB storage devices can still be mounted, please reboot the system"
fi
fi
if [ "${modules_unloaded}" == "true" ]; then
echo "[Info] Unloaded USB storage modules"
else
if [[ "${_arg_reboot}" == "true" ]]; then
echo "[Info] USB storage devices are still mounted, rebooting the system"
# Shutdown in 1 minute
shutdown -r +1
else
echo "[Warn] USB storage devices are still mounted, please unmount them and rerun this script OR reboot the system"
fi
fi
else
die "[Error] Invalid parameter. Use -Enable or -Disable" 1
fi
Detailed Breakdown
Here’s how the script functions step-by-step:
1. Command-Line Parsing
The script accepts the following flags:
- -Enable: Allows USB storage by removing related kernel module restrictions.
- -Disable: Prevents USB storage by applying kernel module blacklists and explicit loading blocks.
- -Reboot: Optional flag to reboot the machine after the change.
- –help: Displays usage instructions.
2. Privilege Check
The script verifies it’s being run with root privileges—essential for kernel-level changes.
3. Module Detection
It confirms that usb-storage and uas are compiled as kernel modules, a prerequisite for the changes to be effective.
4. Enabling USB Storage
When -Enable is invoked:
- The script removes its own config file (ninja-usb-block.conf).
- It scans other .conf files in /etc/modprobe.d/ and deletes any blacklist or explicit load-block directives.
- It regenerates initramfs to reflect the changes.
- Optionally, it schedules a reboot.
5. Disabling USB Storage
When -Disable is used:
- The script writes blacklist (blacklist usb_storage, blacklist uas) and install block (install usb-storage /bin/true) directives into dedicated .conf files.
- It forcibly unloads the kernel modules using modprobe -r and rmmod.
- It validates module removal via lsmod.
- It updates initramfs and, if needed, reboots the system.
Potential Use Cases
Case Study: Securing Developer Laptops
An MSP managing Linux developer workstations wants to prevent code or proprietary data from being exfiltrated via USB drives. Using NinjaOne, the admin deploys this shell script with the -Disable -Reboot flags. All targeted systems become USB-storage restricted upon next boot. During a code freeze, USB access is temporarily re-enabled via a scheduled task with -Enable.
This method ensures tight control with auditability and rollback capability.
Comparisons
| Method | Pros | Cons |
| udev rules | Granular device control | Requires device IDs, complex |
| Group Policy (on Windows) | Native enforcement | Not applicable to Linux |
| Shell Script (This) | Fast, scriptable, integrates well | Requires kernel module support |
| SELinux/AppArmor | Very secure | Complex to configure properly |
Compared to alternatives, this shell script offers a balanced mix of simplicity, portability, and system-wide enforcement without needing to handle device IDs or third-party software.
Implications
Using this script enhances endpoint security and enforces policy compliance across Linux machines. It mitigates risks from:
- Insider threats transferring sensitive data
- Malware infection from rogue USBs
- Bypass of DLP systems via removable drives
For regulated industries like finance, healthcare, or government, this script offers an effective compliance control.
Recommendations
- Test before mass deployment—especially on systems with custom kernel modules.
- Automate rollback procedures—store a backup of modified .conf files.
- Integrate with RMM alerts—track systems where USB storage is re-enabled.
- Schedule reboots carefully to avoid disrupting users.
Final Thoughts
Whether you’re looking to disable USB storage devices on Linux with shell scripting, enable USB storage devices on Linux with shell scripting, or configure USB storage access policies on Linux, this script offers a reliable and maintainable approach. Through NinjaOne’s scripting and automation framework, MSPs and IT professionals can operationalize USB governance at scale—enforcing security policies while maintaining administrative control.
For managing Linux endpoints efficiently and securely, NinjaOne’s centralized scripting, automation, and reporting tools complement this script’s power, helping teams scale enforcement without increasing workload.