Glacier y tartarus

Esto es un minimanual de como utilizar la herramienta de backup tartarus con amazon glacier.

Definiciones previas:

Tartarus (http://wertarbyte.de/tartarus.shtml) es un inteligente script escrito en bash que sirve para hacer copias de seguridad. Es muy versátil y debido a sus conectores permite usar desde SCP, FTP, FTPS, rsync y casi cualquier otra herramienta de copia. Este script hace un tar del directorio indicado y lo comprime en gzip o bzip además de poder cifrarlo con GNUpg, además, llamándolo con la opción -i (incremental) permite transmitir y guardar en un nuevo fichero sólo los cambios.

Si disponemos de LVM, podremos crear snapshots durante la copia de seguridad y consolidarlos después de la misma para hacer un backup en caliente de datos que están cambiando.

Por otro lado, glacier (http://aws.amazon.com/glacier/) es un servicio de almacenamiento en la nube bastante barato. Con un coste aproximado de un centavo de dólar por giga al mes a octubre de 2013. No obstante, su bajo coste trae aparejado una merma de funcionalidad: Las tareas de recuperación de archivos tardan varias horas, no almacena nombres de archivos sino descripciones de los mismos y las tareas de inventario (listar ficheros) deben solicitarse y también tardan varias horas.

Para consumir el API de glacier hay multitud de herramientas, en este tutorial voy a hacer uso de la herramienta glaciercmd (https://github.com/LordGaav/glaciercmd) el uso de esta herramienta ha requerido instalar la máquina oficial de java de oracle, he sido incapaz de hacerla funcionar con openjdk. Comento esto por si alguien pasa algún tiempo rompiéndose la cabeza, para que no pierda demasiado tiempo, probablemente se pueda hacer funcionar con openjdk según dice el autor, pero resulta más simple utilizar la versión oficial de java en este caso.

A pesar que tartarus de por si resulta muy interesante y tiene muchas opciones, voy a hablar de cómo usarlo en conjunción con amazon glacier.

Por un lado debemos instalar la máquina oficial de java, la herramienta ant para compilar glaciercmd y el gestor de repositorios git.

En debian:

apt-get install git ant

En fedora:

yum install git ant

Una vez bajada la máquina de java, estableceremos las variables: PATH y JAVA_HOME en nuestro $HOME/.bash_profile. En mi caso, he instalado java en /opt:

export JAVA_HOME=/opt/jdk1.7.0_40/
export PATH=/opt/jdk1.7.0_40/bin/:$PATH

Esto hará que se coja por defecto nuestra máquina de java al estar antes en el PATH.

Ahora clonaremos el repositorio de glaciercmd:

mkdir /opt/amazon
cd /opt/amazon
git clone https://github.com/LordGaav/glaciercmd.git

Una vez clonado, compilamos:

ant dist

Con esto, tendremos la herramienta glaciercmd casi lista. ¿Por qué casi? Porque el script que nos genera para ejecutar la herramienta tiene los path relativos y en caso de llamarla desde otros directorios (algún común si utilizamos cron, tartarus, otro script, etc) fallará por no encontrar las librerías.

Para poner los path absolutos, editaremos el archivo glaciercmd que se ha generado, que no es más que un script en bash y pondremos las rutas correspondientes:

#!/bin/sh
FULLPATH=/opt/amazon/glaciercmd/
java -classpath $FULLPATH./classes:$FULLPATH./lib/apache-commons/commons-cli-1.2-javadoc.jar:$FULLPATH./lib/apache-commons/commons-cli-1.2-sources.jar:$FULLPATH./lib/apache-commons/commons-cli-1.2.jar:$FULLPATH./lib/apache-commons/commons-codec-1.3.jar:$FULLPATH./lib/apache-commons/commons-configuration-1.8-javadoc.jar:$FULLPATH./lib/apache-commons/commons-configuration-1.8-sources.jar:$FULLPATH./lib/apache-commons/commons-configuration-1.8.jar:$FULLPATH./lib/apache-commons/commons-lang-2.6-javadoc.jar:$FULLPATH./lib/apache-commons/commons-lang-2.6-sources.jar:$FULLPATH./lib/apache-commons/commons-lang-2.6.jar:$FULLPATH./lib/apache-commons/commons-logging-1.1.1-javadoc.jar:$FULLPATH./lib/apache-commons/commons-logging-1.1.1-sources.jar:$FULLPATH./lib/apache-commons/commons-logging-1.1.1.jar:$FULLPATH./lib/apache/httpclient-4.1.1.jar:$FULLPATH./lib/apache/httpcore-4.1.jar:$FULLPATH./lib/aws/aws-java-sdk-1.3.27-javadoc.jar:$FULLPATH./lib/aws/aws-java-sdk-1.3.27-sources.jar:$FULLPATH./lib/aws/aws-java-sdk-1.3.27.jar:$FULLPATH./lib/aws/aws-java-sdk-flow-build-tools-1.3.27.jar:$FULLPATH./lib/jackson/jackson-core-asl-1.8.7-sources.jar:$FULLPATH./lib/jackson/jackson-core-asl-1.8.7.jar:$FULLPATH./lib/jackson/jackson-mapper-asl-1.8.7-sources.jar:$FULLPATH./lib/jackson/jackson-mapper-asl-1.8.7.jar nl.nekoconeko.glaciercmd.Entry "$@"

Ahora ya tenemos la herramienta lista para ser llamada desde cualquier sitio.

Un ejemplo de subida de archivos podría ser:

$
 /opt/amazon/glaciercmd/glaciercmd -r $ZONA -k $LLAVE -s $SECRETO 
--description $NOMBRE_FICHERO --input $RUTA_AL_FICHERO -u --vault 
$NOMBRE_VAULT

A modo de introducción, para quien no conozca amazon S3 o Glacier:

La Zona puede ser: VIRGINIA, OREGON, CALIFORNIA, IRELAND o TOKYO.

La llave y el secreto te las proporciona amazon, es parecido al usuario y clave, pero para el uso exclusivo de su API.

La descripción es el nombre del fichero, amazon identifica los ficheros por un identificador de archivo alfanumérico bastante largo.

La ruta al fichero es donde se encuentra el fichero físicamente, recomiendo usar una ruta absoluta para evitar errores.

Por último, el vault ($NOMBRE_VAULT) es el nombre del vault que deseemos utilizar. Grosso modo, un vault es un almacén de archivos, podemos tener hasta 1000 distintos.

Y ahora nos pondremos con tartarus. Su instalación es muy sencilla, sólo necesitamos previamente los programas: tar, bzip2, gzip, lvm2, gnupg y curl

Por ejemplo, para instalarlos desde debian:

# apt-get install tar bzip2 lvm2 gnupg curl

Si queremos instalar tartarus desde el repositorio oficial podemos ejecutar:

# wget -O /etc/apt/sources.list.d/wertarbyte.list http://wertarbyte.de/apt/wertarbyte-apt.list
# wget -O - http://wertarbyte.de/apt/software-key.gpg | apt-key add -
# apt-get update
# apt-get install tartarus

O bien bajarnos el tar.gz y meterlo donde queramos, realmente no hay mucha diferencia por tratarse de un script en bash.

Ahora, si queremos cifrar los archivos que subiremos a amazon glacier, lo cual resulta muy recomendable ya que al subir los datos a la nube realmente no sabemos quien ni como los custodiará, debemos crear un archivo con una clave. Abordaremos el cifrado mediante el uso de un cifrado simétrico.

He guardado todos los archivos de configuración en /etc/tartarus para mayor claridad.

Generamos una clave aleatoria de 128 caracteres:

< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-128};echo;

Y la metemos en un archivo, por ejemplo: /etc/tartarus/clave.tartarus

Ahora crearemos un archivo con la configuración básica de tartarus, en este ejemplo he elegido trozos de 1 GB, con gzip (mucho más rápido que bzip2) y que guarde los timestamps de los ficheros (las marcas de tiempo que indican si han o no cambiado) en /var/spool/tartarus/

/etc/tartarus/glacier.conf

NAME="glacier"
DIRECTORY="/directorio/del/que/hacer/backup"
STORAGE_METHOD="CUSTOM"
STORAGE_CHUNK_SIZE="1000"
COMPRESSION_METHOD="gzip"
STAY_IN_FILESYSTEM="yes"
CREATE_LVM_SNAPSHOT="no"
ENCRYPT_SYMMETRICALLY="yes"
ENCRYPT_PASSPHRASE_FILE="/etc/tartarus/clave.tartarus"
INCREMENTAL_TIMESTAMP_FILE="/var/spool/tartarus/timestamps/directoriodelquehacerbackup"
INCREMENTAL_STACKING="yes"
TARTARUS_CUSTOM_STORAGE_METHOD() {
nombredelfichero=$FILENAME /opt/amazon/enviar-a-glacier.sh
}

Por último, nos creamos un script en /opt/amazon/enviar-a-glacier.sh con el siguiente contenido:

#!/bin/bash
ficherotemporal=`mktemp`
cat - > $ficherotemporal
/opt/amazon/glaciercmd/glaciercmd -r $ZONA -k $LLAVE -s $SECRETO --description $nombredelfichero --input $ficherotemporal -u --vault $VAULT
rm $temporalf

Esto recibirá el archivo por entrada estándar que le pasará tartarus, lo almacena en un fichero temporal creado mediante mktemp y lo subirá a glacier. Por último lo borrará antes de pasar al siguiente. De este modo, sólo necesitaremos un giga libre para poder hacer nuestro backup.

Por último le daremos permisos de ejecución al script:

# chmod a+rx /opt/amazon/enviar-a-glacier.sh

Acordaros de sustituir cada $VARIABLE por su valor, como está explicado más arriba.

Recomiendo guardar en algún sitio la salida del log, en este ejemplo no lo he contemplado. Es muy útil porque nos devolverá los identificadores de fichero y en caso de querer recuperar algún archivo, no tendremos que esperar por el listado del inventario, que puede tardar varias horas.

Ya podemos ejecutar tartarus:

# /usr/sbin/tartarus (-i) /etc/tartarus/glacier.conf

El parámetro -i de incremental es opcional y no debe ponerse la primera vez, por eso va entre paréntesis.

A día de hoy (2018) existen alternativas más baratas a glacier de amazon como backblaze.