Le contrôle de l’accès aux périphériques de stockage USB est une pratique fondamentale pour maintenir l’intégrité des données et empêcher l’exfiltration de données non autorisées dans les environnements d’entreprise. Face à la persistance des menaces liées aux supports amovibles (des fuites de données internes aux clés USB chargées de logiciels malveillants) les administrateurs informatiques et les fournisseurs de services gérés (MSP) doivent appliquer des politiques strictes en matière d’utilisation des clés USB. Une méthode efficace et évolutive consiste à contrôler les scripts au niveau du module du noyau (kernel). Cet article plonge dans un script shell performant conçu pour activer, désactiver ou configurer les périphériques de stockage USB sur Linux avec un script shell.
Contexte
Sur les systèmes Linux, l’accès au stockage USB est régi par des modules du noyau, notamment usb-storage et uas (USB Attached SCSI). Ces modules peuvent être chargés automatiquement lorsque les appareils sont connectés (chargement implicite) ou invoqués manuellement (chargement explicite). En bloquant ou en autorisant ces modules au niveau du système, les professionnels de l’informatique peuvent contrôler efficacement le comportement des périphériques de stockage USB dans les parcs de terminaux Linux.
Le script en question est conçu pour l’automatisation, l’application de stratégies et la compatibilité avec des plateformes RMM telles que NinjaOne. Il crée et gère les fichiers de configuration dans /etc/modprobe.d/, met à jour le système de fichiers RAM initial (initramfs) et peut éventuellement déclencher un redémarrage du système, ce qui en fait une solution complète pour la gouvernance des périphériques USB.
Le 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
Description détaillée
Voici comment fonctionne le script, étape par étape :
1. Analyse de la ligne de commande
Le script accepte les drapeaux suivants :
- -Enable : Permet le stockage USB en supprimant les restrictions liées au module du noyau.
- -Disable : Empêche le stockage USB en appliquant des listes noires de modules du noyau et des blocs de chargement explicites.
- -Reboot : Indicateur facultatif permettant de redémarrer la machine après la modification.
- –help : Affiche les instructions d’utilisation.
2. Contrôle des privilèges
Le script vérifie qu’il est exécuté avec les privilèges de l’utilisateur root, ce qui est essentiel pour les modifications au niveau du noyau.
3. Détection des modules
Il confirme que usb-storage et uas sont compilés en tant que modules du noyau, une condition préalable pour que les changements soient effectifs.
4. Activation du stockage USB
Lorsque l’option -Enable est invoquée :
- Le script supprime son propre fichier de configuration (ninja-usb-block.conf).
- Il analyse les autres fichiers .conf dans /etc/modprobe.d/ et supprime toute liste noire ou directive explicite de blocage de charge.
- Il régénère les initramfs pour refléter les changements.
- En option, il planifie un redémarrage.
5. Désactivation du stockage USB
Lorsque l’option -Disable est utilisée :
- Le script écrit les directives blacklist (blacklist usb_storage, blacklist uas) et install block (install usb-storage /bin/true) dans des fichiers .conf dédiés.
- Il décharge de force les modules du noyau en utilisant modprobe -r et rmmod.
- Il valide la suppression d’un module via lsmod.
- Il met à jour initramfs et, si nécessaire, redémarre le système.
Cas d’utilisation potentiels
Étude de cas : Sécuriser les ordinateurs portables des développeurs
Un MSP gérant des postes de travail de développeurs Linux souhaite empêcher l’exfiltration de code ou de données propriétaires par le biais de clés USB. Avec NinjaOne, l’administrateur déploie ce script shell avec les options -Disable -Reboot. Tous les systèmes visés deviennent limités à la mémoire USB au prochain démarrage. Lors d’un gel de code, l’accès USB est temporairement réactivé par une tâche programmée avec -Enable.
Cette méthode garantit un contrôle rigoureux avec possibilité d’audit et de retour en arrière.
Comparaisons
| Méthode | Avantages | Inconvénients |
| règles udev | Contrôle précis des appareils | Nécessite des identifiants d’appareils, complexes |
| Stratégie de groupe (sous Windows) | Application par les autochtones | Non applicable à Linux |
| Shell Script (Ceci) | Rapide, scriptable, bien intégré | Nécessite la prise en charge du module du noyau |
| SELinux/AppArmor | Très sûr | Complexe à configurer correctement |
Par rapport aux autres solutions, ce script shell offre un mélange équilibré de simplicité, de portabilité et d’application à l’échelle du système sans qu’il soit nécessaire de gérer des identifiants d’appareils ou des logiciels tiers.
Questions fréquentes
Question 1 : Que se passe-t-il si mon système n’utilise pas initramfs ?
Le script saute silencieusement les mises à jour des initramfs. Toutefois, les modifications peuvent ne pas s’appliquer avant le prochain redémarrage.
Question 2 : Ce script peut-il être déployé via NinjaOne ?
Oui. Il est entièrement compatible avec l’automatisation des scripts Linux de NinjaOne, y compris la prise en charge du passage de paramètres tels que action=Disable et reboot=true.
Question 3 : Que se passe-t-il si un utilisateur charge manuellement le module après l’avoir désactivé ?
La directive install /bin/true empêche même le chargement manuel des modules, à moins qu’elle ne soit explicitement supprimée.
Question 4 : Est-ce réversible ?
Absolument. L’exécution du script avec -Enable annule toute la configuration et rétablit la fonctionnalité USB.
Implications
L’utilisation de ce script permet de renforcer la sécurité des points d’accès et d’assurer la conformité des politiques sur les machines Linux. Il atténue les risques de :
- Menaces d’initiés transférant des données sensibles
- Infection par des logiciels malveillants à partir de clés USB frauduleuses
- Contournement des systèmes DLP via des lecteurs amovibles
Pour les secteurs réglementés tels que la finance, la santé ou l’administration, ce script offre un contrôle de conformité efficace.
Recommandations
- Testez avant de procéder à un déploiement massif, en particuliersur les systèmes dotés de modules de noyau personnalisés.
- Automatiser les procédures de retour en arrière en stockantune sauvegarde des fichiers .conf modifiés.
- Intégration avec les alertes RMM : suivi dessystèmes où le stockage USB est réactivé.
- Planifiez soigneusement les redémarrages pour éviter de perturber les utilisateurs.
Conclusion
Que vous cherchiez à désactiver les périphériques de stockage USB sous Linux à l’aide d’un script shell, à activer les périphériques de stockage USB sous Linux à l’aide d’un script shell, ou à configurer les politiques d’accès au stockage USB sur Linux, ce script offre une approche fiable et facile à maintenir. Grâce au cadre de script et d’automatisation de NinjaOne, les MSP et les professionnels de l’informatique peuvent opérationnaliser la gouvernance USB à l’échelle – en renforçant les politiques de sécurité tout en conservant le contrôle administratif.
Pour gérer les points d’extrémité Linux de manière efficace et sécurisée, les outils centralisés de script, d’automatisation et de reporting de NinjaOne complètent la puissance de ce script, aidant les équipes à faire évoluer l’application sans augmenter la charge de travail.