Sauvegarde chiffrée d’un serveur dédié vers FTP
Je sais pas chez vous mais ici aujourd’hui c’est après-midi pluvieux. Et qui dit après-midi pluvieux dit maintenance sur mon petit serveur !
Je me suis attelé à la réécriture du script de sauvegarde du serveur, car mon vieux truc moisi avec rsync commençait à me faire un peu honte…
Dernière mise à jour le 17/07/2014 (mise à jour mineure)
J’ai donc commencé par poser la question à mon canard préféré et je suis tombé sur un site que je connais bien puisqu’il s’agit du blog de Nono, qui nous propose depuis février 2012 un script assez complet :
- Archivage / Compression des dossiers choisis dans un dossier local daté.
- Archivage / Compression des bases de données MySQL.
- Envoi du contenu du dossier de sauvegarde vers un FTP.
- Suppression du contenu du dossier local (ben oui pas la peine de garder une copie locale…).
- Génération de rapport et envoi par email.
Comme il ne convenait pas exactement à mon cas, j’y ai apporté quelques modifications :
- Les archives sont toutes chiffrées avec OpenSSL grâce à l’algorithme de chiffrement AES-256.
- Les bases de données MySQL sont archivées par base (une archive = une base) et non pas de manière globale.
- La liste des dossier à sauvegarder est placée dans un tableau, que le script va parcourir.
Sans compter une petite erreur par-ci / par-là 😀
Dépendances et fonctionnement du script
Ce script repose donc sur l’utilisation des outils OpenSSL, lftp, tar et gzip (et la commande mail au cas où). Le voici :
#!/bin/bash # Script de sauvegarde du serveur par Guillaume # Librement inspiré de http://blog.m0le.net/2012/02/17/le-petit-script-de-backup-de-nono/ date_start=`date +'%d/%m/%Y @ %H:%M:%S'`; format_date='%d%m%Y'; date=`date +${format_date}`; keepday="7"; keepdate=`date --date "-${keepday} days" +${format_date}`; backup_dir='/home/backup/'${date}; rapport='/home/backup/backup.log'; sql_pass='SQLPASSWORD'; archives_pass='PASSWORD'; ftp_host='ftp.mon-domaine.de'; ftp_user='FTPUSER'; ftp_pass='FTPPASSWORD'; mail='mail@mon-domaine.fr'; # Création du répertoire de backup et initialisation du rapport mkdir -p ${backup_dir} echo -e "Rapport du ${date_start}.\n\n" > ${rapport}; # Tableau des répertoires à sauvegarder backup=( '/etc/dossier1' '/home/dossier2' '/var/lib/dossier3' ) # Initialisation de la boucle et parcours du tableau index=0 length=${#backup[*]} while [ "$index" -lt "$length" ] do tar -jc ${backup[$index]} | openssl enc -e -aes256 -k ${archives_pass} -out ${backup_dir}/91-121-166-59.kimsufi.com${backup[$index]//\//_}.bz2.enc 2> /dev/null let "index = $index+1" done # Dump de MySQL for db in `mysql -uroot -h localhost -p${sql_pass} -Bse 'show databases'`; do if [ "$db" != "information_schema" ]; then mysqldump -uroot -p${sql_pass} -h localhost --events $db | gzip -9 | openssl enc -e -aes256 -k ${archives_pass} -out ${backup_dir}/91-121-166-59.kimsufi.com_sqldump_"$db"_${date}.sql.bz2.enc fi done # Mise à jour du rapport echo "Etat du dossier local :" >> ${rapport}; ls -lh ${backup_dir} -I rapport* >> ${rapport}; echo " " >> ${rapport}; # Envoi du dossier vers le FTP echo "Etat du dossier distant :" >> ${rapport}; lftp ftp://${ftp_user}:${ftp_pass}@${ftp_host} -e "mirror -R ${backup_dir} /${date} ; quit" >> ${rapport}; echo " " >> ${rapport}; # Suppression du dossier local echo "Suppression du dossier local : ${backup_dir}" >> ${rapport}; rm -rf ${backup_dir}; echo " " >> ${backup_dir}; # Suppression du dossier distant de plus de "$keepday" jour(s) echo -e "Suppression du dossier distant de plus de ${keepday} jours : ${keepdate}.\n" >> ${rapport}; echo "Etat du FTP :" >> ${rapport}; lftp ftp://${ftp_user}:${ftp_pass}@${ftp_host} -e "rm -rf ${keepdate} ;ls ; quit" >> ${rapport}; # Finalisation du rapport et envoi par email date_end=`date +'%d/%m/%Y @ %H:%M:%S'`; echo -e "\nSauvegarde terminee le ${date_end}." >> ${rapport}; mail -s "Rapport de sauvegarde du `date +%d\/%m\/%Y`" ${mail} < ${rapport}; |
Explications
Vous l’aurez compris, c’est la commande openssl enc -e -aes256 -k pass_de_larchive -out nom_sortie
qui chiffre tout cela. Pour déchiffrer une archive chiffrée de cette manière, utilisez simplement la commande suivante :
openssl enc -d -aes256 -k pass_de_larchive -in fichier_a_dechiffrer -out fichier_de_sortie |
Vous trouverez quelques autres moyens de chiffrer une archive sur k0n1k.com qui m’a beaucoup aidé.
Le résultat
Ce petit script vous génère donc un email journalier ressemblant à cela :
Rapport du 04/03/2014 @ 02:10:01. Etat du dossier local : total 911M -rw-r--r-- 1 root root 7,2M mars 4 02:24 91-121-166-59.kimsufi.com_etc.tar.bz2.enc -rw-r--r-- 1 root root 2,8M mars 4 02:24 91-121-166-59.kimsufi.com_home_guillaume.tar.bz2.enc [...] -rw-r--r-- 1 root root 2,3K mars 4 02:32 91-121-166-59.kimsufi.com_sqldump_phpmyadmin_04032014.sql.gz.enc -rw-r--r-- 1 root root 22K mars 4 02:32 91-121-166-59.kimsufi.com_sqldump_prod_pydio_04032014.sql.gz.enc -rw-r--r-- 1 root root 496 mars 4 02:32 91-121-166-59.kimsufi.com_sqldump_test_04032014.sql.gz.enc -rw-r--r-- 1 root root 22K mars 4 02:32 91-121-166-59.kimsufi.com_usr_ssl.tar.bz2.enc -rw-r--r-- 1 root root 547K mars 4 02:24 91-121-166-59.kimsufi.com_var_awstats.tar.bz2.enc -rw-r--r-- 1 root root 392M mars 4 02:32 91-121-166-59.kimsufi.com_webroot.tar.bz2.enc Etat du dossier distant : Suppression du dossier local : /home/backup/04032014 Suppression du dossier distant de plus de 7 jours : 25022014. Etat du FTP : drwx---r-x 4 96475 users 4 Mar 4 02:39 . drwx---r-x 4 96475 users 4 Mar 4 02:39 .. drwx---r-x 2 96475 users 24 Mar 3 17:52 03032014 drwx---r-x 2 96475 users 24 Mar 4 02:42 04032014 Sauvegarde terminee le 04/03/2014 @ 02:34:58. |
Si vous avez des idées ou des suggestions à apporter n’hésitez pas ! )
Cet article vous a plu ? Partagez-le sur les réseaux sociaux !




17/07/2014 @ 07:37
Hey, je viens de tomber sur ta modif !
Tu devrais faire une pull request sur github, je pense la valider sans trop de souci 🙂
17/07/2014 @ 11:33
Salut,
Ça fait déjà quelques semaines que je dois mettre à jour cet article parce que j’ai encore modifié le script (gestion des dossiers avec un tableau). Je jetterai un œil à ta proposition dès que j’ai du temps 🙂
25/07/2014 @ 08:43
J’ai vu que sur ton gitlab, il y avait une erreur pour les mots de passe SQL, non ? (j’avais pas envie de me créer un n-ième compte, désolé).
L37 : for db in `mysql -uroot -h localhost -pPassword -Bse ‘show databases’`; do
devrait être :
for db in `mysql -uroot -h localhost -p${$sql_pass} -Bse ‘show databases’`; do
non ? idem quelques lignes plus bas. l’idée étant de changer les variables qu’à un unique endroit (au debut du fichier).
25/07/2014 @ 09:52
C’est exact ! C’est corrigé 🙂
11/10/2014 @ 11:57
Hello,
tu n’aurais pas oublié dans ta correction un $ avant le sql_pass au niveau de :
for db in `mysql -uroot -h localhost -p${$sql_pass} -Bse ‘show databases’`; do
🙂
11/10/2014 @ 12:00
Non je crois que j’ai dit une bétise 🙂
24/09/2014 @ 16:05
Alors, du nouveau ? :p Pas eu de pull request ^^
Je viens de tomber la dessus, ca t’intéressera peut-être ?
http://www.wxproject.com/article16/sauvegarder-ses-bases-de-donnees-mariadb-mysql
24/09/2014 @ 16:07
Han désolé je suis très pris j’ai pas pris le temps. Et comme je m’apprête à partir un mois à l’autre bout du monde ça ne va pas arriver de si tôt !