Muchos tenemos contratado un servicio de alojamiento, que suele incluir espacio para ubicar nuestras webs, y la posibilidad de crear una o varias bases de datos. Normalmente nos garantizan que toda la información contenida en el alojamiento está protegida por copias de seguridad, por sistemas redundantes, y que no debemos preocuparnos de que se pierda nada. Pero también es muy recomendable tener “en casa” una copia de esos datos, tanto por simple respaldo, como a la hora de realizar ciertas actualizaciones en nuestros proyectos.

Los métodos habituales para acceder y descargar el contenido web y las bases de datos suele ser bastante tedioso, y poco práctico si se quiere hacer periódicamente. Por ello he montado un script para facilitar la tarea, y que sólo tiene estos requerimientos:

  1. Posibilidad de ejecutarlo desde un equipo con Linux.
  2. Acceso al contenido de nuestro alojamiento web a través de FTP.
  3. Base de datos en servidor MySQL.
  4. Acceso al host de nuestro alojamiento vía SSH, con posibilidad de ejecutar la herramienta mysqldump.

Si cumplimos con estos requisitos ya podemos comenzar con la configuración necesaria.

En primer lugar instalaremos los paquetes necesarios para el envío de correos electrónicos desde la línea de comandos:

sudo apt-get install ssmtp mailutils

Luego configuramos el sistema ssmtp, que hará uso de un servidor SMTP externo, editando los siguientes archivos:

/etc/ssmtp/ssmtp.conf

mailhub=host_servidor_smtp_externo:25
FromLineOverride=YES
AuthUser=usuario_smtp
AuthPass=password_smtp

/etc/ssmtp/revaliases

usuario_que_ejecutará_el_script:usuario@dominio.com:host_servidor_smtp_externo:25

A continuación autorizaremos la conexión de nuestro equipo y usuario al host remoto vía SSH para que no pida contraseña, y así poder incluir estas conexiones en el script.

En primer lugar generamos un par de claves RSA desde nuestro equipo, dejando la contraseña en blanco:

ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/usuario/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/usuario/.ssh/id_rsa.
Your public key has been saved in /home/usuario/.ssh/id_rsa.pub.
The key fingerprint is:
xx:xx:xx:xx:xx usuario@host

Ahora creamos el directorio ~/.ssh en el host remoto (si no existe):

ssh usuario@host_remoto mkdir -p .ssh

Ahora añadimos nuestra clave pública (que hemos generado anteriormente) al final del fichero authorized_keys del host remoto, para lo que nos solicitará por última vez la contraseña:

cat .ssh/id_rsa.pub | ssh usuario@host_remoto 'cat >> .ssh/authorized_keys'

Con esto ya podemos hacer uso del script que viene a a continuación. La primera parte ejecuta remotamente un export de la base de datos que se le indique, enviando después un correo electrónico con el resultado del proceso. La segunda parte, sincroniza el contenido del alojamiento web con el de una carpeta local. Evidentemente sería inviable descargar cada vez todo el contenido remoto vía FTP, pero la herramienta lftp gestiona automáticamente la sincronización, descargando únicamente los archivos nuevos o modificados y eliminando los inexistentes. Para personalizar el script, es suficiente con modificar el contenido de las variables. También es posible ejecutar más de un export, o más de una sincronización, volviendo a establecer el valor de las variables y volviendo a llamar a las funciones correspondientes.

#!/bin/bash

# $SSH_USER = usuario conexión ssh
# $SSH_HOST = host conexión ssh
# $LOG_PATH = ruta destino log mysqldump
# $HTTP_LOG_PATH = ruta HTTP al destino log mysqldump
# $MYSQL_HOST = host conexión mysql
# $MYSQL_USER = usuario conexión mysql
# $MYSQL_PWD = contraseña conexión mysql
# $MYSQL_DB = base de datos mysql
# $MAIL_RCPT = destinatario correo electrónico

mysql_export() {

ssh $SSH_USER@$SSH_HOST "rm $LOG_PATH/mysql_$MYSQL_DB.log; mysqldump -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PWD --verbose --log-error=$LOG_PATH/mysql_$MYSQL_DB.log $MYSQL_DB >mysql_$MYSQL_DB.sql"
curl -s -w \n $HTTP_LOG_PATH/mysql_$MYSQL_DB.log | mail -s "Resultado export $MYSQL_DB" $MAIL_RCPT

}

remote_sync() {

lftp -c "set ftp:list-options -a;
open ftp://$FTP_USER:$FTP_PWD@$FTP_HOST;
lcd $LOCAL_PATH;
mirror --delete --verbose=3" > web_backup.log

cat web_backup.log | mail -s "Resultado sincronizacion" $MAIL_RCPT

}

SSH_USER=usuario
SSH_HOST=host.dominio.com
LOG_PATH=./mensajes
HTTP_LOG_PATH=http://dominio.com/mensajes
MYSQL_HOST=mysql.dominio.com
MYSQL_USER=usuario
MYSQL_PWD=password
MYSQL_DB=base_de_datos
MAIL_RCPT=usuario@dominio.com

mysql_export

FTP_HOST=ftp.dominio.com
FTP_USER=usuario
FTP_PWD=password
LOCAL_PATH=carpeta_local

remote_sync

Fuentes:

http://www.linuxproblem.org/art_9.html
http://serverfault.com/questions/24622/how-to-use-rsync-over-ftp
http://fal254.blogspot.com/2009/09/envia-correos-desde-tu-terminal-de.html