Copias de seguridad: rSync

Las copias de seguridad son esa asignatura pendiente que muchos tenemos y que deberíamos valorar antes de que nos tengamos que arrepentir

Copias de seguridad: rSync

Seguramente recordéis el incidente que sufrió OVH en uno de sus centros de datos.  El servidor en el que tengo este blog fue uno de los que sufrió el "apagón colateral", no se vio afectado pero estuvo innacesible durante un par de semanas.

Empecé usándolo para cacharreos y pruebas, pero poco a poco se ha ido convirtiendo en una pieza imprescindible de mi nube, a medida que he ido añadiendo servicios y aplicaciones al mismo. Si bien mantenía unas copias manuales de lo realmente imprescindible (gestor de contraseñas, entradas del blog...) pensando en que, en caso de catástrofe al menos no perder lo importante, tras el incendio me planteé automatizar este proceso, tanto en el VPS como en mi querida Raspberry PI.

En mi Raspberry PI tengo definido un proceso de copia de seguridad que comprime a un ZIP encriptado lo importante y lo sube a mi servidor de MinIO. Pero en el caso del VPS quería algo más "directo", de manera que, si me volviera a quedar sin acceso al servidor, pudiera derivar todas las peticiones a otro que estuviera listo para servirlas con facilidad. Así pues, investigando di con rSync, una herramienta que me permite sincronizar directorios entre mi servidor principal y el de respaldo. A grandes rasgos, la idea es la siguiente:

Copia de directorios seleccionados desde Alice a Bob
Copia de directorios seleccionados desde Alice a Bob
Es necesario tener instalado rSync en ambas máquinas para poder hacer los siguientes pasos

Lo primero que deberemos configurar será una clave SSH para que rSync pueda conectarse a la máquina de respaldo (Bob en el diagrama) desde nuestra máquina principal (Alice) como expliqué en esta entrada.

Una vez la tenemos, creamos un script en Alice con el siguiente contenido:

#!/bin/bash

USER=<user>
REMOTE_USER=<remoteuser>
IP_DESTINO=<ip_destino>

rsync -avp --exclude={'/bin','/boot','/dev','initrd.img','initrd.img.old','lib*','/lost+found','/media','/mnt','/proc','/root','/run','sbin','/srv','/sys','/tmp','/usr','/var','vmlinuz','vmlinuz.old'} --delete-after -e 'ssh -p 12345 -i /home/$USER/.ssh/id' / $REMOTE_USER@$IP_DESTINO:/home/$REMOTE_USER/backups/rsync/alice/

if [ $? -ne 0 ]
then
  /home/$USER/scripts/publishMessageToTg.sh "Error realizando el backup de **Alice** en **Bob**... Consulta el log para ver los detalles" > /dev/null 2>&1
else
  /home/$USER/scripts/publishMessageToTg.sh "Copia de seguridad de **Alice** en **Bob** realizada correctamente." > /dev/null 2>&1
fi
Script para copiar los directorios de Alice en Bob

Como podéis ver es bastante simple: Definimos el usuario origen en Alice y el usuario destino en Bob, así como la IP de destino donde se encuentra Bob. A continuación, invocamos el script de rSync con los siguientes parámetros:

  • -a: Ejecuta el modo archivo. Equivale a pasarle los parámetros -rlptgoD, que son, en este orden: ejecutar de manera recursiva en cada carpeta, copiar los symlinks como tal en lugar del archivo destino, preservar los permisos, preservar el timestamp de la última modificación de cada archivo, preservar los grupos en los permisos, preservar el usuario (sólo si se ejecuta como root) y preservar los ficheros especiales y de directorio.
  • -v: Activar el modo verbose.
  • -p: Preservar los permisos. Es redundante con el -a anterior, pero así queda más claro y explícito.
  • --exclude: Excluye los directorios y archivos que encajen con el patrón que le definimos. En nuestro caso, una lista de directorios y ficheros que queremos ignorar y no replicar en Bob.
  • --delete-after: En la parte de Bob, una vez realizada la copia, se borrarán los directorios y ficheros que se eliminaron en Alice, pero no se hará durante la copia. De esta manera, se ejecutarán 2 rondas: en la primera se copiarán los ficheros nuevos y las modificaciones, y en la segunda se borrarán de Bob los ficheros y directorios que se hayan eliminado de Alice.
  • -e: Especificamos el comando a ejecutar en el destino. Para nuestro caso, lo que hacemos es especificarle que haga la copia por ssh usando el puerto 12345 (recordad que SSH no debería estar con el puerto por defecto si está expuesto al exterior) y qué perfil debe usar para coger la clave público-privada (de manera que no nos va a requerir introducir contraseña).
  • /: Ruta de origen. En este caso le estamos diciendo que recorra todo el disco desde la raíz (ignorando las carpetas y ficheros especificados en --exclude, de manera que nos copiará las carpetas principales que no estén ahí especificadas). Se puede hacer así o usar el parámetro --include de la misma forma si preferimos ser más concretos (y más claros en el script de qué carpetas estamos copiando...)
  • $REMOTE_USER@$IP_DESTINO:/home/$REMOTE_USER/backups/rsync/alice/: Le estamos indicando el usuario remoto y la IP de destino a la que debe conectarse y, ya en Bob, la ruta absoluta donde queremos que se copie el origen.

Por último, en función del resultado que nos dé rSync, enviamos una notificación a Telegram con el resultado.

Una vez tengamos el script, bastará con que añadamos al cron del usuario root la siguiente línea:

3 0 * * 2,4,6 /scripts/backupSync.sh > /var/log/backupSync.log 2>&1
Línea de cron para ejecutar el script

¡Y listo! Ahora en los martes, jueves y sábados, a las 3 de la madrugada se nos hará una copia exacta de una gran parte de Alice en Bob. Y si pasa cualquier catástrofe, no nos costará mucho restaurar dichos directorios en una máquina en blanco para poner en funcionamiento lo más crítico. Seguro que hay maneras mejores de hacerlo, pero ésta es una que, de momento, me sirve :P. ¡Poco a poco iremos mejorando!

Si te ha gustado la entrada, o te ha sido útil y quieres ayudarme a pagar los gastos que conlleva el servidor y mantener así el blog libre completamente de anuncios, puedes hacer una donación en Bitcoin en la siguiente dirección:

Donar