Création de scripts de backup automatisés

Présentation

Cet article vise à renseigner les points suivants :

– Sauvegarder le contenu des bases manuellement
– Sauvegardes les fichiers manuellement
– Sauvegarder le contenu des bases automatiquement
– Sauvegardes les fichiers automatiquement
– Envoi automatique des données via FTP ou SSH
– Restauration des données

On verra ces parties une par une indépendamment, puis on analysera un modèle de script à utiliser

Sauvegarder le contenu d’une base de données

La commande à utiliser est toute simple et se fait via mysqldump :

mysqldump -u <utilisateur> -p’<mot_de_passe><nom_base> > <chemin_cible>.sql

Où :

utilisateur : est l’utilisateur SQL à utiliser. Il peut être soit l’utilisateur par défaut de la base, ou bien l’admin mysql
mot_de_passe : mot de passe de l’utilisateur SQL choisi
nom_base : la base de données à sauvegarder
<chemin_cible> : le chemin pour le fichier destination. Exemple : /tmp/backup.sql

On obtient au final un fichier .SQL que l’on peut exploiter.

Sauvegarder des fichiers

Pour sauvegarder des fichiers, on peut soit les transférer un par un via SSH (possible mais on préfère une solution plus générale ici) ; soit créer un .tar.gz que l’on pourra soit envoyer par SSH soit par FTP :

Il suffit de taper la commande :

tar cfzX <chemin_cible>.gz fichier_exclusion.txt <chemin_source>

où :

<chemin_cible>.gz est le chemin dans lequel il va créer notre archive
fichier_exclusion est le fichier qui contient d’éventuels fichiers à exclure lors de la création du tar
<chemin_source> qui est le chemin du dossier que l’on va archiver.

Envoi d’un ou plusieurs fichiers vers un serveur de backup :

Nous allons voir ici deux méthodes, par FTP et par SSH.

Commençons par la plus facile. Pour envoyer les données par SSH vers un serveur de backup, il suffit de taper la commande suivante :

scp <fichier_a_envoyer>.gz root@<serveur_backup>:<chemin_cible>

Sinon pour envoyer par FTP, c’est un peu plus complqué, il faudra scrpter ça dans un script bash. Vous pouvez utiliser le bloc suivant :

SERVER="<serveur_backup>"
USER="<utilisateur_FTP>"
PASS="<mdp_FTP>"
ftp -i -n $SERVER << END_SCRIPT
quote USER $USER
quote PASS $PASS
pwd
bin
mput $FILENAME.gz
quit
END_SCRIPT

 Script Complet de backup

Ci-dessous un script.bash complet qui reprend tout ce qui a été expliqué :

#!/bin/bash
#***********************************************************************#
 #             BACKUP SUR FTP OVH  par daniel Polli aka Dansteph         #
 #             ------------------                                        #
 # Ce script a lancer en cron tout les deux ou trois jours backup les    #
 # repertoire "/home" "/usr/local/apache/conf/" et "/var/named"          #
 # et les envois sur votre espace backup FTP. Editez les paramètres      #
 # ci-dessous.                                                           #
 #                                                                       #
 #***********************************************************************#
#########################################################################
 # PARAMETRES A EDITER
 #########################################################################
 SERVER="example.com"               #Serveur backup FTP
 USER="login_ftp"                   #Votre nom d'utilisateur
 PASS="pwd_ftp"                    #Votre password
 EMAIL="admin@votre_site"          #Pour envoi mail si backup echoue
 MAILSIOK="O"                    #Mettre "O" si on veut un mail aussi si backup ok
 SAVEDIR1="/home/backups/mysql"        #Backup optionnel SANS slash a la fin
 #########################################################################
#autres parametre a éditer seulement par confirmé------------------------
 FILENAME=`date +"%Y-%m-%d-%H-%M"`_fichier_backup.tar        #nom du fichier "[année-mois-jour-heure-minute]_fichier_backup.gz" (.gz est ajouté après)
 TEMPDIR="/home/backups/backupsite/"                         #repertoire temporaire de home pour creation tar
 EXCLUDEFILE="/home/backups/backupsite/backup_exclude.txt"   #ce fichier doit contenir les rep a exclure du backup
 #fin parametres, rien pour vous plus bas---------------------------------
STARTTIME=`date +%s`
#envoi des infos sur le log authpriv (le log "secure" sur OVH)
 DATE=`date +%H:%M:%S`
 logger -p authpriv.info "[$0] -->Debut de backup de $SAVEDIR a $DATE"
 echo "[$0] -->Debut de backup de $SAVEDIR1 a $DATE"
#compression dun ou plusieurs repertoires choisi en parametre
mysqldump -u <compte_SQL> -p'<mdp_SQL>' <nom_base> > $SAVEDIR1/backup_`date +"%Y-%m-%d-%H-%M"`.sql
 tar cfzX $TEMPDIR$FILENAME.gz $EXCLUDEFILE $SAVEDIR1
 RESULT=$?
 if [ "$RESULT" != "0" ]; then
 DATE=`date +%H:%M:%S`
 logger -p authpriv.info "[$0] -->ERREUR TAR à $DATE Backup NON effectué."
 echo "[$0] -->ERREUR TAR à $DATE Backup NON effectué."
 echo "Erreur TAR le backup FTP sur OVH non effectue" | mail -s 'ERREUR BACKUP FTP OVH' $EMAIL
 exit $RESULT
 fi
#Si vous voulez transférer par SSH le fichier de backup, vous pouvez utiliser cette commande :
 sshpass -p '<mdp_ssh_server_cible>' scp $TEMPDIR$FILENAME.gz root@<serveur_ssh_cible>:<chemin_cible>
#Si vous voulez transférer par FTP le fichier de backup, vous pouvez utiliser cet bloc :
 ftp -i -n $SERVER << END_SCRIPT
 quote USER $USER
 quote PASS $PASS
 pwd
 bin
 mput $FILENAME.gz
 quit
 END_SCRIPT
RESULT=$?
 FILESIZE=`ls -l $TEMPDIR$FILENAME.gz | awk '{print $5}'`
 FILESIZE=$(($FILESIZE/1000000))
rm -f $SAVEDIR1/*
 rm -f $TEMPDIR$FILENAME.gz
if [ "$RESULT" != "0" ]; then
 DATE=`date +%H:%M:%S`
 logger -p authpriv.info "[$0] -->ERREUR: ${CDERR[$RESULT]} à $DATE Backup NON effectué."
 echo "[$0] -->ERREUR: ${CDERR[$RESULT]} à $DATE Backup NON effectué."
 echo "[$0] -->ERREUR: ${CDERR[$RESULT]} à $DATE Backup NON effectué." | mail -s 'ERREUR BACKUP FTP OVH' $EMAIL $EMAIL1
 else
 TOTALTIME=$(((`date +%s`-$STARTTIME)/60))
 DATE=`date +%H:%M:%S`
 logger -p authpriv.info "[$0] -->Fin de backup normal de $SAVEDIR a $DATE. Durée: $TOTALTIME mn. Taille: $FILESIZE Mb"
 echo "[$0] -->Fin de backup normal de $SAVEDIR a $DATE.  Durée: $TOTALTIME mn. Taille: $FILESIZE Mb"
if [ "$MAILSIOK" = "O" ]; then
 echo -e "Backup effectué à $DATE Status: OK\nDurée du backup: $TOTALTIME minutes\nFichier: $FILENAME.gz transféré avec une taille de $FILESIZE Mb" | mail -s 'BACKUP FTP OVH OK' $EMAIL $EMAIL1
 fi
 fi
 exit $RESULT

En résumé, ce que fait le sciprt dans ce cas précis :

– Il dumpe le contenu de la base <nom_base> et la met dans un fichier $SAVEDIR1/backup_`date + »%Y-%m-%d-%H-%M »`.sql, qui est un fichier sql portant le nom backup suivi de la date et de l’heure, et ce dans le dossier SAVEDIR1 qui est /home/backups/mysql
– Il compresse le dossier /home/backups/mysql (qui contient notre backup) et il met le .tar créé dans $TEMPDIR$FILENAME.gz c’est à dire dans /home/backups/backupsite/date + »%Y-%m-%d-%H-%M »`_fichier_backup.tar
– Il envoie ce fichier via SSH ou FTP (à vous d’adapter selon vos besoins)
– Il supprime les fichiers temporaires créés (le .sql et le .tar.gz)
– Il envoie un email notifiant de l’état de l’opération

Automatisation en crontab

Comme on est très paresseux, rien de mieux que de mettre ça en exécution automatique…
On a donc créer un cron job, une exécution planifier du script selon la période choisie en quelque sorte.

Vous pouvez vous documenter sur la syntaxe, je ne vais pas m’y attarder ; je vais juste vous fournir un générateur automatique, c’est un jeu d’enfant.

Vous allez juste ici :

http://www.crontab-generator.org/

Et vous cochez ce que vous voulez. Dans l’exemple ci-dessous, on exécute le script /home/scripts/backup.sh tous les soit à minuit.

Sans titre1

Sans titre3

Il va alors vous sortir une ligne comme ça :

Sans titre4

Vous la copiez coller et dans votre linux vous tapez :

crontab -e

Vous rajouter votre ligne (0 0 * * * /home/scripts/backup.sh >/dev/null 2>&1)

et vous enregistrez et quittez.

et vous relancer votre cron :

/etc/init.d/cron restart

La commande peut varier en fonction de la distribution

C’est tout. Votre script s’exécutera tout seul chaque soir comme un grand.

Restauration d’un base à partir d’un fichier SQL

Prenons notre fichier backup.sql de tout à l’heure. Nous souhaitons le restaurer. Pour cela on utilise la commande inverse suivante :

mysql -u <utilisateur> -p <nom_base> –default_character_set utf8 < <chemin_source>.sql

Le paramètre utf8 est indiqué pour résoudre les problèmes d’accents qui ne passeront pas sinon.

Restauration des fichiers à de serveur à serveur (via SSH)

Pour décrire ce scénario, nous allons prendre un exemple concret :

Nous avons un serveur A, de production ; dont le site s’appelle mon_site_A et dont le chemin est le suivant : /var/www/vhosts/mon_site_A/httpdocs ; et il dispose d’un compte FTP nommé « compte_A » Dans la suite, c’est dans ce serveur que nous voulons restaurer les données
Nous avons un serveur B, de backup ; qui contient les fichiers de backup de mon_site_A dans le dossier /home/backups/mon_site_A/httpdocs.

Il y a 1001 façons de restaurer les fichiers, on peut par exemple :

– Télécharger les fichiers chez soi, et les uploader via Filezilla (si vous avez du temps à perdre allez y)
– Transférer les fichiers en SSH via le compte root (vous aurez plusieurs erreurs d’accès à cause de droits d’accès (des Forbidden)et vous deverez ensuite réarranger manuellement les droits des fichiers sur le serveur A à coup de chmod et chown…)
– Récupérer un .tar et le décompresser en .tar.gz dans le bon dossier (moui, bon..)
– Transférer les fichiers de serveur à serveur via SSH avec les compte FTP (si si..) de façon à garder les bons droits. On va détailler cette méthode :

Pour que cette méthode soit applicable, il faut que l’arborescence du site A existe en complet (non compressé) dans le serveur B.
NOTE : Cette méthode de transfert de serveur sert tout aussi bien à restaurer un backup qu’à migrer un site d’un serveur à un autre…

Donc, revenons à nos moutons :

On se connecte avec putty ou autre sur le serveur A (cible)

Tout en étant root, on fait un su vers le compte FTP du site :

# su - compte_A

Faites whoami pour vérifier qui vous êtes. Si vous êtes toujours root, c’est pas bon.

Dans ce cas, vous pouvez aussi taper :

# sudo - compte_A /bin/bash

Cette fois ça devrait être bon. (toujours vérifier avec whoami ; il doit vous renvoyer compte_A)

Une fois ceci fait, positionner vous dans le dossier de restauration :

$ cd /var/www/vhosts/mon_site_A/httpdocs

Remarquez que j’ai changé le # en $, car vous avez changé d’utilisateur

maintenat on va lancer le transfert à partir du serveur B avec le commande :

$ scp -r -v root@<serveur_B>:/home/backups/mon_site_A/httpdocs .

Où : root est le compte root du serveur B
:/home/backups/mon_site_A/httpdocs : ben c’est là où les données sont sauvegardées dans le serveur B
. c’est qu’on souhaite les copier dans le serveur A dans le chemin actuel, qui n’est autre que /var/www/vhosts/mon_site_A/httpdocs

Le serveur A va ainsi se connecter via SSH au server B en tant que root, puiser récursivement dans les dossiers de backup, et les stocker dans /var/www/vhosts/mon_site_A/httpdocs avec les droits système correspondant au compte compte_A.

Note : Dans le cas où dans le serveur B, les données ne sont pas éclatées mais sont dans une archive .tar, vous la décompressez d’abord avec tar xvfz nom_archive.tar.gz puis vous appliquez ce tuto.