Duply es una interfaz para la poderosa magia de Duplicity y es excelente. Cualquiera que haya usado Duplicity para hacer copias de seguridad habrá notado dos cosas: lo poderoso y versátil que es como herramienta, y lo complicado que puede llegar a ser configurar un plan de copias de seguridad.

Antes de nada, vamos a hablar sobre el motor, esto es, Duplicity. Como amablemente apunta el artículo de la Wikipedia, Duplicity proporciona copias de seguridad cifradas, versionadas y remotas que exigen poco al servidor remoto. De hecho, simplemente necesita que el servidor remoto sea accesible mediante uno de los protocolos soportados (FTP, SSH, Rsync, etc).

Configurando Duply

El primer paso necesario para usar Duply es la creación de un perfil. Esto se puede conseguir ejecutando duply <perfil> create donde <perfil> es el nombre que queremos para el perfil.

Esto creo un archivo de configuración llamado ~/.duply/<perfil>/conf que editaremos. El archivo de configuración está bastante bien documentado pero voy a desglosar los principales puntos.

Hay varios ajustes que deberemos tener en cuenta cuando configuremos Duply:

  • Cifrado: si necesitamos que nuestras copias de seguridad estén cifradas, tanto con cifrado simétrico como con una clave y frase de paso;
  • Ubicación: en qué lugar almacenaremos la copia de seguridad, tanto en un servidor remoto como en una carpeta local;
  • Origen: el directorio que queremos guardar (podemos excluir archivos para evitar almacenar basura);
  • Edad: cuánto tiempo deberán conservarse nuestras copias de seguridad.

Cifrado

Hay dos tipos de cifrado que puede usar Duply (a no ser que lo deshabilitemos del todo), ambos con ventajas y desventajas.

El cifrado con claves GPG no necesita explicación. Usas una clave GPG para cifrar cada volumen de la copia de seguridad y tanto la clave GPG como su frase de paso son necesarios para descifrar la copia, dándote un extra de seguridad. Esto también significa que, si pierdes la clave GPG, no serás capaz de recuperar tu copia de seguridad, por tanto debes asegurarte de que el directorio ~/.gnupg/ está copiado en algún otro sitio y no sólo dentro de la copia de seguridad… Créeme, me ha pasado:

GPG_KEY='ADD274FA'        # Use 'gpg --list-keys' to see your keys
GPG_PW='VeryStrongPass'   # Passphrase of the key

El cifrado simétrico es más sencillo puesto que solamente usa una contraseña para el cifrado, esto es, podrás recuperar tu copia de seguridad siempre que puedas recordar esta contraseña. Obviamente, es menos seguro que si usamos una clave, puesto que es vulnerable a ataques de fuerza bruta:

#GPG_KEY='ADD274FA'       # Comment out this line
GPG_PW='ItBetterBeStr0ng' # Password to use

Ubicación

Ahora debemos configurar dónde va a guardar Duply nuestras copias de seguridad. En el archivo conf hay varios ejemplos para todos los protocolos soportados. En mi caso usaré FTP:

TARGET="ftp://ftpuser:ftppass@server/$USER@$HOSTNAME"

Ten en cuenta que, si usas variables de entorno de shell ($USER, $HOSTNAME, etc), debes usar comillas dobles en lugar de las sencillas que aparecen por defecto puesto que, si no, no se sustituirán las variables.

Origen

Normalmente, como usuarios normales, querremos salvaguardar nuestro directorio de usuario y excluir otros directorios/archivos con una lista de exclusión. Esto se puede hacer con Duply cambiando el siguiente ajuste en el archivo conf:

SOURCE="$HOME"

De nuevo ten en cuenta las comillas dobles para la sustitución de variables.

Para copias de seguridad del sistema, puesto que sólo podemos especificar un origen, deberíamos usar el directorio raíz y usar listas de exclusión:

SOURCE='/'

Excluyendo archivos

Una vez que hayamos determinado el origen, deberíamos filtrar aquellos archivos o directorios que harían nuestras copias demasiado grandes. Hacemos esto listando estos archivos en ~/.duply/<perfil>/exclude. Afortunadamente, este archivo acepta comodines de Unix. Como referencia, esto es lo que tengo en mi archivo de exclusiones:

**/*[Cc]ache*
**/*[Hh]istory*
**/*[Ss]ocket*
**/*[Tt]humb*
**/*[Tt]rash*
**/*[Bb]ackup
**/*.[Bb]ak
**/*[Dd]ump
**/*.[Ll]ock
**/*.log
**/*.part
**/*.[Tt]mp
**/*.[Tt]emp
**/*.swp
**/*~
**/.adobe
**/.cache
**/.dbus
**/.fonts
**/.gnupg/random_seed
**/.gvfs
**/.kvm
**/.local/share/icons
**/.macromedia
**/.obex
**/.rpmdb
**/.thumbnails
**/.VirtualBox
**/.wine
**/Descargas

Como puedes ver, puedes especificar tanto comodines como directorios/archivos concretos.

Vale la pena añadir que, aunque el archivo se llame exclude, se puede usar también para incluir archivos. Por ejemplo, si usamos el directorio raíz como origen (SOURCE='/') tal y como comentamos previamente, podemos excluir todos los archivos excepto ciertos directorios:

+ /etc
+ /root
+ /var/lib/mysql
+ /var/mail
+ /var/spool/cron
+ /var/www
**

Esa última línea le diría a Duply que ignorase todos los archivos excepto aquellos precedidos de un signo más.

Desde la versión v0.5.14 de Duply, existe otra forma de excluir directorios. Creando un archivo llamado .duplicity-ignore dentro de un directorio, forzamos a Duply a ignorarlo recursivamente. Para activar esta característica, deberemos descomentar estas líneas en nuestro archivo de configuración ~/.duply/<profile>/conf:

FILENAME='.duplicity-ignore'
DUPL_PARAMS="$DUPL_PARAMS --exclude-if-present '$FILENAME'"

Edad

Finalmente, podemos especificar la edad de las copias que mantendremos cuando ejecutemos los comandos de purgado. Hay un par de ajustes, dependiendo de la forma en la que hagamos nuestras copias de seguridad.

Este ajuste le dice a Duply que mantenga las copias de menos de cierta edad (por ejemplo 6 semanas) cuando ejecutamos duply <perfil> purge:

MAX_AGE=6W

Éste otro le dice a Duply que mantenga un cierto número de copias de seguridad completas cuando ejecutamos duply <perfil> purge-full:

MAX_FULL_BACKUPS=2

Sin embargo, el más útil para mí es el ajuste que usa el argumento --full-if-older-than de Duplicity para hacer un copia de seguridad completa de forma automática cuando la anterior copia completa tiene más tiempo que el límite que indicamos:

MAX_FULLBKP_AGE=1W
DUPL_PARAMS="$DUPL_PARAMS --full-if-older-than $MAX_FULLBKP_AGE "

Planificando copias

Por último, tras configurar todo, deberíamos lanzar una copia de prueba para comprobar que todo funciona correctamente con el comando duply <perfil> backup. Esto puede llevar bastante tiempo puesto que, al no tener ninguna copia previa, realizará una copia de seguridad completa.

A continuación, podemos comprobar el estado de nuestras copias ejecutando duply <perfil> status, lo que nos daría algo parecido a esto:

Found primary backup chain with matching signature chain:
-------------------------
Chain start time: Tue Apr 17 14:48:54 2012
Chain end time: Wed Apr 18 14:01:33 2012
Number of contained backup sets: 1
Total number of contained volumes: 52
 Type of backup set:                            Time:      Num volumes:
                Full         Tue Apr 18 14:48:54 2012                52
-------------------------
No orphaned or incomplete backup sets found.
--- Finished state OK at 15:46:34.122 - Runtime 00:00:03.495 ---

Esto está muy bien y todo eso, pero no podemos confiar en nuestra memoria para recordar cuándo deberíamos lanzar una copia de seguridad. Es por esto que deberíamos programar nuestras copias usando cron (o anacron, o fcron) y dejarles el trabajo pesado.

Podemos especificar una hora, tanto para la copia completa como para la copia incremental, así:

@daily    duply <perfil> backup_verify
@weekly   duply <perfil> full_verify_purge --force

Esto lanzará y verificará una copia incremental diaria y una copia completa semanal. También, purgará las copias viejas semanalmente tras completar y verificar la copia completa.

Sin embargo, si hemos configurado Duply para usar el argumento --full-if-older-than de Duplicity como hemos comentado más arriba, podemos simplemente lanzar un solo comando:

@daily    duply <perfil> backup_verify_purge --force

Esto es extremadamente útil para portátiles y máquinas que no están encendidas 24x7.

Guiones pre y post

Otro requisito básico para cualquier solución de copias de seguridad es la opción de ejecutar ciertos comandos tanto antes como después de realizar una copia. Duply, por supuesto, también ofrece esta opción y ejecutará cualquier comando dentro del archivo ~/.duply/<perfil>/pre antes de la copia y cualquier comando dentro de ~/.duply/<profile>/post después de ésta.

Esto es útil para bloquear y sincronizar bases de datos antes de la copia, y para desbloquearlas posteriormente, quizás para hacer incluso un snapshot de LVM para copias más rápidas y consistentes. O simplemente para obtener cualquier otra información que necesite copiarse también (p. ej. paquetes instalados, marcadores de Delicious, etc).

Copias en vivo

Existen ciertas desventajas al usar el sistema mientras se está realizando la copia de seguridad. Una de ellas es el impacto en el rendimiento, puesto que la copia está usando los discos.

También tenemos el hecho de que, si la copia de seguridad se prolonga, lo cual es bastante probable, y algún archivo se modifica mientras tanto, la verificación fallará. Esto no quiere decir que la copia haya fallado pero la verificación obviamente sí.

Para esto recomendaría usar, o un snapshot de LVM (como hemos comentado) lo cual, seamos realistas, no se suele hacer a no ser que se trate de un servidor; o podemos deshabilitar la verificación y usar ionice:

@daily    ionice -c3 duply <perfil> backup_purge --force

Esto lanzará la copia de seguridad con baja prioridad de E/S, lo que quiere decir que seremos capaces de usar el ordenador sin mucho impacto, y cron nos enviará un correo con la salida del comando de forma que podemos confirmar que la copia se ha realizado con éxito.