Intentas reiniciar un servicio en Debian 13 y systemd responde con el equivalente operativo de una puerta cerrada con llave: “Unit is masked.” No hay reinicio, el estado no tiene sentido y tu ventana de cambios se está evaporando en tiempo real.
El instinto es desmascararlo y seguir adelante. A veces eso está bien. Otras veces así es como reactivas accidentalmente un servicio que fue deshabilitado intencionalmente por seguridad, integridad de arranque o por precaución. El objetivo de este escrito es devolverte al verde y evitar la próxima sorpresa, porque “unit masked” rara vez es toda la historia.
Qué significa realmente “masked” (y qué no)
En términos de systemd, una unidad enmascarada es una unidad que se ha hecho deliberadamente no iniciable. No es “deshabilitada”. No es “detenida”. No iniciable. systemd implementa el enmascaramiento colocando un enlace simbólico con el nombre del archivo de unidad (o su drop-in) que apunta a /dev/null. Es un veto duro: no arranque manual, no arranque por dependencias, ninguna activación accidental.
El enmascaramiento se usa por varias razones legítimas:
- Impedir que un servicio problemático se inicie vía dependencias o sockets.
- Evitar que un servicio legado sea incorporado automáticamente por otras unidades.
- Impedir que un administrador “simplemente intente iniciarlo” en pánico.
- Sobrescribir unidades del proveedor cuando el paquete no ofrece un control limpio.
Y se usa por algunas razones ilegítimas:
- Los scripts de automatización usan
maskcomo una herramienta tosca y nunca la limpian. - Alguien enmascara una unidad durante un incidente y olvida documentarlo.
- Una imagen de nube se distribuye con servicios enmascarados para evitar sorpresas al arrancar, y luego esperas que esos servicios funcionen.
Enmascarar no es lo mismo que:
- Disabled: no se inicia al arranque, pero puede iniciarse manualmente (
systemctl startfunciona). - Static: no puede habilitarse (no hay sección
[Install]) pero puede iniciarse vía dependencias. - Failed: se inició y falló, o nunca se inició por errores en tiempo de ejecución.
- Not-found: el archivo de unidad no existe (o el generador no lo creó).
El enmascaramiento es una decisión de política. Tu trabajo es averiguar qué motivó esa decisión de política y si debe permanecer.
Guía de diagnóstico rápido (verificar primero/segundo/tercero)
Primero: confirma el estado de la unidad y dónde vive el enmascaramiento
- ¿Está enmascarada en tiempo de ejecución, o mediante un enlace persistente?
- ¿Está enmascarada en la instancia del sistema o en la del usuario?
- ¿Es la propia unidad, o un alias/plantilla/socket lo que está enmascarado?
Segundo: encuentra quién/qué pidió el enmascaramiento
- Revisa scripts de paquetes (registros de dpkg), registros de gestión de configuración e historial de shell cuando corresponda.
- Comprueba si un metapaquete o una política de preset está forzando un estado inesperado.
- Busca drop-ins que conflijan con la ruta de activación de la unidad.
Tercero: decide si es seguro desmascarar
- ¿Iniciar este servicio crea riesgo de pérdida de datos (montajes, cifrado, replicación)?
- ¿Abre escuchas de red que no quieres (por ejemplo, daemons de depuración)?
- ¿Competirá con otro servicio (dos clientes DHCP, dos servicios de sincronización de tiempo, dos firewalls)?
Solo después de eso desmascaras. “Desmascarar primero, preguntar después” es la forma de convertir un apagón sencillo en un postmortem.
Tareas prácticas: comandos, salidas, decisiones (12+)
Estos son los movimientos exactos que uso en producción. Cada tarea incluye un comando, una salida realista y la decisión que tomas a partir de ella.
Tarea 1: Reproducir el fallo y capturar el error exacto
cr0x@server:~$ sudo systemctl start fstrim.timer
Failed to start fstrim.timer: Unit fstrim.timer is masked.
Qué significa: systemd se negó antes de evaluar dependencias. Esto es a nivel de política, no de tiempo de ejecución.
Decisión: No “desmascarar y ya”. Identifica dónde está el mask y si es intencional.
Tarea 2: Revisar el estado (te dice cómo lo ve systemd)
cr0x@server:~$ systemctl status fstrim.timer
○ fstrim.timer
Loaded: masked (Reason: Unit fstrim.timer is masked.)
Active: inactive (dead)
Qué significa: “Loaded: masked” confirma que la definición de la unidad está sobrescrita a /dev/null (o máscara equivalente).
Decisión: Siguiente: localizar el enlace simbólico y determinar si es a nivel de sistema o un mask transitorio en tiempo de ejecución.
Tarea 3: Encontrar la ruta del archivo de unidad (o el hecho de que sea /dev/null)
cr0x@server:~$ systemctl show -p FragmentPath -p UnitFileState fstrim.timer
FragmentPath=/etc/systemd/system/fstrim.timer
UnitFileState=masked
Qué significa: La máscara está en /etc, no en un archivo del proveedor en /lib. Alguien (humano o automatización) hizo esto a propósito.
Decisión: Inspecciona el archivo para confirmar que es un enlace a /dev/null.
Tarea 4: Verificar el destino del enlace de la máscara
cr0x@server:~$ ls -l /etc/systemd/system/fstrim.timer
lrwxrwxrwx 1 root root 9 Dec 29 03:12 /etc/systemd/system/fstrim.timer -> /dev/null
Qué significa: Máscara clásica. Sin ambigüedad.
Decisión: Determinar quién lo creó y si realmente quieres que fstrim.timer se ejecute en esta clase de hosts (¿VMs? ¿SSD? ¿SAN thin-provisioned?).
Tarea 5: Comprobar si es un mask en tiempo de ejecución (menos común, pero sigiloso)
cr0x@server:~$ systemctl show -p FragmentPath fstrim.timer
FragmentPath=/etc/systemd/system/fstrim.timer
Qué significa: No es en tiempo de ejecución. Si fuera runtime-masked, a menudo verías el enmascaramiento bajo /run/systemd/system.
Decisión: Pasa a las pistas de auditoría: logs de dpkg, gestión de configuración o acciones humanas.
Tarea 6: Confirmar si existe la unidad del proveedor (importa al desmascarar)
cr0x@server:~$ systemctl cat fstrim.timer
# /etc/systemd/system/fstrim.timer
# (null)
Qué significa: systemd está literalmente cargando “nada” porque /dev/null es la unidad. Necesitas saber qué archivo debería usarse en su lugar.
Decisión: Revisa la unidad provista por el vendor en /lib/systemd/system y si está instalada.
Tarea 7: Localizar la unidad del proveedor y su comportamiento de instalación
cr0x@server:~$ ls -l /lib/systemd/system/fstrim.timer
-rw-r--r-- 1 root root 402 Jan 5 10:02 /lib/systemd/system/fstrim.timer
Qué significa: La unidad existe y puede restaurarse desmascarando (systemd usará la unidad del proveedor).
Decisión: Antes de desmascarar, evalúa si es necesario habilitarla, o solo iniciarla manualmente.
Tarea 8: Comprobar si la unidad estará habilitada/deshabilitada después de desmascarar (no asumas)
cr0x@server:~$ systemctl is-enabled fstrim.timer
masked
Qué significa: Está enmascarada, así que el estado de habilitación es irrelevante hasta desmascararla.
Decisión: Plan: desmascarar y luego decidir entre enable y start.
Tarea 9: Desmascarar con seguridad (solo la unidad, sin reinicios sorpresa)
cr0x@server:~$ sudo systemctl unmask fstrim.timer
Removed "/etc/systemd/system/fstrim.timer".
Qué significa: Se eliminó el enlace simbólico. Eso no significa que esté habilitada o iniciada.
Decisión: Recarga el daemon si estás cambiando archivos de unidad en lote; para un simple unmask no suele ser necesario, pero verifica el estado inmediatamente.
Tarea 10: Verificar que la unidad ahora sea cargable y ver su estado por defecto
cr0x@server:~$ systemctl show -p FragmentPath -p UnitFileState fstrim.timer
FragmentPath=/lib/systemd/system/fstrim.timer
UnitFileState=disabled
Qué significa: Ahora systemd usa la unidad del proveedor y está deshabilitada (no se iniciará al arranque).
Decisión: Decide si necesitas habilitarla. Para un timer como fstrim, casi siempre sí, pero comprueba almacenamiento y políticas primero.
Tarea 11: Habilitar (para persistencia en arranque) o iniciar (para uso inmediato)
cr0x@server:~$ sudo systemctl enable --now fstrim.timer
Created symlink '/etc/systemd/system/timers.target.wants/fstrim.timer' → '/lib/systemd/system/fstrim.timer'.
Qué significa: Se ejecutará según el horario y se ha iniciado ahora. Los timers son una clase relativamente segura para habilitar, pero verifica el comportamiento.
Decisión: Confirma que está activo y comprueba el siguiente tiempo de activación.
Tarea 12: Confirmar el horario del timer y últimas/siguientes ejecuciones
cr0x@server:~$ systemctl list-timers --all | sed -n '1,6p'
NEXT LEFT LAST PASSED UNIT ACTIVATES
Mon 2025-12-30 03:15:00 UTC 2h 11min left Mon 2025-12-29 03:15:01 UTC 21h ago fstrim.timer fstrim.service
Qué significa: Has vuelto a un horario predecible. Si “LAST” está vacío, puede que aún no haya corrido.
Decisión: Si este timer debería dispararse semanalmente pero tu equipo de almacenamiento odia DISCARD, detente aquí y coordina.
Tarea 13: Identificar si una unidad relacionada está enmascarada en su lugar (socket, path, plantilla)
cr0x@server:~$ systemctl list-unit-files | grep -E '^(ssh|ssh@|ssh\.socket)'
ssh.service enabled
ssh.socket masked
ssh@.service static
Qué significa: Podrías estar intentando iniciar un servicio que normalmente se activa por socket. Si el socket está enmascarado, la activación nunca ocurrirá.
Decisión: Decide si realmente quieres activación por socket. Desmascarar el socket puede tener implicaciones de seguridad (aparecen escuchas).
Tarea 14: Seguir la cadena de dependencias para ver quién lo arrastraría
cr0x@server:~$ systemctl list-dependencies --reverse fstrim.service | head
fstrim.service
● multi-user.target
Qué significa: Si las dependencias inversas incluyen targets de alto nivel, habilitar puede cambiar el comportamiento de arranque.
Decisión: Si se incorpora ampliamente, asegúrate de que no bloqueará el arranque (problemas de ordenamiento de almacenamiento/red).
Tarea 15: Inspeccionar logs de dpkg por scripts de paquete que podrían haber enmascarado algo
cr0x@server:~$ grep -n "mask" /var/log/dpkg.log | tail -n 5
23341:2025-12-29 03:11:52 status installed util-linux:amd64 2.40.2-1
23342:2025-12-29 03:12:03 configure util-linux:amd64 2.40.2-1 <none>
Qué significa: dpkg en sí no registra el enmascaramiento como “mask”; la mayoría de los enmascaramientos provienen de llamadas a systemctl en scripts de mantenedor o de la gestión de configuración. La ausencia de evidencia no es evidencia de ausencia.
Decisión: Si sospechas de un script de paquete, inspecciona los scripts del mantenedor en disco.
Tarea 16: Revisar scripts de mantenedor por manipulación de unidades (donde el enmascaramiento puede ocultarse)
cr0x@server:~$ dpkg -L util-linux | grep -E '/(postinst|prerm|postrm)$'
/var/lib/dpkg/info/util-linux.postinst
/var/lib/dpkg/info/util-linux.prerm
/var/lib/dpkg/info/util-linux.postrm
cr0x@server:~$ sudo grep -n "systemctl .*mask" /var/lib/dpkg/info/util-linux.postinst
Qué significa: No hay un enmascaramiento explícito en ese script (en este ejemplo). Vale la pena comprobarlo cuando aparece una máscara justo después de una actualización.
Decisión: Si los scripts están limpios, céntrate en la automatización, cloud-init y acciones humanas.
Tarea 17: Auditar quién ejecutó systemctl (lo mejor posible)
cr0x@server:~$ sudo journalctl -u systemd-logind --since "2025-12-29" | head -n 6
Dec 29 03:09:18 server systemd-logind[610]: New session 42 of user root.
Dec 29 03:09:18 server systemd-logind[610]: Removed session 41.
Dec 29 03:12:01 server systemd-logind[610]: Session 42 logged out. Waiting for processes to exit.
Qué significa: Esto no es una traza de auditoría perfecta, pero puede correlacionar sesiones con la hora en que apareció el enlace de la máscara (a partir de timestamps del sistema de archivos o diffs de backup).
Decisión: Si necesitas verdadera responsabilidad, despliega reglas de auditd para cambios en /etc/systemd/system. De lo contrario, trata esto como una pista, no como prueba concluyente.
Por qué las unidades se enmascaran en Debian 13 (razones reales)
“Está enmascarada” es el síntoma. Las causas raíz tienden a agruparse. Si aprendes las agrupaciones, dejas de sorprenderte.
1) Un humano la enmascaró para detener un bucle de arranque o un incidente
Esto es común con servicios de red (dhcpcd vs NetworkManager), servicios de almacenamiento (multipath, iscsid) y cualquier cosa que pueda detener el arranque (remote-fs.target dependencias). Enmascarar es la opción nuclear usada a las 03:00 cuando “disable” no detuvo la activación por dependencias.
2) La gestión de configuración usó mask como «off» idempotente
Algunos playbooks tratan “masked” como una versión más estricta de disabled. Eso no es incorrecto. Es solo un compromiso mayor del que muchos equipos se dan cuenta. La sorpresa llega después cuando un rol espera que la unidad se inicie y obtienes una negativa tajante.
3) Una imagen de nube o appliance se distribuyó con unidades enmascaradas
Los creadores de imágenes enmascaran servicios para evitar arranques lentos, logs ruidosos o configuraciones inseguras. Las imágenes basadas en Debian en particular pueden distribuir ciertos timers o servicios deshabilitados/enmascarados para mantener la imagen base genérica. Cuando más tarde instalas un paquete que espera que el servicio arranque, obtienes “masked” y el mantenedor del paquete recibe la culpa por la política de la imagen.
4) El proveedor enmascaró la unidad intencionalmente para forzar migración
A veces un servicio queda obsoleto y se enmascara para evitar que se inicie accidentalmente. Esto es menos común en Debian que en algunas distros de proveedor, pero ocurre en transiciones (por ejemplo, cuando un servicio es reemplazado por una versión activada por socket, o cuando un demonio antiguo es inseguro).
5) Enmascaraste la cosa equivocada (alias, sockets, plantillas)
Las unidades systemd vienen en familias: .service, .socket, .timer, .path y plantillas como foo@.service. Enmascarar uno puede hacer que toda la funcionalidad parezca muerta. He visto gente desmascarar el servicio pero dejar el socket enmascarado y luego jurar que systemd les “ignora”. No lo está. Está obedeciendo tu decisión anterior.
6) Una unidad se genera y enmascaraste el nombre generado
Algunas unidades se generan al arranque por generadores de systemd (por ejemplo, a partir de entradas de fstab). Si enmascaras un nombre de unidad generado, puedes forzarlo a estar apagado. Pero si el generador cambia el nombre (o cambias a UUIDs en lugar de rutas de dispositivo), tu máscara deja de coincidir y el montaje vuelve a arrancar. Eso no es systemd siendo “aleatorio”; eres tú fijando la política a un identificador inestable.
Una cita que mantengo mentalmente:
Werner Vogels: “Everything fails, all the time.” (idea parafraseada)
El enmascaramiento es uno de los mecanismos que usamos para hacer las fallas predecibles. Cuando es accidental, hace lo contrario.
Desmascarar con seguridad: la secuencia correcta y las trampas
Aquí está la postura segura: trata el desmascaramiento como tratarías habilitar una regla de firewall o volver a montar un sistema de archivos. Puedes hacerlo rápido, pero con consciencia.
Paso 1: Identifica exactamente qué está enmascarado
No asumas que es el .service. Podría ser el timer que debería activarlo, el socket que debería iniciarlo, o un alias que escribes por costumbre.
Paso 2: Identifica dónde se define la máscara
Si está en /etc/systemd/system, es política local. Si está en /run/systemd/system, puede ser transitorio. Si está en /lib/systemd/system (raro para masking), es política del proveedor.
Paso 3: Decide si lo quieres habilitado a largo plazo
Desmascarar solo elimina la política de “no iniciar”. No lo habilita. No ejecutes reflexivamente enable --now a menos que estés seguro de que la unidad debe ejecutarse al arranque. Para una recuperación puntual, puede bastar con unmask + start solamente.
Paso 4: Vigila el efecto “inicia otra cosa”
Desmascarar una unidad socket o path puede cambiar inmediatamente cómo se aceptan las peticiones. Desmascarar un timer puede hacer que empiece a dispararse según timers persistentes (ejecuciones perdidas). Eso es una característica, pero sorprende a la gente.
Broma corta #1: enmascarar en systemd es como poner un cartel de “NO ABRIR” en una puerta—y luego sorprenderse de que no se abra.
Paso 5: Si la unidad estaba enmascarada por una razón, arregla la razón
El enmascaramiento raramente es la verdadera solución. Es un torniquete. Aún debes tratar la herida: daemons en conflicto, configuración rota, dependencias rotas o desajuste del entorno (contenedores, chroots, imágenes mínimas).
Datos e historia interesantes que explican el comportamiento actual
- Dato 1: El enmascaramiento de systemd se implementa principalmente mediante un enlace simbólico a
/dev/null, que prevalece sobre casi cualquier otra fuente de unidades en la ruta de carga. - Dato 2: La integración de systemd en Debian se apoya fuertemente en el mecanismo de “vendor preset”: los paquetes pueden incluir estados sugeridos de habilitación, pero los administradores locales pueden anularlos.
- Dato 3: La distinción entre disabled y masked es intencional: disabled detiene la activación en arranque; masked impide cualquier activación, incluidas dependencias.
- Dato 4: El orden de búsqueda de unidades de systemd prefiere
/etc/systemd/systemsobre/runsobre/lib/systemd/system. Por eso el enmascaramiento local en/etces tan decisivo. - Dato 5: Una unidad puede ser “static” y aun así iniciarse automáticamente por dependencias; muchos administradores encuentran “static” la primera vez que intentan
enablealgo que nunca se pensó habilitar directamente. - Dato 6: Los timers reemplazaron muchos cron antiguos en distribuciones modernas, y algunas imágenes enmascaran timers para reducir la actividad en segundo plano en instancias pequeñas.
- Dato 7: La activación por socket significa que el
.socketpuede ser más importante que el.service; enmascarar el socket es efectivamente enmascarar la funcionalidad. - Dato 8: En los primeros años de adopción de systemd, “mask it” se volvió un parche común para impedir que servicios compatibles con SysV siguieran resucitando por scripts de init legacy o dependencias.
- Dato 9: El enmascaramiento es reversible sin reinstalar paquetes, por eso se usa operacionalmente durante incidentes: rápido, determinista y contundente.
Tres mini-historias corporativas desde el campo
Mini-historia 1: El apagón causado por una suposición equivocada
Una compañía minorista ejecutaba Debian en gateways de borde en tiendas. Los gateways usaban un servicio VPN con una unidad systemd. Durante una migración, un ingeniero sénior decidió “temporalmente deshabilitar la unidad VPN heredada para probar la nueva”. Usaron systemctl mask porque hacía que la unidad dejara de arrancar de inmediato y además impedía que el viejo servicio fuera incorporado por otras unidades.
La suposición: el enmascaramiento se comporta como un disable más fuerte y será eliminado más tarde por el rol de migración. La realidad: el rol de migración solo ejecutaba disable/enable, nunca unmask. Ni siquiera comprobaba el estado masked. El playbook era “correcto” en el sentido estrecho, pero ciego al martillo de política que se había usado antes.
Semanas después, un parche de seguridad requirió reiniciar el servicio VPN. El despliegue se topó primero con las unidades enmascaradas (por orden desafortunado). El sistema de orquestación interpretó “failed to start” como error fatal y paró a mitad de vuelo. Las tiendas quedaron medio actualizadas: algunos gateways tenían kernel parcheado, otros no; algunos tenían VPN y otros no.
La solución fue trivial—unmask y reiniciar. La lección no lo fue. Añadieron una comprobación previa: cualquier unidad crítica para conectividad debe ser enabled o disabled, nunca masked, salvo que la orden de cambio lo documente explícitamente. También actualizaron el rol de migración para tratar masked como un estado separado que requiere manejo intencional.
Mini-historia 2: La optimización que salió mal
Una empresa de medios quería arranques más rápidos en sus nodos de renderizado con Debian 13. Alguien detectó varias unidades esperando network-online y montajes remotos. La “optimización” rápida fue enmascarar servicios que parecían opcionales: un daemon de sincronización horaria, un timer de trim y un ayudante de montaje remoto. El arranque se volvió más rápido. Todos se felicitaron y volvieron a discutir controladores GPU.
El retroceso llegó en silencio. La granja de render ejecutaba nodos de larga vida, y sin trim periódico el rendimiento de los SSD fue decayendo lentamente. El daemon de sincronización horaria enmascarado provocó que certificados fallaran validación de forma intermitente tras reinicios con drift de reloj suficiente. El ayudante de montaje remoto enmascarado hizo que un camino de fallback escribiera caches en discos locales en vez del almacenamiento compartido.
Ninguno de estos fallos fue dramático. Fueron del peor tipo: esporádicos, entre equipos y difíciles de correlacionar. El enmascaramiento era el denominador común, pero tomó una semana notarlo porque “masked” no es un estado de fallo—es un estado de política.
Revirtieron las máscaras y luego hicieron el trabajo aburrido: arreglar dependencias de orden, reducir el uso de network-online y establecer timeouts sensatos. El arranque siguió siendo razonablemente rápido y la flota dejó de acumular deuda invisible.
Mini-historia 3: La práctica aburrida pero correcta que salvó el día
Una fintech ejecutaba Debian 13 para servicios internos. Tenían un hábito que parecía burocrático: un trabajo de auditoría diario que comparaba /etc/systemd/system contra una línea base conocida para cada rol de servidor. No era sofisticado; solo marcaba enlaces simbólicos inesperados, especialmente los que apuntaban a /dev/null.
Una mañana la auditoría se encendió: un timer de respaldo de base de datos estaba enmascarado en un puñado de hosts. Nadie había abierto un incidente. No hubo pager. Solo un diff. Investigaron antes de que los respaldos faltaran lo suficiente como para importar.
Causa raíz: un ingeniero junior ejecutó un script “temporal” de limpieza durante un evento de presión de disco. El script enmascaró varios timers para detener el churn de I/O, con la intención de desmascararlos luego. Fue llamado a otra tarea y lo olvidó. La auditoría lo encontró al día siguiente, antes de que compliance lo hiciera.
Desmascararon el timer, ejecutaron un backup bajo demanda y añadieron un runbook: si enmascaras algo como medida temporal, crea un ticket que expire y que genere pager si no se resuelve. La práctica era aburrida. Funcionó. Lo aburrido está subestimado en operaciones.
Errores comunes: síntoma → causa raíz → solución
1) “systemctl enable dice que la unidad está enmascarada”
Síntoma: Failed to enable unit: Unit file is masked
Causa raíz: Estás intentando cambiar el estado de habilitación mientras existe una anulación a /dev/null.
Solución: systemctl unmask UNIT, luego vuelve a ejecutar systemctl enable. Verifica que FragmentPath se movió fuera de /etc y hacia /lib o una anulación válida.
2) “Desmascaré el servicio pero aún no arranca”
Síntoma: Servicio desmascarado, pero la activación aún falla o nunca ocurre.
Causa raíz: La unidad disparadora está enmascarada (socket/timer/path) o la unidad es static y solo se inicia por dependencias que no estás satisfaciendo.
Solución: Revisa unidades relacionadas: systemctl list-unit-files | grep NAME. Desmascara el disparador (si procede) y valida dependencias con list-dependencies.
3) “Se enmascara otra vez después del reinicio”
Síntoma: Desmascaras, pero la unidad vuelve a estar enmascarada más tarde.
Causa raíz: Automatización (Ansible/Puppet/Salt), cloud-init o un rol de hardening reaplica la máscara.
Solución: Encuentra y elimina la política. Grepea tu repo de configuración por el nombre de la unidad y por systemctl mask. Si no puedes cambiar la automatización rápidamente, añade una anulación gestionada: hacer cumplir el estado unmasked como código.
4) “La instalación del paquete no inició el servicio”
Síntoma: Instalas un paquete y esperas que el servicio arranque; no lo hace y luego descubres que está enmascarado.
Causa raíz: La imagen del host tenía la unidad enmascarada ya, o la política de preset la deshabilitó, y el postinst del paquete respetó la política del administrador.
Solución: Confirma el preset del proveedor con systemctl preset-status (donde esté soportado) y revisa máscaras existentes en /etc/systemd/system. Decide si seguir la política de la imagen o sobreescribirla para este rol.
5) “Enmascarar para arreglar un crash”
Síntoma: Alguien enmascaró una unidad para que dejara de fallar repetidamente.
Causa raíz: El enmascaramiento se usa como sustituto de arreglar el crash o la mala configuración.
Solución: Desmascara en una ventana controlada, inspecciona logs (journalctl -u), corrige la configuración y luego vuelve a habilitar. Si debes mantenerla apagada, prefiere disable salvo que la activación por dependencias sea un riesgo.
6) “Unidades de montaje enmascaradas y rarezas de almacenamiento”
Síntoma: Los montajes de almacenamiento no ocurren; los servicios fallan esperando sistemas de archivos.
Causa raíz: Una unidad de montaje generada desde fstab fue enmascarada para evitar bloqueos, pero el problema subyacente de almacenamiento nunca se resolvió (DNS, iSCSI, multipath, credenciales).
Solución: Arregla la dependencia de almacenamiento subyacente. Usa timeouts sensatos y nofail donde corresponda. Enmascarar montajes es aceptable como medida paliativa, no como arquitectura.
Broma corta #2: Si tu “solución” es enmascarar servicios, no estás haciendo SRE—estás jugando whack-a-mole con systemd.
Listas de verificación / plan paso a paso
Lista A: Recuperación de una unidad (rápido, seguro)
- Captura el error:
systemctl start UNITy copia el mensaje exacto. - Confirma el estado:
systemctl status UNITysystemctl is-enabled UNIT. - Localiza la máscara:
systemctl show -p FragmentPath UNIT. - Verifica el enlace simbólico:
ls -l FRAGMENTPATHy confirma-> /dev/null. - Comprueba que exista la unidad del proveedor:
ls -l /lib/systemd/system/UNIT. - Decide seguridad: ¿iniciar abre puertos, monta almacenamiento, modifica discos o entra en conflicto con otro daemon?
- Desmascara:
systemctl unmask UNIT. - Verifica que FragmentPath se movió a un archivo real.
- Inicia (temporal) o enable –now (persistente), explícitamente.
- Valida: logs (
journalctl -u UNIT -b), health checks y timers/sockets si procede.
Lista B: Prevención a nivel de flota
- Inventario de máscaras: encuentra enlaces a
/dev/nullbajo/etc/systemd/system. - Clasifica: intencional (documentado) vs accidental (origen desconocido).
- Para máscaras intencionales, añade un comentario en tu gestión de configuración y una referencia de ticket en el runbook.
- Para máscaras accidentales, desmascara y arregla la causa raíz (conflictos, orden, configuraciones rotas).
- Añade controles CI para evitar nuevas máscaras en roles salvo aprobación explícita.
- Detección de deriva de la línea base: alerta sobre nuevos
/etc/systemd/system/*.service -> /dev/null.
Pack de tareas: comandos de inventario de flota (bonus, aún práctico)
cr0x@server:~$ sudo find /etc/systemd/system -maxdepth 2 -type l -lname /dev/null -printf '%p -> %l\n' | head
/etc/systemd/system/fstrim.timer -> /dev/null
/etc/systemd/system/ssh.socket -> /dev/null
Qué significa: Estas son tus máscaras. Cada línea es una decisión de política que alguien tomó.
Decisión: Para cada una, decide: mantener (documentar) o eliminar (unmask + arreglar causa raíz).
Preguntas frecuentes
1) ¿Cuál es la diferencia entre disable y mask?
disable elimina enlaces que inician la unidad al arranque. La unidad aún puede iniciarse manualmente o como dependencia. mask la hace no iniciable en cualquier escenario.
2) ¿Hace systemctl unmask que el servicio se inicie?
No. Solo elimina el veto. Aún necesitas start para activación inmediata y enable para persistencia en arranque.
3) ¿Por qué la unidad enmascarada está en /etc/systemd/system?
Porque el enmascaramiento suele ser una política de administrador local. systemd busca primero en /etc, así que las anulaciones locales ganan sobre los valores por defecto del proveedor.
4) ¿Puede una unidad estar enmascarada de una forma que no muestre un enlace en /etc?
Sí. Puede enmascararse de forma transitoria en /run/systemd/system, o puedes estar mirando un nombre de unidad diferente (alias/socket/plantilla) al que crees.
5) ¿Por qué ocurrió el enmascaramiento durante una actualización?
Más a menudo de lo que piensas, no ocurrió durante la actualización. Las actualizaciones revelan políticas existentes porque los paquetes cambian defaults, añaden timers o cambian rutas de activación. Si sospechas de scripts de mantenedor, inspecciona /var/lib/dpkg/info/*.postinst por llamadas a systemctl.
6) Si desmascaro, ¿Debian “recordará” y lo mantendrá desmascarado tras actualizaciones?
Sí, porque la máscara era un archivo en /etc. Una vez eliminado, permanece eliminado—a menos que la automatización o un rol de hardening lo recree.
7) ¿Cuál es la forma más segura de probar el desmascarado en producción?
Desmascara sin habilitar, luego inicia manualmente y observa logs. Para escuchas de red, confirma sockets/puertos antes y después. Para servicios relacionados con almacenamiento, valida montajes y dependencias antes del reinicio.
8) ¿Puedo enmascarar una unidad para evitar que se inicie indirectamente?
Sí, es un caso de uso válido. Si la activación por dependencias es el problema y disable no es lo bastante fuerte, mask es la herramienta correcta—solo documéntalo y audita la deriva.
9) ¿Por qué systemctl cat muestra “(null)”?
Porque el archivo de unidad es literalmente /dev/null. systemd te está diciendo “cargué nada, por diseño.” Esa es la máscara.
10) ¿Cómo evito enmascarar montajes y luego olvidarlo?
Trata las máscaras como mitigaciones incidentales que expiran. Crea un ticket, añade una alerta sobre enlaces de máscara y arregla el problema real (timeouts, orden, credenciales, disponibilidad de red).
Conclusión: próximos pasos que perduran
Cuando Debian 13 dice “Unit is masked”, no está siendo misterioso. Está siendo obediente. Una máscara es una anulación de política deliberada, implementada de la forma más simple posible: un enlace simbólico a ninguna parte.
Haz lo siguiente:
- Para la unidad que te afectó: captura
FragmentPath, verifica el destino del enlace y registra dónde vivía la política. - Desmascara solo después de decidir que es seguro, luego elige intencionalmente entre
startyenable --now. - Encuentra al autor: automatización, política de imagen o una reparación humana de incidente. Elimina la sorpresa en la fuente.
- Higiene de flota: audita
/etc/systemd/systemen busca de enlaces-> /dev/nully trata las máscaras no documentadas como defectos.
Si recuerdas una regla operativa: desmascarar arregla el síntoma; entender por qué se enmascaró arregla el sistema.