Script de backup remote_backup.sh

Mediante este script, se pueden realizar copias de resguardo remotas, utilizando una conexión encriptada con SSH.

#!/bin/sh

# 43 6 * * * /usr/local/sbin/remote_backup.sh 2>&1 | /bin/mail mail@dominio.com -s "Reporte del backup de host.dominio.com para el `/bin/date`"

# Remote backup script
#
# Author: Federico Voges <ftc@ftc.com.ar>
# Copyright 2004 Federico Voges. Modified by Felix Molinuevo :)

# Importante: Este script usa SSH para transferir los archivos de manera 
# segura. Debido a esto, es necesario poder acceder via SSH *SIN PASSWORD*
# O sea: a leer el manual de SSH y asegurarse de entender como configurar 
# public/private keys y sus implicaciones de seguridad :)

# Warning: This script uses SSH to transfer files in a secure way. This means
# that you should setup SSH to use public/private keys *WITHOUT PASSPHRASE*.
# That means: Read the man pages and make sure you understand how to configure 
# public/private keys and the security considerantions :)

# Idioma/Language (es/en)
LANG=es
          
# Candidad de backups historicos (diarios y mensuales respectivamente)
# Number of historic backups to save
DAILY_BACKUPS=7
MONTHLY_BACKUPS=1
          
# Directorio donde se guardaran los backups
# Where to make the backups (you'll probably need a lot of space)
BACKUP_DIR="/mnt/backupdir"

# Host a backupear
# Remote hostname (host to backup)
SOURCE_HOST="host.dominio.com"

# Directorios a backupear. Importante:
# NO PONER BARRA "/" AL FINAL DEL NOMBRE
# NO PONER NOMBRES DE DIRECTORIOS QUE CONTENGAN ESPACIOS

# Remote directories to backup
# DO NOT PUT "/" AT THE END
# DO NOT USE DIRECTORY NAMES CONTAINING SPACES
SOURCE_DIRS="/home /etc /var /root"

#############################################################################
#
# No deberia ser necesario cambiar nada de aca en adelante...
# You shouldn't need to change anything below this
#
DAILY_DIR="${BACKUP_DIR}/daily"
MONTHLY_DIR="${BACKUP_DIR}/monthly"
DEST_DIR="${BACKUP_DIR}/rsync"
EXCLUDE="/tmp/`basename $0`.$$"
VERBOSE="0"

#FIND="/usr/local/bin/find.bigfiles" 		# Support for filesize >2GB
FIND="/usr/bin/find"
TAR="/bin/tar"
#RSYNC="/usr/sbin/rsyncd"
RSYNC="/usr/bin/rsync"
RSHELL="/usr/bin/ssh"
RSYNC_OPTS=""
RSYNC_OPTS="${RSYNC_OPTS} -e ${RSHELL}"
RSYNC_OPTS="${RSYNC_OPTS} --archive" 		# Equivalent to -rlptgoD:
						#  --recursive
						#  --links
						#  --perms
						#  --times
						#  --group
						#  --owner
						#  --devices
RSYNC_OPTS="${RSYNC_OPTS} --partial"
RSYNC_OPTS="${RSYNC_OPTS} --delete"
#RSYNC_OPTS="${RSYNC_OPTS} --relative" 		# Usar para directorios de 2do nivel (ej /usr/local)
RSYNC_OPTS="${RSYNC_OPTS} --delete-after"
RSYNC_OPTS="${RSYNC_OPTS} --compress"
#RSYNC_OPTS="${RSYNC_OPTS} --bwlimit=7"
RSYNC_OPTS="${RSYNC_OPTS} --exclude-from=${EXCLUDE}"

if [ "$VERBOSE" = "1" ]; then
	RSYNC_OPTS="${RSYNC_OPTS} --progress"
	RSYNC_OPTS="${RSYNC_OPTS} --verbose"
	RSYNC_OPTS="${RSYNC_OPTS} --stats"
else
	RSYNC_OPTS="${RSYNC_OPTS} --quiet"
fi

DATE="`date +%Y-%m-%d`"
BACKUP_FILE="${DAILY_DIR}/backup-${DATE}.tar.gz"

cat > ${EXCLUDE} << EOF
\.journal
lost\+found
aquota\.user
aquota\.group
quota\.user
quota\.group
/home/ftp/pub/*
/home/backup/*
/home/backup/tmp/*
/home/backup/mysql/*
/home/backup/old/*
/home/games/*
/home/games/.*
/var/tmp/*
/var/tmp/.*
*/.ccache
*/tmp/ccache
EOF

mkdir -p ${MONTHLY_DIR} || exit 1
mkdir -p ${DEST_DIR} || exit 1
mkdir -p ${DAILY_DIR} || exit 1

cd ${BACKUP_DIR}

if [ "$LANG" != "en" ]; then
	echo "Iniciando proceso de backup"
	echo "Sincronizando archivos"
else
	echo "Starting backup process"
	echo "Rsync'ing files"
fi
for d in ${SOURCE_DIRS}; do
	TRY=0
	while [ $TRY -le 10 ]; do 
		if [ "$VERBOSE" = "1" ]; then
			${RSYNC} ${RSYNC_OPTS} ${SOURCE_HOST}:$d ${DEST_DIR}
		else
			${RSYNC} ${RSYNC_OPTS} ${SOURCE_HOST}:$d ${DEST_DIR} >& /dev/null
		fi
		rc=$?
		if [ $rc = 0 ]; then
			TRY=11
		elif [ $rc = 20 ]; then
			echo -e "\nProceso abortado (SIGINT)!"
			exit 1
		else
			TRY=$[ $TRY + 1 ]
			echo -e "\nError sincronizando archivos. Intentando nuevamente ($TRY/10)"
		fi
	done
	if [ $TRY = 10 ];then
		echo -e "\nError durante sincronizacion de archivos. Backup abortado!"
		exit 1
	fi
done
rm ${EXCLUDE}

if [ "$LANG" != "en" ]; then
	echo "Haciendo backup para el dia ${DATE}"
else
	echo "Making backup for ${DATE}"
fi
	
/bin/nice -n 19 ${TAR} -cpzf ${BACKUP_FILE} -C ${DEST_DIR} . || echo "Error!"

if [ "$LANG" != "en" ]; then
	echo "Borrando los backups con mas de ${DAILY_BACKUPS} dias de antigüedad"
else
	echo "Deleting backups older than ${DAILY_BACKUPS} days"
fi
${FIND} ${DAILY_DIR} -type f -daystart -name "backup-*" -mtime +$[${DAILY_BACKUPS} - 1] -exec rm -Rf {} \; 2> /dev/null

if [ "`date +%-d`" = "1" ]; then
	if [ "$LANG" != "en" ]; then
		echo "Haciendo copia para el backup mensual"
	else
		echo "Copying monthly backup"
	fi

	ln ${BACKUP_FILE} ${MONTHLY_DIR}

	if [ "$LANG" != "en" ]; then
		echo "Borrando los backups con mas de ${MONTHLY_BACKUPS} meses de antigüedad"
	else
		echo "Deleting backups older than ${MONTHLY_BACKUPS} month"
	fi
	${FIND} ${MONTHLY_DIR} -type f -daystart -name "backup-*" -mtime +$[$MONTHLY_BACKUPS * 31] -exec rm -Rf {} \; 2> /dev/null
fi

if [ "$LANG" != "en" ]; then
	echo "Uso actual de disco:"
else
	echo "Current disk usage:"
fi

du -shc *

if [ "$LANG" != "en" ]; then
	echo "Proceso de backup finalizado."
else
	echo "Backup process done."
fi