Generar copias de seguridad incrementales automáticamente

Hacía falta un sistema seguro para almacenar copias de seguridad automáticamente, sin intervención humana para evitar olvidos. La copia debía contener tanto documentos como bases de datos, páginas web, configuraciones del equipo, etc.

El script resultante realizará una copia completa cada domingo y copias incrementales los demás días de la semana. Las copias de los domingos se sobreescriben cada dos semanas, por si hemos borrado algo y tardamos en darnos cuenta.

En palabras claras, el domingo día 1 se hace copia completa. El lunes solo se salvaguarda lo que haya cambiado respecto al domingo. El martes se guarda lo que haya cambiado respecto al lunes, y así hasta el domingo día 7 en que se realiza una nueva copia completa y se archiva la anterior. La semana siguiente se hacen copias incrementales hasta el domingo día 14, cuando se archiva la copia del domingo 7 sobreescribiendo la del domingo 1.

Como las copias de seguridad se hacen en el disco duro principal, cada noche sincronizaremos la copia de seguridad hacia otro dispositivo, para poder recurrir a ellas en caso de fallo del disco duro principal. Este dispositivo puede ser un equipo remoto, pero en nuestro caso aprovecharemos un disco duro que estaba cogiendo polvo y lo instalaremos como disco secundario, con la particularidad de que estará apagado todo el día salvo a la hora de realizar la copia de seguridad. De este modo no solo ahorramos energía, sino que además evitamos un desgaste prematuro del disco y mantenemos más frío y silencioso el habitáculo del servidor.

Importante

No debemos olvidarnos de colocar el script en la carpeta cron.daily


#!/bin/bash
#
# cron script to save a backup copy of Server configuration, web pages && databases
# Incremental copies on mon-sat, and full backup on sunday
#

#################### VARIABLES ####################

BAK=/home/datos/backups
DBPASS=MYSQL_PASSWORD_GOES_HERE

NUMDIA=`date +%u`

case $NUMDIA in
        1)    DIA=lun;;
        2)    DIA=mar;;
        3)    DIA=mie;;
        4)    DIA=jue;;
        5)    DIA=vie;;
        6)    DIA=sab;;
        7)    DIA=dom;;
esac

case $DIA in
        lun)    AYER=dom;;
        mar)    AYER=lun;;
        mie)    AYER=mar;;
        jue)    AYER=mie;;
        vie)    AYER=jue;;
        sab)    AYER=vie;;
        dom)    AYER=sab;;
esac

#################### FUNCIONES ####################

# Las bases de datos la copiamos entera todos los días, ya que al ser 1 solo fichero no podemos
# hacer copias incrementales.

function dbbackup {
		DB=$1
		DBDIR=$BAK/databases
		FILENAME=$2
		mysqldump -p$DBPASS --opt $DB > $DBDIR/$DB'_'$DIA.sql
		cd $DBDIR
		tar -cjvf $FILENAME'_'$DIA'.tar.bz2' $DB'_'$DIA'.sql' 2> /tmp/backuplog > /dev/null
		rm $DBDIR/$DB'_'$DIA'.sql'
           }

# Hacemos una copia completa el domingo, renombrando las incrementales de la
# semana pasada y borrando la del domingo anterior

function backup {
                # Pasamos como parámetro la carpeta que queremos salvar (e.g: /etc/apache2)
                # Como segundo parámetro pasamos la carpeta donde guardaremos la salvaguarda
                # Como tercer parámetro pasamos el fichero destino
                SOURCE=$1
                DEST=$2
                FILENAME=$3

                if [ -d $DEST ]
		then
			true
		else
			mkdir -p $DEST
		fi

		if [ $DIA == "dom" ]
		then
                # Comprimimos y guardamos copia del domingo anterior por si hay que recuperar alguna copia incremental.
			mv $DEST/$FILENAME'_'$DIA'.tar.bz2' $DEST/$FILENAME'_'$DIA'_ant.tar.bz2'
                        tar -cjvf $DEST/$FILENAME'_'$DIA'.tar.bz2' $SOURCE 2> /tmp/backuplog > /dev/null

                else

                # Hacemos copias incrementales respecto a la del día anterior entre lunes y sábado
                # y borramos las del mismo día de la semana anterior
			LASTCHG=`date +%y%m%d -r $DEST/$FILENAME'_'$AYER'.tar.bz2'`
                        tar -cjvf $DEST/$FILENAME'_'$DIA'.tar.bz2' --newer-mtime $LASTCHG $SOURCE 2> /tmp/backuplog > /dev/null
                fi
                }

#################### PROGRAMA ####################

##### Bases de datos #####

# jvc_joomla
dbbackup jvc_joomla jvc_joomla

# Geneweb
dbbackup gedview gedview

# mythweb
#dbbackup mythconverg mythweb

# Gallery

dbbackup jvc_gallery jvc_gallery

##### Configuraciones, spools  #####

# Usage: backup "folder_to_save" "dest_folder" "compressed_filename"
# e.g: backup /etc/apache2 $BAK/etc apache2
# will make a copy of /etc/apache2 into $BAK/etc in a filename called apache2.tar.bz2

# Configuraciones
backup /etc/apache2 $BAK/etc/apache2 apache2
backup /etc/apache2_asterisk $BAK/etc/apache2_asterisk apache2_asterisk
backup /etc/bind $BAK/etc/bind bind
backup /etc/cups $BAK/etc/cups cups
backup /etc/dhcp3 $BAK/etc/dhcp3 dhcpd
backup /etc/openvpn $BAK/etc/openvpn openvpn
backup /etc/postfix $BAK/etc/postfix postfix
backup /etc/sane.d $BAK/etc/sane.d saned
backup /etc/ssl $BAK/etc/ssl ssl
backup /etc/mysql $BAK/etc/mysql mysql
backup /var/lib/mysql $BAK/var/lib/mysql mysql
backup /etc/acidbase $BAK/etc/acidbase acidbase
backup /etc/snort $BAK/etc/snort snort
backup /etc/squid $BAK/etc/squid squid
backup /var/lib/mldonkey $BAK/var/lib/mldonkey mldonkey
backup /etc/calamaris $BAK/etc/calamaris calamaris
backup /var/www/seguridad $BAK/var/www/seguridad seguridad
backup /var/lib/awstats $BAK/var/lib/awstats awstats
backup /etc/samba $BAK/etc/samba samba
backup /var/lib/samba $BAK/var/lib/samba samba
backup /srv/tftp $BAK/srv/tftp tftp
#backup /etc/ejabberd $BAK/etc/ejabberd ejabberd
#backup /var/lib/jabber $BAK/var/lib/jabber jabber

# Webs
backup /var/www/jesusvillaverde.com $BAK/var/www/jesusvillaverde.com jesusvillaverde.com
backup /var/www/phpgedview $BAK/var/www/phpgedview phpgedview
backup /var/www/hermes.vigowireless.info $BAK/var/www/hermes.vigowireless.info hermes.vigowireless.info

# Asterisk
# Previamente hemos programado una copia de seguridad diaria en freepbx
#rsync --delete -gopt -Rlzrv /var/lib/asterisk/backups/DailyBackup $BAK/ > /dev/null
#rsync --delete -gopt -Rlzrv /etc/asterisk $BAK/ > /dev/null
#rsync --delete -gopt -Rlzrv /etc/dahdi $BAK/ > /dev/null

# Gallery
backup /home/datos/Imagenes/gallery $BAK/home/datos/Imagenes gallery

backup /var/www/gallery $BAK/var/www/gallery gallery

# Ficheros sueltos, varios
cp /etc/sudoers $BAK/etc
cp /etc/exports $BAK/etc
cp /etc/fstab $BAK/etc
cp /etc/dkim-filter.conf $BAK/etc
cp -r /etc/cron.weekly $BAK/etc
cp -r /etc/default $BAK/etc
cp /etc/rkhunter.conf $BAK/etc
cp /etc/init.d/iptables $BAK/etc/init.d
cp /etc/init.d/mldonkey-server $BAK/etc/init.d

# Varios
backup /home/jesus/sincronizar $BAK/home/jesus sincronizar
backup /home/xbmc $BAK/home/xbmc xbmc

#################### SINCRONIZAR ####################
# Sincronizamos hacia otro equipo para tener copia de respaldo.

# rsync --delete -gopt -e "ssh -p666" $BAK/* jesus@sip.jesusvillaverde.com:/media/datos/backups

# Generar registro de errores de la copia de seguridad
cat /tmp/backuplog  |grep -v "no ha cambiado" >> /var/log/backup_stderr
rm /tmp/backuplog