Member of The Internet Defense League Últimos cambios
Últimos Cambios
Blog personal: El hilo del laberinto Geocaching

Backup doméstico seguro con Linux, cifrado y ZFS (II)

Última Actualización: 05 de agosto de 2013

El pasado abril publiqué un artículo documentando cómo montar un sistema de backup doméstico remoto con Linux, cifrado y ZFS. Parte del esquema propuesto consiste en usar un "mirror" para asegurar que los backups estén seguros ante fallos de disco duro, pero para evitar riesgos teniendo ambos discos duros en la misma localización física (incendio, inundación, robo, fallo catastrófico en el servidor) uno de los dos lados del mirror se almacena offline y en una tercera localización. De vez en cuando (dos o tres veces al año), el "mirror" se resincroniza y los discos se intercambian, para asegurar que ambos se desgasten por igual. Los discos están cifrados, así que almacenarlos offline en un lugar fuera de nuestro control no supone un riesgo de seguridad.

En estas condiciones, lo peor que puede pasar es un fallo total del disco duro que queda (en ese caso tenemos un backup "antiguo" disponible), o sectores dañados irrecuperables, que se solucionarán automáticamente cuando resincronicemos el "mirror". Dada la redundancia intrínseca a los discos ZFS, es muy raro (aunque no imposible) que sectores dañados aislados afecten a los metadados y, por tanto, a la integridad del backup. Cómo mucho, afectarían a ficheros aislados, reconstruidos de forma transparente al resincronizar el "mirror":

Con la llegada del verano vuelvo a casa, y toca realizar la sincronización y el intercambio por primera vez. Veamos cómo funciona.

  1. El primer paso consiste en obtener el disco "offline" alojado en casa de un amigo. Lo conectamos al servidor (ahora tendremos ambos enchufados) y configuramos la máquina virtual para que esté accesible dentro.

  2. Vemos lo siguiente:
    # zpool list
    NAME    SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
    datos  1.81T  1.25T   578G    68%  1.00x  DEGRADED  -
    
    # zpool status
      pool: datos
     state: DEGRADED
    status: One or more devices has been taken offline by the administrator.
            Sufficient replicas exist for the pool to continue functioning in a
            degraded state.
    action: Online the device using 'zpool online' or replace the device with
            'zpool replace'.
      scan: resilvered 148K in 0h0m with 0 errors on Sat Apr 20 17:35:32 2013
    config:
    
            NAME                      STATE     READ WRITE CKSUM
            datos                     DEGRADED     0     0     0
              mirror-0                DEGRADED     0     0     0
                primerdisco           ONLINE       0     0     0
                10256769708510827902  OFFLINE      0     0     0  was /dev/mapper/segundodisco
    
    errors: No known data errors
    

  3. En la máquina virtual actualizamos los scripts de montaje y desmontaje para que se active y desactive el cifrado en ambos discos duros.

  4. Activamos el disco antiguo y observamos cómo se sincronizan los cambios:
    # zpool online datos /dev/mapper/segundodisco
    
    # zpool status
      pool: datos
     state: ONLINE
    status: One or more devices is currently being resilvered.  The pool will
            continue to function, possibly in a degraded state.
    action: Wait for the resilver to complete.
      scan: resilver in progress since Sat Aug  3 17:38:41 2013
        49.7M scanned out of 1.25T at 2.92M/s, 124h22m to go
        49.7M resilvered, 0.00% done
    config:
    
            NAME              STATE     READ WRITE CKSUM
            datos             ONLINE       0     0     0
              mirror-0        ONLINE       0     0     0
                primerdisco   ONLINE       0     0     0
                segundodisco  ONLINE       0     0     0  (resilvering)
    
    errors: No known data errors
    
    (Unos minutos más tarde)
    
    # zpool status
      pool: datos
     state: ONLINE
    status: One or more devices is currently being resilvered.  The pool will
            continue to function, possibly in a degraded state.
    action: Wait for the resilver to complete.
      scan: resilver in progress since Sat Aug  3 17:38:41 2013
        266G scanned out of 1.25T at 146M/s, 1h58m to go
        18.1G resilvered, 20.80% done
    config:
    
            NAME              STATE     READ WRITE CKSUM
            datos             ONLINE       0     0     0
              mirror-0        ONLINE       0     0     0
                primerdisco   ONLINE       0     0     0
                segundodisco  ONLINE       0     0     0  (resilvering)
    
    errors: No known data errors
    
    (Unos minutos más tarde)
    
    # zpool status
      pool: datos
     state: ONLINE
    status: One or more devices is currently being resilvered.  The pool will
            continue to function, possibly in a degraded state.
    action: Wait for the resilver to complete.
      scan: resilver in progress since Sat Aug  3 17:38:41 2013
        1.17T scanned out of 1.25T at 274M/s, 0h4m to go
        58.5G resilvered, 94.12% done
    config:
    
            NAME              STATE     READ WRITE CKSUM
            datos             ONLINE       0     0     0
              mirror-0        ONLINE       0     0     0
                primerdisco   ONLINE       0     0     0
                segundodisco  ONLINE       0     0     0  (resilvering)
    
    errors: No known data errors
    

    Obsérvese la velocidad de escaneo del disco. Es tan elevada porque ZFS está analizando el grafo del disco y se salta secciones enteras que sabe que no se han modificado. La velocidad real del disco duro es, por supuesto, muy inferior.

    Este "resilvering" selectivo es una de las grandes ventajas de ZFS. Una de muchas.

  5. Una vez que el "resilvering" se completa, vemos lo siguiente:
    # zpool status
      pool: datos
     state: ONLINE
      scan: resilvered 85.1G in 1h47m with 0 errors on Sat Aug  3 19:26:05 2013
    config:
    
            NAME              STATE     READ WRITE CKSUM
            datos             ONLINE       0     0     0
              mirror-0        ONLINE       0     0     0
                primerdisco   ONLINE       0     0     0
                segundodisco  ONLINE       0     0     0
    
    errors: No known data errors
    

    Sincronizamos un "mirror" de 1.25Terabytes en menos de dos horas. La sincronización sólo copia los datos alterados: 85Gigabytes. Nos sale unos 13.5MB/s, que no está mal teniendo en cuenta que son accesos aleatorios y que estamos trabajando con discos lentos (primamos la capacidad y el consumo de energía).

  6. Ahora tenemos los dos discos perfectamente sincronizados. Pero uno de los discos lleva meses parado y el otro solo ha revisado los datos que se acaban de sincronizar en el "mirror", no el disco duro entero. Como vamos a proceder a desconectar el disco duro que estaba en uso hasta ahora, primero deberíamos asegurarnos de que todo está correcto. Revisamos los dos discos duros y la completa integridad del "pool" ZFS:
    # zpool scrub datos
    
    # zpool status
      pool: datos
     state: ONLINE
      scan: scrub in progress since Sat Aug  3 19:28:02 2013
        70.8M scanned out of 1.25T at 2.21M/s, 164h16m to go
        0 repaired, 0.01% done
    config:
    
            NAME              STATE     READ WRITE CKSUM
            datos             ONLINE       0     0     0
              mirror-0        ONLINE       0     0     0
                primerdisco   ONLINE       0     0     0
                segundodisco  ONLINE       0     0     0
    
    errors: No known data errors
    

  7. La revisión lleva bastante tiempo, ya que supone la lectura de todos los datos en ambos discos duros. Los datos incluyen "checksum", así que si hubiese alguna inconsistencia, ZFS lo sabría y también sabría qué lado del "mirror" debe usar para corregir al "otro". En nuestro caso, todo va bien, no vemos la impresionante capacidad de resistencia de ZFS:
    # zpool status
      pool: datos
     state: ONLINE
      scan: scrub repaired 0 in 13h30m with 0 errors on Sun Aug  4 08:58:50 2013
    config:
    
            NAME              STATE     READ WRITE CKSUM
            datos             ONLINE       0     0     0
              mirror-0        ONLINE       0     0     0
                primerdisco   ONLINE       0     0     0
                segundodisco  ONLINE       0     0     0
    
    errors: No known data errors
    

  8. Con esto, procedemos a desactivar el disco duro que estaba en producción antes, dejando el nuevo activo:
    # zpool offline datos primerdisco
    
    # zpool status
      pool: datos
     state: DEGRADED
    status: One or more devices has been taken offline by the administrator.
            Sufficient replicas exist for the pool to continue functioning in a
            degraded state.
    action: Online the device using 'zpool online' or replace the device with
            'zpool replace'.
      scan: scrub repaired 0 in 13h30m with 0 errors on Sun Aug  4 08:58:50 2013
    config:
    
            NAME              STATE     READ WRITE CKSUM
            datos             DEGRADED     0     0     0
              mirror-0        DEGRADED     0     0     0
                primerdisco   OFFLINE      0     0     0
                segundodisco  ONLINE       0     0     0
    
    errors: No known data errors
    

  9. Ahora retocamos los scripts de montaje y desmontaje para que cifren y descifren exclusivamente el disco "segundodisco".

  10. Paramos la máquina virtual, eliminamos "primerdisco" de la configuración.

  11. Extraemos "primerdisco" del servidor, lo empaquetamos y lo dejo en casa de mi amigo, listo para proceder a otro intercambio en navidad.

  12. Reiniciando la máquina virtual, comprobamos que todo va bien. Vemos lo siguiente:
    # zpool status
      pool: datos
     state: DEGRADED
    status: One or more devices has been taken offline by the administrator.
            Sufficient replicas exist for the pool to continue functioning in a
            degraded state.
    action: Online the device using 'zpool online' or replace the device with
            'zpool replace'.
      scan: scrub repaired 0 in 13h30m with 0 errors on Sun Aug  4 08:58:50 2013
    config:
    
            NAME              STATE     READ WRITE CKSUM
            datos             DEGRADED     0     0     0
              mirror-0        DEGRADED     0     0     0
                primerdisco   OFFLINE      0     0     0
                segundodisco  ONLINE       0     0     0
    
    errors: No known data errors
    

    Obsérvese que se indica que "primerdisco" está offline. Nos da el nombre, no el identificador único del disco, como la vez anterior. Posiblemente sea un bug corregido en las versiones recientes del port ZFS para Linux.

  13. Todo va bien. Hemos terminado. Seguimos trabajando con normalidad. Y con tranquilidad.

Y ZFS nos salva el culo, una vez más

Hacer cosas tan delicadas con el hardware trabajando dentro de máquinas virtuales tiene sus riesgos, y más si el "host" es Microsoft Windows (8) y el hardware físico se dedica a remapear las unidades de disco en cada arranque, cuando le da la gana. Pero incluso en situaciones tan hostiles como ésta, ZFS está a la altura.

En un momento dado pensé que había mapeado los dos discos duros en la máquina virtual, cuando lo que realmente había hecho era mapear el mismo disco duro dos veces. Terrorífico. Las consecuencias normales de este hecho sería la corrupción total y completa de los backups, al menos los contenidos en el disco duro mapeado. Pero ZFS detectó el problema y nos protegió de un fallo catastrófico:

# zpool online datos 10256769708510827902
warning: device '10256769708510827902' onlined, but remains in faulted state
use 'zpool replace' to replace devices that are no longer present

# zpool status
  pool: datos
 state: DEGRADED
[.. No conservo la información que aparecía aquí. Lo siento ..]
config:

        NAME                      STATE     READ WRITE CKSUM
        datos                     DEGRADED     0     0     0
          mirror-0                DEGRADED     0     0     0
            primerdisco           ONLINE       0     0     0
            10256769708510827902  FAULTED      0     0     0  was /dev/mapper/segundodisco

errors: No known data errors

Este error fue completamente inesperado y encendió todas mis alarmas. ZFS detecta un problema (el disco activado no contiene los metadatos esperados) y se niega a utilizar el dispositivo. Una alerta así te obliga a revisarlo todo. Tras unos minutos de pensar se me ocurrió calcular el hash de los primero 8 gigabytes de ambos discos y al comprobar que ambos hashes eran el mismo la única conclusión posible es que estaba viendo un disco fantasma por un mapeo múltiple en la máquina virtual.

El estudio de la configuración del "host" mostró el problema, ocasionado por una renumeración de los dispositivos al enchufar un disco duro nuevo.

La moraleja, no obstante, es que cualquier otro sistema de ficheros hubiera corrompido el "pool" irremediablemente (ya me ha ocurrido antes), mientras que ZFS detecta el problema y te protege.

Gracias, ZFS. ¡Un hurra por los sistemas "serios"!.


Historia

  • 05/ago/13: Primera versión de esta página.



Python Zope ©2013 jcea@jcea.es

Más información sobre los OpenBadges

Donación BitCoin: 19niBN42ac2pqDQFx6GJZxry2JQSFvwAfS