Ir al contenido

Copia de seguridad y restauración en Linux con Duplicity

Duplicity hace copias de seguridad de directorios produciendo volúmenes cifrados en formato tar y subiéndolos a un servidor de ficheros remoto o local. Como duplicity usa librsync, los archivos incrementales son eficientes en espacio y solo registran las partes de los ficheros que han cambiado desde la última copia de seguridad. Como duplicity usa GnuPG para cifrar y/o firmar estos archivos, estarán a salvo de espionaje y/o modificación por parte del servidor.

Duplicity se puede instalar en Debian/Ubuntu tan simplemente como:

Ventana de terminal
$ sudo apt-get install duplicity ncftp python-boto python-paramiko

Pero no está en los repositorios por defecto de CentOS/Red Hat, así que necesita instalarlo desde otro origen. Este script ayudará en este proceso de instalación:

#!/bin/bash
wget http://dl.fedoraproject.org/pub/epel/6/x86_64/duplicity-0.6.18-1.el6.x86_64.rpm
wget http://dl.fedoraproject.org/pub/epel/6/x86_64/ncftp-3.2.4-1.el6.x86_64.rpm
wget http://dl.fedoraproject.org/pub/epel/6/x86_64/librsync-0.9.7-15.el6.x86_64.rpm
wget http://dl.fedoraproject.org/pub/epel/6/x86_64/python-GnuPGInterface-0.3.2-6.el6.noarch.rpm
wget http://dl.fedoraproject.org/pub/epel/6/x86_64/python-boto-2.5.2-1.el6.noarch.rpm
rpm -Uvh duplicity-0.6.18-1.el6.x86_64.rpm ncftp-3.2.4-1.el6.x86_64.rpm librsync-0.9.7-15.el6.x86_64.rpm python-GnuPGInterface-0.3.2-6.el6.noarch.rpm python-boto-2.5.2-1.el6.noarch.rpm

Para hacer una copia de seguridad, puede ejecutar:

Ventana de terminal
$ duplicity --no-encryption /home/openkm file:///path/to/backup

Para verificarla:

Ventana de terminal
$ duplicity --no-encryption verify file:///path/to/backup /home/openkm

Para listar los ficheros respaldados:

Ventana de terminal
$ duplicity --no-encryption list-current-files file:///path/to/backup

Para restaurar un único fichero:

Ventana de terminal
$ duplicity --no-encryption --file-to-restore tomcat-9.0.76/openkm.properties file:///path/to/backup RestoredBackup

Estos scripts asumen los siguientes valores por defecto:

  • El valor de $TOMCAT_HOME es “/home/openkm/tomcat-9.0.76
  • La base de datos de OpenKM se llama “okmdb”.
  • La contraseña de la base de datos de OpenKM es “*secret*”.
  • La ubicación del script de servicio de inicio y parada de OpenKM es “/etc/init.d/tomcat

El punto de montaje del disco USB se puede definir en /etc/fstab como:

/dev/sdb1 /mnt/backup ext4 defaults 0 0

Estas son las secciones globales del script:

  • Configuración de variables globales bajo la sección ## BEGIN CONFIG ##.
  • Comprobación del usuario root bajo la sección # Check root.
  • Eliminación de copias de seguridad de base de datos antiguas bajo la sección # Delete older local database backup.
  • Montar disco (sección opcional) bajo la sección # Mount disk.
  • Detener la aplicación (sección opcional) bajo la sección # Stop tomcat.
  • Limpiar logs (sección opcional) bajo la sección # Clean logs.
  • Copia de seguridad de la base de datos al sistema de ficheros bajo la sección # Backup database.
  • Copia de seguridad del repositorio y volcado de base de datos al destino bajo la sección # Backup and purge old backups.
  • Iniciar la aplicación (sección opcional) bajo la sección # Start tomcat.
  • Mostrar estadísticas (sección opcional) bajo la sección # Status.
  • Desmontar disco (sección opcional) bajo la sección # Umount disk.

Explicación de los parámetros de configuración:

Parámetro Descripción
HOST El nombre de host del servidor.
DATABASE_PASS La contraseña de la base de datos.
El usuario de base de datos usado para hacer la copia de seguridad siempre es el usuario root.
OPENKM_DB El nombre de la base de datos de la aplicación.
Normalmente se llama “okmdb”.
OPENKM_HOME La carpeta home de OpenKM.
TOMCAT_HOME La carpeta home de Tomcat.
Normalmente dentro de la carpeta OPENKM_HOME.
DATABASE_EXP La carpeta del volcado de base de datos.
Normalmente en el mismo servidor.
BACKUP_DIR Destino de la copia de seguridad.

Cree un script de copia de seguridad /root/backup.sh

Ventana de terminal
$ sudo su
$ vim /root/backup.sh
#!/bin/bash
#
## BEGIN CONFIG ##
HOST=$(uname -n)
DATABASE_PASS="*secret*"
OPENKM_DB="okmdb"
OPENKM_HOME="/home/openkm"
TOMCAT_HOME="$OPENKM_HOME/tomcat-9.0.76"
DATABASE_EXP="$OPENKM_HOME/db"
BACKUP_DIR="file:///mnt/backup"
## END CONFIG ##
# Check root user
if [ $(id -u) != 0 ]; then echo "You should run this script as root"; exit; fi
# Delete older local database backup
echo -e "### BEGIN: $(date +"%x %X") ###\n"
rm -rf $DATABASE_EXP
mkdir -p $DATABASE_EXP
# Mount disk
if mount | grep "$BACKUP_DIR type" > /dev/null; then
echo "$BACKUP_DIR already mounted";
else
mount "$BACKUP_DIR";
if mount | grep "$BACKUP_DIR type" > /dev/null; then
echo "$BACKUP_DIR mounted";
else
echo "$BACKUP_DIR error mounting";
exit -1;
fi
fi
# Stop Tomcat
/etc/init.d/tomcat stop
# Clean logs
#echo "Clean Tomcat temporal files."
#rm -rf $TOMCAT_HOME/logs/*
#rm -rf $TOMCAT_HOME/temp/*
#rm -rf $TOMCAT_HOME/work/Catalina/localhost
# Backup database
if [ -n "$DATABASE_PASS" ]; then
echo "* Backuping MySQL data from $OPENKM_DB..."
mysqldump -h localhost -u root -p$DATABASE_PASS $OPENKM_DB > $DATABASE_EXP/mysql_$OPENKM_DB.sql
echo "-------------------------------------";
fi
# Backup and purge old backups
duplicity remove-older-than 1M --force $BACKUP_DIR/$HOST
if [ $(date +%u) -eq 7 ]; then
echo "*** Full Backup ***"
duplicity full --no-encryption $OPENKM_HOME $BACKUP_DIR/$HOST
RETVAL=$?
else
echo "*** Incremental Backup ***"
duplicity --no-encryption $OPENKM_HOME $BACKUP_DIR/$HOST
RETVAL=$?
fi
[ $RETVAL -eq 0 ] && echo "*** SUCCESS ***"
[ $RETVAL -ne 0 ] && echo "*** FAILURE ***"
# Start Tomcat
/etc/init.d/tomcat start
echo -e "\n### END: $(date +"%x %X") ###"
# Status
echo "=================================";
duplicity collection-status $BACKUP_DIR/$HOST
echo "*********************************";
df -h | grep "$BACKUP_DIR"
echo "=================================";
# Umount disk
sync
umount "$BACKUP_DIR"

Aumentar el período de retención de la copia de seguridad

Sección titulada «Aumentar el período de retención de la copia de seguridad»

Modifique la sección # Backup and purge old backups, aumentando el valor del parámetro:

--remove-older-than 3M

Modifique la sección ## Config section.

BACKUP_DIR="ftp://user@ftp.domain.es/backup"
export FTP_PASSWORD="WhateverPasswordYouSetUp"

Modifique la sección # Backup and purge old backups.

# Backup and purge old backups
duplicity remove-older-than 1M --force $BACKUP_DIR/$HOST
if [ $(date +%u) -eq 7 ]; then
echo "*** Full Backup ***"
duplicity full --no-encryption $OPENKM_HOME $BACKUP_DIR/$HOST
RETVAL=$?
else
echo "*** Incremental Backup ***"
duplicity --no-encryption $OPENKM_HOME $BACKUP_DIR/$HOST
RETVAL=$?
fi
[ $RETVAL -eq 0 ] && echo "*** SUCCESS ***"
[ $RETVAL -ne 0 ] && echo "*** FAILURE ***"

Modifique la sección # Status.

duplicity collection-status $BACKUP_DIR/$HOST
unset FTP_PASSWORD

Realizar la copia de seguridad remota a SMB o CIFS

Sección titulada «Realizar la copia de seguridad remota a SMB o CIFS»

Modifique la sección # Mount disk.

# Mount disk
if mount | grep "$BACKUP_DIR type" > /dev/null; then
echo "$BACKUP_DIR already mounted";
else
echo "Mounting $BACKUP_DIR ...";
mount -t cifs //REMOTE_SERVER/REMOTE_DIR $BACKUP_DIR -o username=REMOTE_USER,password=REMOTE_PASSWORD,iocharset=utf8,file_mode=0777,dir_mode=0777
if mount | grep "$BACKUP_DIR type" > /dev/null; then
echo "$BACKUP_DIR mounted";
else
echo "Error mounting $BACKUP_DIR.";
exit -1;
fi
fi

Modifique la sección # Backup database

# Backup de PostgreSQL
echo "* Backuping PostgreSQL data from $OPENKM_DB..."
su postgres -c "pg_dump $OPENKM_DB" > $DATABASE_EXP/pg_$OPENKM_DB.sql
# Databases optimizations
su postgres -c "vacuumdb -a -z" > /dev/null
su postgres -c "reindexdb -a -q" 2> /dev/null

Hacer la copia de seguridad remota a Amazon S3

Sección titulada «Hacer la copia de seguridad remota a Amazon S3»

Modifique la sección ## Config section.

BACKUP_DIR="s3+http://somebucket/somedirectory"
export AWS_ACCESS_KEY_ID=""
export AWS_SECRET_ACCESS_KEY=""
export PASSPHRASE=""

Modifique la sección # Backup and purge old backups.

# Backup and purge old backups
if [ $(date +%u) -eq 7 ]; then
echo "*** Full Backup ***"
duplicity full --no-encryption --s3-use-new-style $OPENKM_HOME $BACKUP_DIR/$HOST
RETVAL=$?
else
echo "*** Incremental Backup ***"
duplicity --no-encryption --s3-use-new-style $OPENKM_HOME $BACKUP_DIR/$HOST
RETVAL=$?
fi
[ $RETVAL -eq 0 ] && echo "*** SUCCESS ***"

Modifique la sección # Status.

# Status
duplicity collection-status --s3-use-new-style $BACKUP_DIR/$HOST
unset AWS_ACCESS_KEY_ID
unset AWS_SECRET_ACCESS_KEY
unset PASSPHRASE

Para instalar la tarea cron, ejecute:

Ventana de terminal
$ sudo mkdir /root/logs
$ sudo crontab -e

Añada estas líneas según su configuración personal:

MAILTO=nomail@openkm.com
@daily /root/backup.sh | tee /root/logs/backup.$(date +\%Y.\%m.\%d_\%H.\%M.\%S).log

Solución de problemas al eliminar copias antiguas

Sección titulada «Solución de problemas al eliminar copias antiguas»

Ha configurado Duplicity para hacer una copia de seguridad completa cada 7 días y eliminar las copias de más de 14 días para ahorrar espacio. ¿Qué ocurre si ve un mensaje como este?

Tue May 1 00:00:00 2012
Wed May 2 00:00:00 2012
Which can't be deleted because newer sets depend on them

Duplicity usa rsync, que registra cambios incrementales. Esos ficheros no se eliminarán porque, aunque una copia de seguridad tenga más de 7 días, existen copias incrementales que tienen menos de 7 días.

Así, tras pasar dos semanas, esos ficheros se eliminarán, ya que la copia completa y las copias incrementales tendrán ya 14 días, y existirá una copia completa más reciente que esas copias.

Puede listar las copias de seguridad disponibles:

Ventana de terminal
$ duplicity collection-status /path/to/backup
Sun Sep 11 05:00:19 2012 4.25 GB 4.25 GB (current mirror)
Sun Sep 4 00:00:18 2012 13.3 MB 4.26 GB
Sun Aug 28 00:00:13 2012 674 MB 4.92 GB
Sun Aug 21 00:00:14 2012 5.50 MB 4.93 GB
Sun Aug 14 00:00:16 2012 1.75 MB 4.93 GB
Sun Aug 7 00:00:12 2012 288 KB 4.93 GB
Sun Jul 31 00:00:13 2012 43.0 KB 4.93 GB
Fri Jul 29 10:36:39 2012 5.56 KB 4.93 GB

Luego decida restaurar una de las copias de seguridad, por ejemplo la hecha el Sun Aug 28 00:00:13 2012:

Ventana de terminal
$ duplicity restore --restore-time 2012-08-28 /path/to/backup /path/to/destination