Copias de seguridad de bases de datos automatizadas [bash]
21 septiembre 2014
Sabemos lo importante que es realizar copias de seguridad pero a veces es algo que descuidamos o no se hace muy a menudo, por ello en esta ocasión hemos realizado un script en Bash para automatizar esta tarea en servidores Linux, en concreto para las copias de seguridad de nuestras bases de datos MySQL.
El script se encargará de exportar las bases de datos indicadas a SQL, posteriormente comprimirlas en ZIP (con una contraseña, opcional) y finalmente enviarlas a un servidor FTP remoto para aportar mayor seguridad.
Script
#!/bin/bash # AUTHOR: SecurityNull # VERSION: 1.1.0 # LAST UPDATE DATE: 22/09/2014 # FTP FTP_HOST="ftp.securitynull.net 21" FTP_USERNAME="securitynull" FTP_PASSWORD="securitynull" FTP_FOLDER="/backups/" # DATABASE DATABASE_USERNAME="root" DATABASE_PASSWORD="secret" # FILE FILE_PASSWORD="SecurityNull.0x00" FILE_EXT="zip" # DATE current_time=$(date +%H) current_date=$(echo `date +%d-%b-%Y` | tr '[:upper:]' '[:lower:]') current_date_time=$(date +%H-%M_%d-%m-%Y) # Name databases database[0]="database_1" database[1]="database_2" database[2]="database_3" function sentToFTP { ftp -in $FTP_HOST << EOF user $FTP_USERNAME $FTP_PASSWORD cd $FTP_FOLDER mkdir $current_date cd $current_date mkdir $1 cd $1 binary put $2 bye EOF } for db in ${database[@]}; do sql_file=${db}_[${current_date_time}].sql db_file="${db}_(${current_time})" # Export databases in SQL format /usr/bin/mysqldump --user=$DATABASE_USERNAME --password=$DATABASE_PASSWORD $db > $sql_file # Compress SQL file (with optional password) if [ -z "$FILE_PASSWORD" ]; then zip -q -r "$db_file.$FILE_EXT" "$sql_file" else zip -q -P "${db}_${FILE_PASSWORD}" -r "$db_file.$FILE_EXT" "$sql_file" fi # Delete SQL file rm $sql_file if [ -n "$FTP_HOST" ]; then # Send databases to remote FTP sentToFTP $db $db_file.$FILE_EXT # Remove compressed database rm $db_file.$FILE_EXT fi done
Es necesario modificar en el script las constantes con nuestros datos de acceso del FTP y base de datos, además de añadir los nombres de las bases de datos que nos interesen al array llamado “database”.
Para almacenar los datos de forma local sin enviar las copias de seguridad a un servidor FTP remoto, dejar la constante FTP_HOST vacía.
FTP_HOST=""
Si no queremos establecer una contraseña a los archivos comprimidos, sólo habría que dejar la constante FILE_PASSWORD en blanco.
FILE_PASSWORD=""
NOTA: Si usamos Parallels Plesk Panel podemos modificar la variable DATABASE_PASSWORD para obtener acceso root a la base de datos sin especificar la contraseña.
DATABASE_PASSWORD=$(/bin/cat /etc/psa/.psa.shadow)
A continuación debemos guardar este script como un archivo .sh y darle permisos de ejecución (chmod +x backup_dbs.sh). Para automatizarlo necesitamos crear un cron de la siguiente forma:
0 * * * * root /var/usr/backup_dbs.sh
En este ejemplo el cron se ejecutaría cada hora, pero podemos modificarlo a nuestro gusto o necesidades.
Por último necesitamos reiniciar el servicio cron.
/etc/init.d/cron restart
Conclusión
Es muy importante realizar copias de seguridad a diario y de esta forma tendremos una copia de seguridad, cada hora, de todas nuestras bases de datos en un segundo servidor.
Se recomienda ofuscar el script y cifrar las claves para evitar que un atacante obtenga con facilidad las claves de acceso al FTP o base de datos.
Encontrados mecanismos de vigilancia ocultos en iOS Vulnerabilidad crítica en sistemas Unix, Linux y Mac (CVE-2014-6271) [ShellShock]
Muchas gracias por el script!
Solo un comentario y una duda:
En plesk (por lo menos en la 12.5) para que funcione el pass hay que poner user: admin y el pass:
DATABASE_PASSWORD=”`cat /etc/psa/.psa.shadow`”
Por otro lado al ejecutarlo directamente me aparece este error:
Cannot create a file when that file already exists.
Eso borrando del ftp todos los archivos antes de probar.
Aunque aparentemente todo funciona correcto. ¿es normal?
Muchas gracias.
Hola Juanjo
`cat /etc/psa/.psa.shadow` y $(cat /etc/psa/.psa.shadow) es lo mismo
El error que te aparece quizás sea de mysqldump o zip porque tienes un archivo dump ya creado con el mismo nombre. En este caso antes de estas instrucciones coloca
Gracias por leernos, un saludo!
Buenos días.
Estoy tratando de utilizar este bash en mi servidor, cuando reemplazo las variables y lo ejecuto me sale el siguiente mensaje:
backups1.sh: 31: backups1.sh: function: not found
(directory-name) (local-file) (remote-file)
backups1.sh: 43: backups1.sh: Syntax error: “}” unexpected
Evidencio de que cuando ejecuto el script me alcanza a llegar hasta el FTP creado y me crea las carpetas especificas pero no me alcanza a realizar la copia de seguridad de la base de datos mysql.
Agradezco de su colaboración.
Buenas tardes Cristian
Revisa que tengas instalado el cliente FTP, si no es así ejecuta este comando si usas Linux Debian:
# apt-get install ftp
Un saludo!