El ransomware normalmente no “hackea” el almacenamiento. Abusa del hecho de que tu almacenamiento está haciendo exactamente lo que se le pidió: aceptar escrituras de una identidad confiable que de repente ya no lo es. Tu servidor de archivos no distingue entre un responsable de nóminas guardando una hoja de cálculo y un malware cifrando 4 millones de documentos a línea completa. Para el disco, todo es escritura entusiasta.
ZFS te ofrece una palanca aparentemente simple: datasets en readonly. Combinado con snapshots y replicación, te permite poner partes de tu almacenamiento en una postura en la que el ransomware no puede cifrar lo que no puede escribir. Esto no es una bala de plata—nada lo es—pero es un control que puedes desplegar hoy, con comandos que puedes ejecutar en producción sin comprar nada ni reorganizar toda tu arquitectura.
Qué significa realmente readonly en ZFS (y qué no significa)
La propiedad de ZFS readonly es exactamente lo que parece: indica a ZFS montar un dataset en modo solo lectura. Cuando está activado, las escrituras a través de ese montaje deberían fallar. Eso es poderoso, pero no mágico. Es una política a nivel de almacenamiento aplicada a un dataset, no un juicio moral sobre la intención.
Readonly se aplica al dataset, no a tus intenciones
Cuando activas readonly=on en un dataset:
- Las escrituras a través del sistema de archivos montado están bloqueadas (las aplicaciones verán errores como “Read-only file system”).
- Las actualizaciones de metadatos que requieren escritura (crear archivos, renombrar, chmod, etc.) también fallan.
- Aún puedes leer, recorrer y calcular sumas de comprobación; ZFS está feliz de servir datos.
Lo que no significa:
- No protege automáticamente las instantáneas. Las snapshots tienen su propia historia de seguridad.
- No impide que un usuario privilegiado lo cambie de nuevo a
off. - No te protege de la destrucción a nivel del pool (por ejemplo,
zpool destroypor root). Por eso importa la separación de funciones. - No impide escrituras a través de una ruta diferente que evade el sistema de archivos montado (por ejemplo, si replicas un dataset hacia él, puedes estar escribiendo a nivel ZFS, no a través del montaje).
En otras palabras: readonly es un cinturón de seguridad fuerte, no un teletransportador. Te ayuda a sobrevivir choques comunes, pero aún así no deberías chocarte contra un muro.
Lo que el ransomware típicamente hace con tus archivos
El ransomware a nivel de archivo usualmente:
- Enumera directorios, a menudo usando APIs estándar, a veces con múltiples hilos.
- Lee un archivo, escribe una versión cifrada (ya sea en el mismo lugar o lado a lado), y luego renombra.
- Elimina originales o los trunca.
- Apunta a servidores de archivos vía SMB/NFS porque concentran datos compartidos y a menudo son ampliamente escribibles.
Si el dataset subyacente está en readonly, esas escrituras, truncaciones, renombrados y eliminaciones fallan. El malware todavía puede leer tus datos (la confidencialidad es un control separado), pero no puede cifrar tu dataset almacenado en el sitio. Esa es una diferencia enorme cuando intentas mantener el negocio en marcha.
Una broma, porque nos la ganamos: readonly es como poner tus datos detrás de un cristal: la gente aún puede admirarlos, pero no puede “mejorarlos” con una capa de pintura ransomware.
Por qué readonly funciona contra el ransomware
La mayoría de las guías anti-ransomware se centran en detección, controles en endpoints y backups. Todo bien. Pero la verdad operacional es: el ransomware no necesita ser ingenioso si tu almacenamiento está totalmente abierto. La inmutabilidad a nivel de almacenamiento cambia las reglas al hacer imposible (o al menos mucho más difícil) el paso de “cifrar y sobrescribir”.
Readonly reduce tu radio de impacto
En producción, los datos rara vez son homogéneos. Tienes:
- Conjuntos activos de trabajo (necesitan escrituras frecuentes).
- Datos de referencia (rara vez cambian, se leen mucho).
- Archivos (deberían permanecer sin cambios).
- Objetivos de backup/replica (deberían ser “write-once” en la práctica).
Readonly encaja perfectamente con datos de referencia, archivos y objetivos de réplica. Si el ransomware llega a una estación de trabajo o a una cuenta de servidor con acceso amplio, solo puede dañar datasets que sean realmente escribibles.
Readonly es inmediato, barato y observable
Los controles de seguridad que requieren un proyecto largo tienden a perder frente a “prioridades de negocio urgentes”. ZFS readonly no es uno de esos controles. Puedes:
- Activarlo con un solo cambio de propiedad.
- Confirmarlo con
zfs gety con el comportamiento real de las aplicaciones. - Monitorizar intentos de escritura (las aplicaciones registrarán errores; los clientes SMB/NFS se quejarán).
Esa observabilidad importa. En varios incidentes que he visto desarrollarse, la primera pista contundente fue “¿por qué este directorio de repente está en solo lectura?” No estaba en solo lectura. El sistema intentaba escribir basura a alta velocidad y chocaba con barreras. Esas barreras convirtieron una catástrofe en una molestia ruidosa.
Readonly funciona bien con snapshots—y las snapshots son las que realmente usarás
Readonly es un control preventivo. Las snapshots son tu control de recuperación. Juntos, te permiten decir:
- “Este dataset no debería cambiar.” (readonly)
- “Si algo cambia que no debería, puedo revertir o restaurar rápidamente.” (snapshots + replicación)
Si solo haces snapshots, el ransomware aún puede cifrar el sistema de archivos en vivo y estarás en modo restauración. Si solo haces readonly, podrías bloquear cambios legítimos del negocio. El punto óptimo es diseñar tu layout de datasets para ser estricto donde es seguro y flexible donde se necesita.
Hechos interesantes y contexto histórico
La ingeniería de almacenamiento tiene memoria larga. Algunos puntos de contexto que hacen que ZFS readonly se sienta menos como un truco y más como la forma moderna de ideas antiguas:
- ZFS empezó a principios de los 2000 en Sun Microsystems, construido alrededor de la idea de que el sistema de archivos y el gestor de volúmenes deberían ser un solo sistema, no dos compañeros incómodos.
- Copy-on-write (CoW) es la superpotencia de ZFS: los datos no se sobrescriben en su sitio; se escriben nuevos bloques y se actualizan punteros. Esto hace que las snapshots sean baratas y consistentes.
- Las snapshots preceden al ransomware como amenaza generalizada. Fueron diseñadas para errores administrativos y consistencia, pero encajan magníficamente con la recuperación por reversión.
- La “inmutabilidad” no es nueva: el almacenamiento WORM (write once, read many) se ha vendido durante décadas para archivos de cumplimiento. ZFS readonly es una aproximación práctica para muchos datasets.
- El ransomware moderno evolucionó desde “bloqueadores de pantalla” hacia extorsión por cifrado cuando la criptografía se hizo más fácil de operacionalizar y las copias de seguridad se volvieron más comunes.
- Las comparticiones SMB se convirtieron en objetivos de alto valor porque concentran datos compartidos y heredan permisos amplios—un usuario comprometido puede tocar mucho.
- Los primeros adoptantes de ZFS aprendieron a la fuerza que “existen snapshots” no es lo mismo que “las snapshots son seguras”. Si un atacante puede destruir snapshots, vuelves al punto cero.
- La separación operativa de funciones es anterior a las computadoras: la persona que aprueba gastos no debería ser la que transfiere fondos. La misma lógica se aplica a quién puede borrar snapshots o cambiar readonly.
- “Backups offline” solían significar cintas. Hoy a menudo significa “una réplica que no puedes modificar desde el plano de identidad de producción”. Los datasets readonly son una pieza de ese rompecabezas.
Segunda broma (y la última): el ransomware es la única carga de trabajo que he visto que escala perfectamente sin una revisión de desempeño.
Patrones de diseño: dónde encaja readonly en almacenamiento real
Readonly es más efectivo cuando tus datasets reflejan la realidad: qué cambia, qué no debería cambiar y qué debe ser recuperable rápido. No esparces readonly como condimento; construyes límites.
Patrón 1: Separar datos “activos” y “publicados”
Común en pipelines de análisis y contenido:
- Dataset de ingest activo: escribible, usado por trabajos ETL o cargas.
- Dataset publicado: readonly, usado por lectores (herramientas BI, servidores web, equipos downstream).
La promoción es una acción controlada: una snapshot o clone se mueve al namespace publicado y luego se bloquea en readonly. Si ransomware impacta un nodo de ingest, puede estropear el ingest, pero lo publicado permanece intacto.
Patrón 2: Réplicas readonly como “air gap del pobre”
Configura un host de backup/DR que reciba replicación ZFS. En el lado receptor, mantiene los datasets montados en readonly (o directamente no montados) y restringe quién puede cambiar propiedades. El objetivo se convierte en “online pero no fácilmente escribible”, que suele ser el punto óptimo operativo.
La clave es la separación de identidades: los sistemas de producción no deberían tener credenciales que puedan reescribir el destino de backup más allá de la capacidad estrecha de replicación. Si la misma clave root SSH puede administrar ambos extremos, has construido un mecanismo de autodestrucción de alta velocidad.
Patrón 3: Directorios home inmutables (con cuidado)
Para algunos entornos—kioscos, laboratorios, centros de llamadas—los datos de usuario no están destinados a persistir o cambiar fuera de una sincronización controlada. Puedes montar directorios home desde un dataset readonly y superponer una capa escribible en otro lugar. Esto bloquea toda una categoría de ataques “cifrar todo lo que veo”.
Pero sé honesto: para trabajadores del conocimiento, los home son datos activos. No conviertas readonly en un denial-of-service de productividad.
Patrón 4: Protege tus restauraciones “conocidas buenas”
La mayoría de las organizaciones tiene un directorio como /srv/releases, /srv/installers, /srv/golden, o “la cosa desde la que reinstalamos cuando el mundo se acaba”. Hazlo un dataset separado. Ponlo readonly. Hazle snapshots. Replica. Si llega el ransomware y no puedes reinstalar de forma segura, descubrirás nuevas definiciones de “mal día”.
Chequeo de modelo de amenaza
Readonly ayuda mayormente contra:
- Cuentas de usuario comprometidas con acceso a comparticiones de archivos.
- Malware ejecutándose en servidores de aplicación que escriben en datasets compartidos.
- Scripts destructivos accidentales (sí, esos cuentan).
Readonly ayuda menos contra:
- Compromiso de root en el propio servidor de almacenamiento.
- Atacantes con derechos administrativos de ZFS que pueden cambiar propiedades o destruir snapshots.
- Acceso físico y manipulación maliciosa a nivel de kernel.
Eso no es una razón para descartarlo. Es una razón para emparejarlo con separación de funciones, protección de snapshots y un objetivo de replicación que no esté gobernado por el mismo conjunto de claves.
Tareas prácticas (comandos + interpretación)
Todos los comandos abajo asumen OpenZFS en Linux con un pool típico llamado tank. Ajusta nombres a tu entorno. El punto no es la cadena exacta; es la intención operativa y cómo se ve “bien”.
Tarea 1: Inventariar datasets y detectar candidatos obvios para readonly
cr0x@server:~$ sudo zfs list -o name,used,avail,refer,mountpoint
NAME USED AVAIL REFER MOUNTPOINT
tank 3.41T 5.22T 192K /tank
tank/home 610G 5.22T 610G /home
tank/projects 1.20T 5.22T 1.20T /srv/projects
tank/releases 42G 5.22T 42G /srv/releases
tank/backup-recv 1.55T 5.22T 1.55T /srv/backup-recv
Interpretación: tank/releases y tank/backup-recv son candidatos inmediatos para readonly. tank/home y tank/projects probablemente son activos y necesitan otra estrategia (snapshots + cuotas + permisos + quizá separación published/active).
Tarea 2: Comprobar el estado actual de readonly en todo el pool
cr0x@server:~$ sudo zfs get -r -o name,property,value,source readonly tank
NAME PROPERTY VALUE SOURCE
tank readonly off default
tank/home readonly off default
tank/projects readonly off default
tank/releases readonly off default
tank/backup-recv readonly off default
Interpretación: Todo es escribible. Eso es normal en el día cero, y exactamente por eso el ransomware se divierte en servidores de archivos.
Tarea 3: Poner un dataset en readonly
cr0x@server:~$ sudo zfs set readonly=on tank/releases
cr0x@server:~$ sudo zfs get -o name,property,value,source readonly tank/releases
NAME PROPERTY VALUE SOURCE
tank/releases readonly on local
Interpretación: La propiedad ahora está establecida localmente. Los procesos existentes que asumían que podían escribir en /srv/releases empezarán a fallar, que es el punto—pero aún debes coordinar el cambio.
Tarea 4: Confirmar el comportamiento con un intento real de escritura
cr0x@server:~$ sudo touch /srv/releases/should-fail
touch: cannot touch '/srv/releases/should-fail': Read-only file system
Interpretación: Este es el modo de fallo que deseas durante un intento de cifrado: ruidoso, inmediato y no “sobrescribió con éxito tus datos”.
Tarea 5: Hacer operativo y seguro el “permitir escrituras temporalmente”
Readonly no es algo de poner y olvidar si a veces actualizas legítimamente el dataset. El truco es crear un procedimiento repetible de “ventana de mantenimiento” que deje evidencia.
cr0x@server:~$ sudo zfs snapshot tank/releases@before-maint-2025-12-24
cr0x@server:~$ sudo zfs set readonly=off tank/releases
cr0x@server:~$ sudo rsync -a --delete /staging/releases/ /srv/releases/
cr0x@server:~$ sudo zfs set readonly=on tank/releases
cr0x@server:~$ sudo zfs snapshot tank/releases@after-maint-2025-12-24
Interpretación: Has creado dos puntos de restauración claros. Si el host de mantenimiento estaba comprometido, puedes revertir a @before-maint o inspeccionar diferencias entre snapshots.
Tarea 6: Apretar el comportamiento de snapshots con un hold (“pinning” de snapshot)
Una snapshot puede ser destruida por un atacante con privilegios suficientes. ZFS provee “holds” para prevenir la eliminación hasta que se libere el hold.
cr0x@server:~$ sudo zfs snapshot tank/releases@golden
cr0x@server:~$ sudo zfs hold keep tank/releases@golden
cr0x@server:~$ sudo zfs holds tank/releases@golden
NAME TAG TIMESTAMP
tank/releases@golden keep Wed Dec 24 10:02 2025
Interpretación: Incluso si alguien ejecuta zfs destroy tank/releases@golden, no funcionará hasta que se libere el hold. Esto no es protección absoluta contra root en el host de almacenamiento, pero eleva el esfuerzo y previene borrados accidentales.
Tarea 7: Construir un objetivo de replicación que por defecto sea readonly
En un host receptor de backup, puedes hacer cumplir una política: los datos llegan vía zfs receive, pero la vista montada es readonly.
cr0x@backup:~$ sudo zfs create -o mountpoint=/srv/backup-recv tank/backup-recv
cr0x@backup:~$ sudo zfs set readonly=on tank/backup-recv
cr0x@backup:~$ sudo zfs get -o name,property,value tank/backup-recv
NAME PROPERTY VALUE
tank/backup-recv readonly on
Interpretación: Esto protege contra “alguien montó los backups y luego escribió en ellos”. No impide recibir replicación, que escribe a nivel dataset, no a través de escrituras POSIX de archivos.
Tarea 8: Replicar snapshots (send/receive) de una forma realmente recuperable
cr0x@prod:~$ sudo zfs snapshot tank/projects@replica-001
cr0x@prod:~$ sudo zfs send -w tank/projects@replica-001 | ssh backup sudo zfs receive -u tank/backup-recv/projects
Interpretación: -u recibe sin montar, lo cual es higiene de seguridad subestimada. Las copias de seguridad desmontadas no pueden ser navegadas o modificadas casualmente por procesos aleatorios, y no se convierten en parte de tu namespace cotidiano.
Tarea 9: Verificar replicación y marcar el dataset recibido como readonly
cr0x@backup:~$ sudo zfs list -t snapshot tank/backup-recv/projects | tail -n 3
NAME USED AVAIL REFER MOUNTPOINT
tank/backup-recv/projects@replica-001 0B - 1.20T -
cr0x@backup:~$ sudo zfs set readonly=on tank/backup-recv/projects
cr0x@backup:~$ sudo zfs get readonly,mounted,mountpoint tank/backup-recv/projects
NAME PROPERTY VALUE SOURCE
tank/backup-recv/projects readonly on local
tank/backup-recv/projects mounted no -
tank/backup-recv/projects mountpoint /tank/backup-recv/projects default
Interpretación: Ahora tienes un dataset réplica que ni siquiera está montado y está marcado readonly. Este es el tipo de postura aburrida que frustra a los atacantes y deleita a los auditores.
Tarea 10: Revertir rápido tras un evento de cifrado (cuando estés seguro)
El rollback es una motosierra. También es la forma más rápida de volver a “operativo”, por eso la gente la usa en incidentes. Úsala con cuidado.
cr0x@server:~$ sudo zfs list -t snapshot -o name,creation tank/projects | tail -n 5
tank/projects@hourly-2025-12-24-08:00 Wed Dec 24 08:00 2025
tank/projects@hourly-2025-12-24-09:00 Wed Dec 24 09:00 2025
tank/projects@hourly-2025-12-24-10:00 Wed Dec 24 10:00 2025
tank/projects@hourly-2025-12-24-11:00 Wed Dec 24 11:00 2025
tank/projects@hourly-2025-12-24-12:00 Wed Dec 24 12:00 2025
cr0x@server:~$ sudo zfs rollback -r tank/projects@hourly-2025-12-24-10:00
Interpretación: Esto revierte el dataset al estado de la snapshot, y -r también revertirá clones/snapshots dependientes según sea necesario. Solo deberías hacerlo cuando hayas confirmado el alcance del compromiso y aceptes perder cambios posteriores a esa snapshot.
Tarea 11: Si el rollback es demasiado destructivo, monta una snapshot en solo lectura y copia
cr0x@server:~$ sudo mkdir -p /mnt/projects-restore
cr0x@server:~$ sudo mount -t zfs tank/projects@hourly-2025-12-24-10:00 /mnt/projects-restore
cr0x@server:~$ sudo rsync -a /mnt/projects-restore/ /srv/projects/
cr0x@server:~$ sudo umount /mnt/projects-restore
Interpretación: Esto es más lento pero más seguro para restauraciones parciales e investigación. Puedes restaurar selectivamente sin rebobinar toda la línea de tiempo del dataset.
Tarea 12: Detectar presión de escritura sospechosa con métricas ZFS y del SO
cr0x@server:~$ sudo zpool iostat -v tank 1 5
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 3.41T 5.22T 220 4100 25.3M 620M
raidz2 3.41T 5.22T 220 4100 25.3M 620M
sda - - 40 690 4.3M 102M
sdb - - 42 710 4.5M 104M
sdc - - 46 680 4.8M 101M
sdd - - 45 705 4.7M 105M
Interpretación: Un pico repentino de escrituras con muchas operaciones pequeñas es consistente con reescritura masiva de archivos/cifrado. No es prueba, pero es motivo para revisar logs SMB, listas de procesos y la rotación reciente de archivos.
Tarea 13: Auditar quién puede cambiar propiedades ZFS (delegación)
Si tu modelo operativo lo permite, delega derechos ZFS limitados en lugar de dar acceso root amplio.
cr0x@server:~$ sudo zfs allow tank/releases
---- Permissions on tank/releases ---------------------------------------
Local+Descendent permissions:
user backupop create,mount,snapshot,send,receive
Interpretación: La delegación puede mantener funcional a un operador de backups sin darle las llaves para destruir tu mundo. Si todos son root, readonly es un tope de velocidad, no una barrera.
Tarea 14: Hacer que readonly se herede para todo un subárbol
cr0x@server:~$ sudo zfs set readonly=on tank/archive
cr0x@server:~$ sudo zfs create tank/archive/2024
cr0x@server:~$ sudo zfs get readonly tank/archive/2024
NAME PROPERTY VALUE SOURCE
tank/archive/2024 readonly on inherited from tank/archive
Interpretación: La herencia es cómo evitas “olvidamos bloquear el nuevo dataset”. En producción, el enemigo a menudo no es la malicia—es la deriva.
Tarea 15: Confirmar comportamiento visible por el cliente sobre NFS/SMB (sanity rápida)
Desde el lado del servidor puedes validar las flags de montaje. La salida exacta varía por distro y configuración.
cr0x@server:~$ mount | grep '/srv/releases'
tank/releases on /srv/releases type zfs (ro,xattr,posixacl)
Interpretación: Quieres ver ro. Si dice rw, no has logrado readonly a nivel de montaje, independientemente de lo que creas haber establecido.
Tres microhistorias del mundo corporativo
Microhistoria 1: El incidente causado por una suposición errónea
La empresa tenía una teoría ordenada: “El NAS es seguro porque solo el servidor de archivos puede escribir en él.” Y en el pizarrón, era cierto. El servidor de archivos exportaba shares SMB, los usuarios montaban unidades y el backend de almacenamiento era “interno”. A la gente le encanta la palabra interno. Suena como una puerta cerrada. Usualmente es una cortina.
Una mañana de lunes, un administrador junior informó que una compartición de proyecto estaba “actuando raro”. Los archivos no se abrían. El helpdesk notó una ola de tickets: archivos Excel no cargaban, PDFs mostraban errores y “hay un archivo nuevo en cada carpeta con instrucciones”. El ritmo normal de incidentes se puso en marcha—contención, comunicación, triage. Entonces alguien hizo la pregunta que nadie quiere hacer: “¿Están bien las copias de seguridad?”
Existían backups. También estaban montados en modo lectura-escritura en el mismo servidor de archivos porque “es más fácil restaurar”. Al malware no le importa “más fácil de restaurar”. Le importa “más fácil de destruir”. El ransomware había llegado a una estación de trabajo, capturó la sesión del usuario, se movió lateralmente con credenciales en caché y usó SMB como estaba diseñado: una API de archivos rápida y autenticada. Cifró la compartición, luego alegremente entró en la ruta de backup montada y hizo lo mismo.
La suposición equivocada no era “tenemos backups”. Era “los backups están seguros porque son backups”. Las copias de seguridad solo son seguras cuando son más difíciles de cambiar que los datos de producción. Tras la autopsia (del tipo que lee como una novela de horror), reconstruyeron el objetivo de backup como réplicas ZFS recibidas en datasets desmontados y marcados readonly. La restauración quedó algo menos cómoda. La supervivencia se volvió dramáticamente más cómoda.
La lección operativa: si tu camino de backup es escribible desde el mismo plano de identidades que la producción, no tienes backups—tienes copias adicionales de tu fallo.
Microhistoria 2: La optimización que salió mal
Un equipo de infraestructura quiso mejorar el rendimiento para una carga de medios grande. Reorganizaron datasets para reducir “overhead”, consolidando muchos datasets pequeños en uno gigante con ACLs amplias. La idea era simple: menos puntos de montaje, menos dolores de cabeza, mejor rendimiento. También desactivaron algunos horarios de snapshots “ruidosos” porque las snapshots “ocupaban demasiado espacio”. Las gráficas se vieron mejor. El equipo se fue a casa sintiéndose ganador.
Tres meses después, les golpeó un script destructivo, ni siquiera ransomware: un trabajo de pipeline con una variable de ruta usada erróneamente que resolvía a la raíz de la share. Empezó a limpiar “archivos antiguos”. Limpió casi todo. El equipo buscó snapshots y encontró… no mucho. El diseño de dataset consolidado significó que no había límites naturales. La cuenta de servicio del pipeline tenía derechos en todas partes porque “necesita acceder a medios”. Con menos datasets, había menos lugares para aplicar políticas distintas, y con menos snapshots, había menos puntos de restauración.
El fallo no fue que la consolidación siempre sea mala. El fallo fue que la consolidación eliminó puntos de control. Las propiedades ZFS—readonly, horarios de snapshot, cuotas, reservas—operan en límites de dataset. Si todo es un dataset, todo comparte el mismo destino. En la práctica, así es como “una optimización” se convierte en “un único punto de fallo”.
Revirtieron la decisión: el ingest activo permaneció escribible, los medios publicados se convirtieron en un dataset readonly separado, y las cuentas de servicio del pipeline obtuvieron acceso acotado a donde debían escribir. Los horarios de snapshot volvieron con retención ajustada a la realidad del negocio. El rendimiento siguió bien. La recuperación volvió a ser sensata.
La lección operativa: el layout de datos es el layout de seguridad. Si quitas límites para simplificar, también quitas lugares para aplicar salvaguardas.
Microhistoria 3: La práctica aburrida pero correcta que salvó el día
Una organización con fuerte carga financiera tenía una costumbre casi pintoresca: cada cierre de mes, “sellaban” el dataset del mes anterior. Era un dataset ZFS separado por periodo contable, con un nombre predecible y una checklist de runbook. Tras el cierre, el dataset se marcaba readonly, se snapshoteba y se replicaba a un sistema secundario. El equipo lo hacía como un reloj, incluso cuando nadie miraba.
Entonces llegó el incidente. Una cuenta de estación de trabajo comprometida empezó a cifrar una amplia gama de carpetas compartidas. Fue rápido, agresivo y—como la mayoría de los ransomware—indiferente a los calendarios de negocio. El servidor de archivos se encendió. La monitorización mostró una subida pronunciada de IOPS de escritura y latencia. Los usuarios reportaron errores de acceso a archivos. El comandante de incidentes empezó la danza familiar: aislar endpoints, deshabilitar cuentas, bloquear sesiones SMB, preservar evidencia.
Cuando el polvo se asentó, la mala noticia fue real: varios datasets activos estaban parcialmente cifrados. La buena noticia fue quirúrgica: todos los datasets sellados de cierre de mes estaban intactos. No porque los atacantes fueran educados, sino porque esos datasets eran readonly y el malware no pudo sobrescribirlos. Los datos del cierre de mes—lo que desencadenaría caos regulatorio si se perdiera—estaban intactos e inmediatamente utilizables. Aún tenían un lío, pero fue un lío acotado.
La recuperación se convirtió en una operación a dos velocidades: restaurar áreas de trabajo activas desde snapshots y réplicas, mientras se seguía operando usando los datasets sellados para informes y cumplimiento. La organización no “evitó” el incidente. Evitó la falla existencial.
La lección operativa: las rutinas aburridas son las que te salvan. No porque sean excitantes, sino porque son repetibles bajo estrés.
Guía rápida de diagnóstico
Cuando algo se siente mal—picos de latencia, usuarios reportan extensiones raras de archivos, fallos de escritura—los mejores equipos no debaten teoría. Ejecutan una breve guía que estrecha posibilidades rápido. Aquí hay una que funciona bien para servicios de archivos respaldados por ZFS.
Primero: confirma si ves presión de escritura, churn de metadatos o enforcement de readonly
- Revisa I/O del pool: ¿son mayormente escrituras? ¿Las ops son pequeñas y numerosas?
cr0x@server:~$ sudo zpool iostat -v tank 1 3
Interpretación: Operaciones masivas de escritura + alto ancho de banda sugieren sobrescritura/cifrado o copia a granel. Muchas ops con bajo ancho pueden ser churn de metadatos (tormentas de renombrado, archivos pequeños).
- Comprueba si los datasets objetivo están readonly como esperas (y si es heredado o local):
cr0x@server:~$ sudo zfs get -r -o name,property,value,source readonly tank/projects tank/releases
Interpretación: Si un dataset “protegido” muestra readonly=off con local cuando esperabas inherited o on, puede haber deriva o un cambio durante mantenimiento.
- Comprueba flags de montaje para asegurar que el SO respeta readonly:
cr0x@server:~$ mount | egrep '/srv/releases|/srv/backup-recv'
Interpretación: Debes ver ro para datasets readonly. Si no, trátalo como “no protegido”.
Segundo: identifica el dataset y el cliente responsable (o al menos correlacionado)
- Encuentra qué dataset está caliente:
cr0x@server:~$ sudo zfs list -o name,used,refer,quota,reservation,mountpoint -S used | head
Interpretación: Crecimiento rápido puede indicar cifrado que produce nuevos archivos, o un job que vuelca datos inesperadamente.
- Revisa estadísticas I/O por dataset (Linux):
cr0x@server:~$ sudo zpool iostat -r -w tank 1 5
Interpretación: Busca ancho de escritura sostenido inconsistente con patrones normales del negocio.
- Correlaciona con sesiones SMB/NFS (ejemplos; tus comandos variarán):
cr0x@server:~$ sudo smbstatus -p | head
PID Username Group Machine Protocol Version Encryption Signing
4123 jdoe domain users 10.10.14.27 (ipv4:10.10.14.27:51234) SMB3_11 - partial
Interpretación: Un número reducido de clientes causando mucho daño es común. Si ves una estación que no debería tocar una share, eso es una pista.
Tercero: decide si estás en modo “incidente de seguridad” o “bug de rendimiento”
Los síntomas se solapan. El cifrado parece un problema de rendimiento al principio. Los bugs de rendimiento a veces parecen ransomware (alto IOPS, muchas operaciones de archivo). La diferencia es si el contenido de los datos está cambiando inesperadamente y si los intentos de escritura fallan por enforcement de readonly.
Diferenciadores rápidos:
- Errores de readonly en logs de aplicaciones y reportes de usuarios: sugiere que las barreras están deteniendo escrituras (bueno) o que bloqueaste accidentalmente un dataset activo (malo).
- Nuevas extensiones / notas de rescate: incidente de seguridad.
- Un job u host correlaciona exactamente: aún puede ser seguridad, pero puede ser un proceso batch descontrolado.
- Picos de latencia más picos de CPU en endpoints: frecuentemente cifrado.
En cualquier caso, quieres la misma primera acción de contención para comparticiones de archivos: restringir acceso de escritura, aislar clientes sospechosos y preservar snapshots antes de tocar nada.
Errores comunes (síntomas + soluciones)
Error 1: “Readonly en el dataset significa que las snapshots están seguras”
Síntoma: Activaste readonly=on, te sentiste orgulloso, y luego descubriste que las snapshots faltan tras un incidente.
Por qué sucede: La eliminación de snapshots no está bloqueada por el readonly del dataset. Si un atacante tiene acceso administrativo a ZFS, puede destruir snapshots o cambiar propiedades.
Solución: Usa holds de snapshot para puntos clave de restauración, restringe derechos administrativos de ZFS y replica a un destino donde las credenciales del atacante no existan.
Error 2: Activar readonly en un dataset que contiene estado de aplicación activo
Síntoma: Las aplicaciones empiezan a fallar con “Read-only file system”, bases de datos se niegan a arrancar, pipelines CI se rompen.
Por qué sucede: Alguien aplicó un control de seguridad sin mapear los flujos de datos.
Solución: Separa datasets: coloca el estado mutable de la app en un dataset escribible; publica artefactos en un dataset readonly separado. Si debes mantener un solo dataset, no uses readonly—usa snapshots y permisos en su lugar.
Error 3: Asumir que readonly se propaga a todas partes sin comprobar herencia
Síntoma: Un dataset recién creado bajo un árbol protegido es escribible.
Por qué sucede: Fue creado en otro lugar y movido, o alguien puso readonly=off localmente en un dataset hijo, sobreescribiendo la herencia.
Solución: Audita con zfs get -r readonly y presta atención a source. Para árboles importantes, aplica estándares vía runbooks y revisiones.
Error 4: Réplicas de backup montadas que son navegables (y escribibles) desde identidades de producción
Síntoma: Las copias de seguridad se cifran junto con la producción.
Por qué sucede: Conveniencia: los administradores montan datasets de backup para que las restauraciones sean una simple copia de archivos. Al malware le encanta la conveniencia.
Solución: Recibe réplicas con zfs receive -u, mantenlas desmontadas por defecto y provee restauraciones vía flujos controlados de mount/clone.
Error 5: “Simplemente desactivaremos readonly durante despliegues” sin un proceso
Síntoma: Readonly queda desactivado tras un cambio apresurado, y nadie se da cuenta hasta después.
Por qué sucede: Los humanos son malos recordando volver a cerrar puertas en medio de incendios.
Solución: Usa un procedimiento de mantenimiento scriptado que snapshotee antes/después y vuelva a poner readonly. Audita la deriva de propiedades regularmente.
Error 6: Confundir permisos de sistema de archivos con ZFS readonly
Síntoma: Un usuario aún puede modificar archivos aunque “lo bloqueamos”, o escrituras legítimas fallan inesperadamente.
Por qué sucede: Permisos POSIX/ACLs y ZFS readonly son capas distintas. Una controla quién puede escribir; la otra controla si cualquiera puede escribir.
Solución: Usa permisos para control de acceso normal, y readonly para objetivos de inmutabilidad y reducción de radio de impacto. No trates de sustituir una capa con la otra.
Error 7: Ignorar escrituras por canales secundarios (directorios temporales, logs, metadatos)
Síntoma: Una aplicación “solo lee”, pero aún falla en un dataset readonly.
Por qué sucede: Muchos “lectores” escriben caches, archivos de bloqueo, archivos temporales o actualizan marcas de tiempo en su lugar.
Solución: Redirige caches y rutas temporales a una ubicación escribible. Para servicios, define dirs de cache explícitos y asegura que los logs vayan a otro sitio.
Listas de verificación / plan paso a paso
Paso a paso: Desplegar readonly de forma segura en producción (sin romper todo)
- Clasifica datasets por comportamiento: escritura-activa, publicado-lectura, archivo, objetivo de backup.
- Separa datasets donde los límites no estén claros: no luches contra la realidad; crea puntos de control.
- Elige un dataset de bajo riesgo (p. ej., releases, instaladores, archivos) y haz una prueba piloto con readonly.
- Snapshot antes del cambio para que el rollback sea trivial.
- Activa readonly y valida en tres capas: propiedad ZFS, flags de montaje y comportamiento cliente.
- Actualiza runbooks: cómo hacer escrituras planificadas (modo mantenimiento), quién aprueba y cómo volver a bloquear.
- Define expectativas de monitorización: fallos de escritura deben alertar, pero no despertar a toda la empresa.
- Añade holds a snapshots para puntos críticos de restauración cuando sea apropiado.
- Construye un objetivo réplica que reciba snapshots desmontados; márcalo readonly donde sea posible.
- Restringe quién puede cambiar readonly y quién puede destruir snapshots; usa delegación si encaja en tu organización.
- Prueba restauraciones trimestralmente: monta una snapshot, copia o clona y verifica que las aplicaciones pueden leerla.
- Audita deriva mensualmente: readonly, estado de montaje, presencia de snapshots, frescura de replicación.
Checklist operativa: “Sellar” un dataset tras su publicación
- Crear una snapshot nombrada para el evento/hora.
- Verificar que los consumidores leen desde el punto de montaje correcto.
- Establecer
readonly=on. - Hacer hold de la snapshot de sellado si es un punto clave de restauración.
- Replicar a backup/DR.
- Registrar el nombre de snapshot y el estado de replicación en tu ticket o log de cambios.
Checklist operativa: Sospecha de ransomware en comparticiones de archivos
- Contener: cortar acceso SMB/NFS para clientes sospechosos; deshabilitar cuentas sospechosas.
- Preservar: tomar snapshots inmediatas de datasets afectados (sí, incluso si están parcialmente cifrados).
- Evaluar: identificar la snapshot “buena” más temprana; verificar integridad de snapshot y estado de replicación.
- Decidir: rollback vs restauración selectiva. El rollback es rápido; la restauración selectiva es más segura para recuperación parcial.
- Recuperar: restaurar datos; rotar credenciales; validar endpoints; reactivar accesos por etapas.
- Endurecer: mover datos de referencia y archivos a datasets readonly; reforzar postura de inmutabilidad de backups.
Preguntas frecuentes (FAQ)
1) ¿ZFS readonly es lo mismo que “almacenamiento inmutable”?
No. Es un bloqueo fuerte a nivel de sistema de archivos para un dataset, pero un actor con privilegios suficientes aún puede cambiar propiedades o destruir datasets/snapshots. La verdadera inmutabilidad requiere separación más fuerte (dominios administrativos distintos, medios offline o controles de gobernanza). Readonly sigue siendo extremadamente útil porque muchos eventos de ransomware operan con permisos a nivel de usuario o servicio, no con poder administrativo de almacenamiento.
2) Si pongo un dataset en readonly, ¿puedo aún replicar en él con zfs receive?
Generalmente sí. zfs receive opera a nivel ZFS, no a través del path montado del sistema de archivos. Readonly bloquea escrituras normales de archivos vía el montaje; no bloquea necesariamente actualizaciones administrativas del dataset como recibir un stream. Prueba esto en tu entorno y trata los permisos de replicación como una capacidad privilegiada.
3) ¿Readonly me protegerá si el servidor de almacenamiento está comprometido?
No de forma fiable. Si un atacante tiene root y capacidad administrativa de ZFS en el host de almacenamiento, a menudo puede volver a poner readonly en off y destruir snapshots. Tu protección entonces depende de controles fuera de ese host: destinos de backup separados, separación de acceso y posiblemente copias offline.
4) ¿Debería poner todo mi pool en readonly?
No. Esa es una excelente forma de descubrir cuántas aplicaciones escriben más de lo que pensabas, generalmente en horas punta. El valor viene de hacer readonly en datasets específicos: archivos, artefactos publicados, periodos sellados de reporting y objetivos de réplica.
5) ¿Cómo manejo actualizaciones legítimas a un dataset readonly?
Crea un procedimiento de mantenimiento: snapshot, temporalmente set readonly off, efectuar escrituras controladas, set readonly on, snapshot de nuevo. La clave es repetibilidad y auditabilidad, no heroísmos.
6) ¿Cuál es la diferencia entre readonly y poner permisos/ACLs que deniegan escrituras?
Los permisos responden “quién puede escribir”. Readonly responde “puede cualquiera escribir”. Los permisos son para operación normal. Readonly es para garantías de inmutabilidad y reducción del radio de impacto. Usa ambos, pero no los confundas.
7) ¿Puede el ransomware eliminar snapshots desde una máquina cliente?
No directamente vía SMB/NFS en la mayoría de configuraciones típicas, porque la gestión de snapshots es función de administrador de almacenamiento. Pero si tu entorno expone eliminación de snapshots vía scripts, APIs o credenciales sobre-privilegiadas en servidores, entonces sí—las snapshots pueden ser objetivo. Trata la capacidad de eliminar snapshots como altamente sensible.
8) ¿Debería montar réplicas de backup en algún momento?
Sólo cuando estés restaurando o verificando. Mantener réplicas desmontadas por defecto es una forma simple de reducir la modificación accidental y reducir la posibilidad de que algún proceso “descubra” las copias de seguridad y empiece a escribir en ellas.
9) ¿Readonly tiene implicaciones de rendimiento?
Impacto directo mínimo. La historia de rendimiento mayor es la arquitectura que habilitas: menos escrituras, menos actualizaciones de metadatos y menos churn en datasets protegidos. Durante un ataque, readonly puede mejorar rendimiento al impedir que tormentas destructivas de escritura tengan éxito (aunque los intentos consumen algunos recursos).
10) ¿Cuál es el control acompañante más importante a readonly?
La separación de identidades entre producción y backups/replicas. Readonly reduce daño, pero si la misma identidad comprometida puede administrar el almacenamiento y el objetivo de backup, estás apostando todo a “nadie llegará tan lejos”. En la práctica, alguien eventualmente lo hará.
Conclusión
ZFS readonly no es una característica de moda. Es uno de esos controles poco glamorosos que cambian los resultados de los incidentes. Cuando lo aplicas a los datasets correctos—datos publicados, archivos, periodos sellados y réplicas de backup—encajas al ransomware en un carril más estrecho. Aún puede ser ruidoso. Aún puede dar miedo. Pero es mucho menos probable que sea fatal.
El truco es tratar los límites de dataset como límites de seguridad, emparejar readonly con snapshots en los que realmente puedas confiar, y practicar las rutinas aburridas: sellado, replicación, pruebas de restauración y auditorías de deriva. En almacenamiento, los sistemas que sobreviven no son los más ingeniosos. Son los que tienen guardarraíles difíciles de eludir y fáciles de verificar.