Comment vérifier l’état du stockage USB dans Linux avec un script Shell

Les périphériques de stockage amovibles tels que les clés USB sont des outils indispensables pour le transfert de données, les sauvegardes et la récupération du système. Cependant, ils représentent également un risque sérieux pour la sécurité s’ils ne sont pas gérés, en particulier dans les environnements d’entreprise ou de MSP. Savoir si l’accès au stockage USB est activé sur vos systèmes Linux n’est pas seulement une question de commodité : c’est une question d’application de politique, de conformité à la sécurité et de sensibilisation opérationnelle. Cet article présente un script shell qui automatise le processus pour vérifier l’état du stockage USB dans Linux avec un script shell et qui s’intègre éventuellement à NinjaOne pour rapporter les résultats.

Contexte

Sous Linux, le contrôle de l’accès au stockage USB est principalement assuré par des modules du noyau, en particulier les pilotes usb_storage et uas (USB Attached SCSI). Les administrateurs système peuvent désactiver ces pilotes en les plaçant sur une liste noire ou en les configurant pour qu’ils exécutent des commandes inoffensives au lieu de se charger.

Le script présenté ici est conçu pour inspecter le répertoire /etc/modprobe.d, où se trouvent généralement ces règles de chargement de modules. C’est particulièrement important dans les environnements gérés par NinjaOne, où une supervision centralisée et des contrôles de conformité automatisés sont essentiels. Les fournisseurs de services gérés (MSP) et les équipes informatiques internes bénéficient de ce type d’outils pour s’assurer que les terminaux sont conformes aux politiques de l’entreprise.

Le script :

#!/usr/bin/env bash

# Description: Checks if the linux machine currently allows access to USB storage devices and optionally saves the results to a custom field.
# 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).
#
#   The script checks the modprobe.d folder for any files that may block the USB storage driver or the USB Attached SCSI driver.
#   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
#
# Preset Parameter: -CustomField "usbStorageStatus"
#   The custom field to save the USB storage status to.
#
# Preset Parameter: --help
#   Displays the help menu.
#

# 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: [-CustomField "custom_field_name"]'
    printf '  %s\n' '-CustomField'
    printf '    The custom field to save the USB storage status to.\n'
}

# Parse the command-line arguments
parse_commandline() {
    while test $# -gt 0; do
        _key="$1"
        case "$_key" in
        -CustomField | --CustomField | -customfield | --customfield | -cf | --cf)
            _arg_customfield="CustomField"
            ;;
        --help | -help | -h | --h)
            _PRINT_HELP=yes die "" 0
            ;;
        *)
            _PRINT_HELP=yes die "[Error] Got an unexpected argument '$1'" 1
            ;;
        esac
        shift
    done
}

function SetCustomField() {
    if [[ -z "$1" ]] || [[ -z "$2" ]]; then
        echo "[Error] Missing required arguments."
        return 1
    fi
    local customfieldName=$1
    local customfieldValue=$2
    if [ -f "${NINJA_DATA_PATH}/ninjarmm-cli" ]; then
        if [ -x "${NINJA_DATA_PATH}/ninjarmm-cli" ]; then
            if "$NINJA_DATA_PATH"/ninjarmm-cli get "$customfieldName" >/dev/null; then
                # check if the value is greater than 10000 characters
                if [ ${#customfieldValue} -gt 10000 ]; then
                    echo "[Warn] Custom field value is greater than 10000 characters" >&2
                    return 1
                fi
                if ! echo "${customfieldValue::10000}" | "$NINJA_DATA_PATH"/ninjarmm-cli set --stdin "$customfieldName"; then
                    echo "[Warn] Failed to set custom field" >&2
                    return 1
                else
                    echo "[Info] Custom field value set successfully"
                fi
            else
                echo "[Warn] Custom Field ($customfieldName) does not exist or agent does not have permission to access it" >&2
                return 1
            fi
        else
            echo "[Warn] ninjarmm-cli is not executable" >&2
            return 1
        fi
    else
        echo "[Warn] ninjarmm-cli does not exist" >&2
        return 1
    fi
}

parse_commandline "$@"

# If script form variables are used, replace the command line parameters with their value.
if [[ -n "${customField}" ]]; then
    _arg_customfield="${customField}"
fi

# Variables
# Modprobe.d folder
modprobFolder="/etc/modprobe.d"

# Check if we have read access to the modprobe.d folder
if ! [ -r "${modprobFolder}" ]; then
    if [[ -n "${_arg_customfield}" ]]; then
        SetCustomField "${_arg_customfield}" "Unable to Determine"
    fi
    die "[Error] User ${USER} has no read access to modprobe.d folder" 1
fi

# Check if modprobe.d folder does not exist
if ! [ -d "${modprobFolder}" ]; then
    if [[ -n "${_arg_customfield}" ]]; then
        SetCustomField "${_arg_customfield}" "Unable to Determine"
    fi
    die "[Error] Modprobe folder does not exist" 1
fi

# Set default values
UsbStorage="Enabled"
usb_storage_status="Enabled"
uas_status="Enabled"
usb_storage_driver_status="Enabled"
uas_driver_status="Enabled"

# Check if usb_storage or uas is blocked in other files
for file in "${modprobFolder}"/*; do

    if ! [ -r "${file}" ]; then
        echo "[Warn] User ${USER} has no read access to ${file}"
    fi

    # Check if implicit loading is blocked
    if grep -q "blacklist usb_storage" "${file}"; then
        echo "[Info] USB storage driver is blocked in ${file}"
        usb_storage_status="Disabled"
    fi
    # Check if implicit loading is blocked
    if grep -q "blacklist uas" "${file}"; then
        echo "[Info] USB Attached SCSI driver is blocked in ${file}"
        uas_status="Disabled"
    fi

    # Check if explicit loading is blocked
    if grep -q "install usb-storage /bin/true" "${file}"; then
        echo "[Info] USB storage driver is blocked in ${file}"
        usb_storage_driver_status="Disabled"
    fi
    # Check if explicit loading is blocked
    if grep -q "install uas /bin/true" "${file}"; then
        echo "[Info] USB Attached SCSI driver is blocked in ${file}"
        uas_driver_status="Disabled"
    fi
done

# Output the status of implicit loading
if [ "${usb_storage_status}" == "Disabled" ] && [ "${uas_status}" == "Disabled" ]; then
    echo "[Info] USB storage driver implicit loading: Blocked"
elif [ "${usb_storage_status}" == "Enabled" ] && [ "${uas_status}" == "Enabled" ]; then
    echo "[Info] USB storage driver implicit loading: Allowed"
else
    echo "[Info] USB storage driver implicit loading: Partially Allowed"
fi

# Output the status of explicit loading
if [ "${usb_storage_driver_status}" == "Disabled" ] && [ "${uas_driver_status}" == "Disabled" ]; then
    echo "[Info] USB storage driver manual loading: Blocked"
elif [ "${usb_storage_driver_status}" == "Enabled" ] && [ "${uas_driver_status}" == "Enabled" ]; then
    echo "[Info] USB storage driver manual loading: Allowed"
else
    echo "[Info] USB storage driver manual loading: Partially Allowed"
fi

# Determine the overall status of USB storage
if [ "${usb_storage_status}" == "Disabled" ] && [ "${uas_status}" == "Disabled" ] && [ "${usb_storage_driver_status}" == "Disabled" ] && [ "${uas_driver_status}" == "Disabled" ]; then
    UsbStorage="Disabled"
elif [ "${usb_storage_status}" == "Enabled" ] && [ "${uas_status}" == "Enabled" ] && [ "${usb_storage_driver_status}" == "Enabled" ] && [ "${uas_driver_status}" == "Enabled" ]; then
    UsbStorage="Enabled"
elif [ "${usb_storage_status}" == "Enabled" ] || [ "${uas_status}" == "Enabled" ] || [ "${usb_storage_driver_status}" == "Enabled" ] || [ "${uas_driver_status}" == "Enabled" ]; then
    UsbStorage="Partially Allowed"
else
    UsbStorage="Unable to Determine"
fi

echo "[Info] USB storage is ${UsbStorage}"

if [[ -n "${_arg_customfield}" ]]; then
    SetCustomField "${_arg_customfield}" "${UsbStorage}"
fi

 

Description détaillée

Ce script shell exécute plusieurs tâches de manière structurée et tolérante aux pannes. Voici une description étape par étape :

  1. Analyse des arguments de la ligne de commande

    • Supporte l’argument optionnel -CustomField pour spécifier un champ personnalisé NinjaOne.
    • Fournit une option –help pour des conseils d’utilisation.
  2. Contrôle des autorisations et des dossiers

    • Valide l’existence et la lisibilité du répertoire /etc/modprobe.d.
    • Si l’accès est refusé ou si le dossier est manquant, il signale « Impossible à déterminer » et, s’il est configuré, l’écrit dans le champ personnalisé NinjaOne.
  3. Évaluation de l’état du pilote

    • Interroge chaque fichier du fichier /etc/modprobe.d.
    • Recherche :
      1. blacklist usb_storage ou blacklist uas (bloque le chargement implicite).
      2. install usb-storage /bin/true ou install uas /bin/true (bloque le chargement explicite).
    • Suivi de l’état de chaque méthode par pilote.
  4. Détermination du statut

    • Classe le chargement des pilotes dans les catégories suivantes : autorisé, bloqué ou partiellement autorisé.
    • Agrège le résultat en un statut final : activé, désactivé ou partiellement autorisé.
  5. Intégration avec NinjaOne

    • Si -CustomField est spécifié et que l’outil ninjarmm-cli est présent, le script écrit l’état du stockage USB dans le champ personnalisé désigné.

Cas d’utilisation potentiels

Étude de cas :

Un fournisseur de services de gestion des soins de santé gère des centaines de kiosques basés sur Linux dans des cliniques. La politique de sécurité prévoit que le stockage USB doit être désactivé pour empêcher l’extraction non autorisée de données. À l’aide de ce script, l’enteprise MSP peut :

  • Déployer le script sur tous les terminaux à l’aide de NinjaOne.
  • Enregistrer automatiquement le statut USB dans un champ personnalisé.
  • Générer des rapports de conformité.
  • Alerter les techniciens si une machine n’est pas conforme à la politique.

Cette surveillance proactive de la conformité permet d’économiser des heures d’audit manuel et garantit le respect des réglementations (par exemple, HIPAA).

Comparaisons

Autres méthodes

ApprocheAvantagesInconvénients
Inspection manuelle(lsmod, grep)Immédiate, native CLIPrend du temps, n’est pas évolutif
Scripts d’audit en PythonUne analyse plus soupleDes dépendances plus lourdes
Détection et réponse des terminaux (EDR)Contrôle centralisé, en temps réelCoût élevé, souvent axé sur Windows
Ce script ShellLéger, s’intègre à NinjaOnePeut nécessiter l’utilisation de sudo et l’intervention de techniciens connaissant bien Linux

La niche de ce script est sa simplicité, sa portabilité et son intégration native avec l’écosystème NinjaOne, ce qui le rend idéal pour les environnements où la simplicité et l’automatisation l’emportent sur la personnalisation.

Questions fréquentes sur la manière de vérifier l’état du stockage USB dans Linux avec un script shell

Quelles sont les distributions Linux prises en charge ?

La plupart des distributions basées sur Debian et Red Hat avec /etc/modprobe.d sont compatibles.

Ce script bloque-t-il le stockage USB ?

Non, il en vérifie uniquement le statut. Le blocage doit être géré par la configuration du système.

Qu’est-ce que ninjarmm-cli ?

Il s’agit de l’interface en ligne de commande de NinjaOne pour lire/écrire les données des champs personnalisés sur les terminaux.

Que signifie l’expression « partiellement autorisé » ?

Elle indique que certaines méthodes de chargement des pilotes sont autorisées tandis que d’autres sont bloquées.

Puis-je l’utiliser sans NinjaOne ?

Oui, mais vous ne pourrez pas enregistrer les résultats dans un champ personnalisé sans ninjarmm-cli.

Implications

Le fait de savoir si le stockage USB est autorisé a une incidence sur votre position en matière de risques. L’autorisation d’un accès USB illimité augmente le risque de fuite de données, d’introduction de logiciels malveillants et de transferts accidentels de données. Dans les secteurs réglementés (finance, santé, administration), il est souvent obligatoire de montrer que l’on contrôle l’accès USB. Ce script permet une telle surveillance d’une manière peu invasive et reproductible.

Recommandations

  • Exécutez le script avec les autorisations élevées pour garantir un accès complet à /etc/modprobe.d.
  • Standardisez le nom du champ personnalisé sur tous les appareils pour des rapports unifiés dans NinjaOne.
  • Associez ce script à des outils de remédiation qui imposent le blocage en cas de détection de non-conformité.
  • Planifiez-la comme une tâche récurrente dans NinjaOne pour la validation périodique de la conformité.

Conclusion

L’utilisation d’un script shell pour vérifier l’état du stockage USB sous Linux offre une méthode légère, vérifiable et automatisable pour la vérification de la conformité des terminaux. Associé à NinjaOne, ce script devient un outil puissant pour l’application centralisée des politiques et la visibilité. Que vous soyez un MSP gérant des flottes de clients ou une équipe informatique interne sécurisant les actifs de l’entreprise, cette solution offre le parfait équilibre entre simplicité et puissance.

Next Steps

Building an efficient and effective IT team requires a centralized solution that acts as your core service delivery tool. NinjaOne enables IT teams to monitor, manage, secure, and support all their devices, wherever they are, without the need for complex on-premises infrastructure.

Learn more about NinjaOne Remote Script Deployment, check out a live tour, or start your free trial of the NinjaOne platform.

Catégories :

Vous pourriez aussi aimer