Disparadores Linux: udev

26 de jun. de 2026

Como SysAdmin, y usuario he probado diferentes Sistemas Operativos...

Copiando la frase de la película Superdetective en Holliwood: "No siempre fui policia", yo también puedo decir que no siempre fui linuxero.

No siempre fui linuxero

Hubo épocas en que me tocó administrar "otros sistemas operativos" y también fui propietario de algun portatil de la manzanita.

¿Historias del abuelo cebolleta?

En su momento tenía un DVD externo de Apple que sólo funcionaba si se conectaba a un Mac.
En cuanto el MacOS fue sustituido elegantemente por un Debian, me encontré que lo único que no me funcionaba con Linux era ese grabador de DVD.
La malvada bruja de la manzana envenenada hacia que su DVD solo se encendiese si recibía mediante su firmware una cadena especial de inicialización.

Espejito, espejito.. ¿qué sistema operativo es más hermoso?

Para poder usar ese hardware por el que has pagado, algunas personas abrían el DVD y cambiaban uno de los chips para dejarlo sin el encantamiento de la bruja.
Yo preferí hacer la magia por software, principalmente por si quería venderlo en el futuro sin ningún tipo de modificación.
Y es ahora cuando llegamos al porqué del título del artículo.

La mágia de los disparadores en Linux

La única solución que encontré fue hacer que cuando Linux detectase que cierto hardware se disparase una acción directamente.

Para ello me aproveché de una las maravilla de Linux, el sistema udev, el truco es crear un fichero especial con una regla en la ruta /etc/udev/rules.d/

Linux al detectar un nuevo dispositivo revisa las reglas definidas y si se cumple ejecuta las acciones de ese fichero.

DVD SuperDrive de Apple

En aquel momento para el dispositivo Superdrive de Apple, me creé un fichero de nombre 99-superdrive.rules muy original en el que su contenido era simplemente lo siguiente:

# Inicializar SuperDrive de Apple
# Luis GuLo
ACTION=="add", ATTRS{idProduct}=="1500", ATTRS{idVendor}=="05ac", DRIVERS=="usb", RUN+="/usr/bin/sg_raw /dev/$kernel EA 00 00 00 00 00 01"

Aprovechando este ejemplo real vamos a ver exactamente como funciona un disparador en Linux.

Este comando es una regla de udev (el gestor de dispositivos de Linux).
Su objetivo es escuchar los eventos del sistema y, en cuanto detecta que se conecta un hardware muy específico, ejecutar un comando "oculto" para activarlo.

Basicamente se compone de dos partes:

  • Las Condiciones (los filtros para encontrar el hardware)
  • La Acción (lo que hace con él).

Parte 1: Las Condiciones (El Filtro)

udev lee esta línea de izquierda a derecha. Si el dispositivo que acabas de conectar no cumple todas y cada una de estas condiciones, Linux ignora la regla y no hace nada.

  • ACTION=="add"
    • Qué hace: Filtra por el tipo de evento. Indica que la regla solo se activará cuando un dispositivo sea conectado o añadido al sistema. No hará nada cuando lo desconectes (remove) o cambie de estado (change).
  • ATTRS{idProduct}=="1500"
    • Qué hace: Filtra por el modelo exacto. Revisa los atributos de hardware del dispositivo buscando que el ID de Producto sea exactamente el 1500 (que corresponde al Apple USB SuperDrive).
  • ATTRS{idVendor}=="05ac"
    • Qué hace: Filtra por la marca. Revisa que el ID de Vendedor sea 05ac, que es el código de identificación global asignado a Apple, Inc.
  • DRIVERS=="usb"
    • Qué hace: Filtra por el tipo de conexión. Asegura que el dispositivo esté utilizando el controlador (driver) del bus USB. Esto evita falsos positivos con otros tipos de conexiones internas, solo funciona si es una conexión mediante USB.

Parte 2: La Acción (El Disparador)

Si el dispositivo cumple con ser un USB de Apple con esos IDs exactos, udev pasa a ejecutar lo que está después del RUN+=

  • RUN+="/usr/bin/sg_raw ... "
    • Qué hace: El operador RUN+= le dice a Linux: "añade este comando a la lista de tareas que debes ejecutar de inmediato como usuario root". Invoca a la herramienta /usr/bin/sg_raw, que sirve para enviar comandos SCSI crudos (raw) directamente al firmware de un dispositivo de almacenamiento (como discos duros o lectoras de CD/DVD).
  • /dev/$kernel
    • Qué hace: Es una variable dinámica de udev. En el momento en que conectas la lectora, Linux le asigna un nombre temporal en el sistema (por ejemplo, sg1, sr0, etc.). udev reemplaza automáticamente $kernel por ese nombre exacto (quedando como /dev/sg1), para que el comando sepa a qué cable físico enviarle la información.
  • EA 00 00 00 00 00 01
    • Qué hace: Este es el "saludo secreto de la manzana" en formato hexadecimal. La lectora SuperDrive de Apple viene "capada" de fábrica para no encenderse ni recibir discos si no detecta que está conectada a una Mac. Este código envía una secuencia de comandos SCSI directamente al chip de la lectora que emula el chequeo que haría macOS.

En resumen:

Al conectar el lector de DVD de Apple (05ac:1500) por USB, Linux lo detecta al instante, averigua qué nombre de dispositivo le dio (por ejemplo, /dev/sg1), y le inyecta directamente a su firmware el código hexadecimal EA 00 00 00 00 00 01.
Al recibirlo, el firmware del lector se "despierta", el motor empieza a girar y queda listo para que puedas meter un DVD y usarlo normalmente en Linux.

Otros usos para los Disparadores

Imagina que tienes un servidor, pero lo tienes sin teclado, sin monitor simplemente haciendo lo que tiene que hacer, pero necesitas realizar tareas de mantenimiento en él, como por ejemplo Backups.

Puedes aprovechar udev para que cuando se detecte un disco externo, en el que por ejemplo exista un fichero determinado, por ejemplo etiqueta.disco y con un texto determinado, se inicie automáticamente el proceso de Backup.

Para lograr esto, necesitamos combinar udev con un script intermedio.

El "problema" con udev es que se dispara apenas el hardware se conecta a nivel eléctrico, pero en ese milisegundo el sistema operativo aún no ha montado el disco ni puede leer si existe el archivo etiqueta.disco.

Por lo tanto, la estrategia correcta es:

  1. udev detecta el USB y lanza un script.
  2. Ese script monta el disco temporalmente.
  3. El script busca el archivo etiqueta.disco y lee su contenido.
  4. Si el contenido coincide con tu "string especial", lanza el backup.

La solución paso a paso sería así:

1. La regla de udev

Para no limitar el backup a un solo USB específico (por si cambiamos de disco externo en el futuro), crearemos una regla genérica que se active con cualquier disco de almacenamiento masivo que se conecte por USB.

Creamos el archivo de la regla:
/etc/udev/rules.d/90-backup-auto.rules

# Auto-Backup
ACTION=="add", SUBSYSTEM=="block", ENV{ID_BUS}=="usb", RUN+="/usr/local/bin/detectar_backup.sh %k"

Nota: El %k al final es un argumento que udev le pasa al script. Le dice qué nombre de dispositivo tiene (por ejemplo, sdb1 o sdc1).

Luego hay quer recarga las reglas de udev, lo haremos con el comando:

sudo udevadm control --reload-rules

2. El script de detección y backup

Ahora creamos el script que hará la magia de montar el disco, verificar el archivo "secreto" y ejecutar el backup de nuestros datos.

Creamo el archivo en el que pondremos nuestro script:
/usr/local/bin/detectar_backup.sh

#!/bin/bash

# --- CONFIGURACIÓN ---
DISPOSITIVO="/dev/$1"
PUNTO_MONTAJE="/mnt/check_backup"
FICHERO_ETIQUETA="etiqueta.disco"
STRING_SECRETO="BACKUP_SERVIDOR_SOLOCONLINUX"
LOG_FILE="/var/log/backup_auto.log"

# Evitar que se ejecute si udev detecta el disco completo (ej. sdb) en lugar de la partición (ej. sdb1)
if [[ "$1" =~ ^sd[a-z]$ ]]; then
    exit 0
fi

echo "$(date): Dispositivo detectado: $DISPOSITIVO" >> $LOG_FILE

# 1. Crear punto de montaje temporal si no existe
mkdir -p $PUNTO_MONTAJE

# 2. Intentar montar el disco (udev corre como root, así que tiene permisos)
if mount $DISPOSITIVO $PUNTO_MONTAJE 2>> $LOG_FILE; then
    
# 3. Verificar si existe el archivo etiqueta
if [ -f "$PUNTO_MONTAJE/$FICHERO_ETIQUETA" ]; then
        CONTENT=$(cat "$PUNTO_MONTAJE/$FICHERO_ETIQUETA" | tr -d '\r\n ') # Limpia saltos de línea
        
# 4. Validar el string secreto
if [ "$CONTENT" == "$STRING_SECRETO" ]; then
            echo "$(date): ¡Etiqueta válida encontrada! Iniciando backup..." >> $LOG_FILE
            
# ------------------------------------------
# NUESTROS COMANDOS DE BACKUP ...
# Ejemplo con rsync (ajusta tus carpetas de origen):
rsync -avz /var/www /home /etc "$PUNTO_MONTAJE/backup_servidor/" >> $LOG_FILE 2>&1
# -------------------------------------------
            
echo "$(date): Backup finalizado con éxito." >> $LOG_FILE
        else
            echo "$(date): Archivo etiqueta encontrado, pero el string no coincide." >> $LOG_FILE
        fi
    else
        echo "$(date): No se encontró el archivo '$FICHERO_ETIQUETA' en la raíz." >> $LOG_FILE
    fi

    # 5. Desmontar el disco al terminar
    umount $PUNTO_MONTAJE
else
    echo "$(date): No se pudo montar $DISPOSITIVO" >> $LOG_FILE
fi

Le damos permisos de ejecución al script:

sudo chmod +x /usr/local/bin/detectar_backu

3. Preparar nuestro disco externo USB

  1. Conectamos el disco.
  2. En la raíz del disco, creamos un archivo de texto llamado etiqueta.disco.
  3. Dentro del archivo, escribe exactamente tu clave (siguiendo el ejemplo del script):
    BACKUP_SERVIDOR _SOLOCONLINUX
    (asegúrate de que no haya espacios de más).

¿Cómo probarlo?

Una vez hecho esto, puedes dejar abierta una terminal viendo el log en tiempo real con el siguiente comando:

tail -f /var/log/backup_auto.log

Conecta el USB, el script lo detecta, comprueba el archivo y, si todo coincide, arranca el proceso de respaldo de forma totalmente automatizada y segura.

Luis GuLo

🐧 SysAdmin GNU/Linux - 🐳 Docker - 🖥️ Bash Scripting - 🐪 Perl - 🐬 MySQL - 👥 Formador de TI - 👥 Formador de SysAdmin's - 💢 Ansible - ☁️ Cloud Computing - ❤️ Debian GNU/Linux