Backup hors de la maison ?

Posted by

Description en bref:

  • Backup régulier et automatique vers un serveur dédié bon marché.
  • Conservation des backups date par date.
  • Utilisation d’outils gratuits et fiables.
  • La machine source est sous Windows ou *nix.
  • Optimisation de la bande passante consommée.
  • Optimisation de l’espace disque sur la machine de backup.
  • Encryption de la communication et du stockage sur le disque de backup.

Il ne faut pas se leurrer. Aujourd’hui tout est digital: les dossiers, les photos, les vidéos de famille, les e-mails, etc. On est à la merci d’un crash disque, d’un vol, d’une malveillance, ou bêtement d’une erreur de manipulation. Votre rejeton prête votre disque externe à un pote, qui va tout effacer pour faire de la place pour y copier 200 gigas de (c)rap inaudible.

Mon installation à la maison consiste en un serveur Windows allumé 24/24 7/7 avec raid5 et VSS disk shadowing. VSS permet de restaurer une version précédente d’un fichier altéré ou effacé accidentellement. Raid5 protège contre un crash disque. Mais quid en cas de vol du serveur, inondation, destruction par la foudre, hack, panne d’alim avec surtension… ?

Beaucoup me disent: “je copie sur un disque externe”.

  • A quand remonte la dernière copie ? Heu…
  • Où se trouve le disque externe ? Dans le bureau, dans le salon TV, … endroits propices au vol (même domestique).
  • Et si le disque source s’avère illisible durant la copie, où se trouve la copie précédente et complète ?

Ma solution de backup mise en place consiste à copier automatiquement via un “schedule” les répertoires sensibles (dossiers, photos), à destination d’un serveur dédié dans un datacentre. OVH propose un kimsufi en France avec 500 GB disque pour 12€ TVAC par mois, et en décembre 2012 a même fait une promo temporaire pour un serveur avec un disque de 2 TB pour 12€ au Canada. Ces serveurs n’ont qu’un seul disque non redondant, ce qui me semble acceptable pour une fonction de backup.
Il faut exclure les vKS à 6€ pour une raison technique que j’expliquerai plus loin.

[edit: le prix des Kimsufi a baissé depuis la rédaction de cet article]

Je ne suis pas à l’aise de savoir qu’une copie complète et en clair de mes données personnelles se trouve sur un serveur qui pourrait échapper à mon contrôle.

La solution est d’encrypter les backups sur le disque du serveur de backup.

Composants utilisés:

  • sur le serveur Windows 2008, cwrsync (-> voir l’onglet “free”) et le task scheduler
  • en hébergement: un serveur dédié Linux Debian6. Les backups se font avec un compte ordinaire non administrateur
  • sur ce serveur dédié, le composant système FUSE et le paquet encfs
  • une clé privée ssh générée sur le serveur Windows et déposée sur le serveur dédié dans ~/.ssh/authorized_keys2

Update: j’ajoute une version ‘shell script’ pour faire le backup d’une machine unix vers une machine unix.

Le premier backup risque de prendre vraiment longtemps. Via une ligne ADSL, compter 15 à 30 GB par 24 heures. Lors d’un changement d’adresse IP, le backup en cours est malheureusement interrompu. Il doit être relancé pour reprendre là où il était arrivé.

Ensuite grâce à la puissance de la commande rsync, lors des backups suivants, seuls les fichiers modifiés sont transmis. Mieux que ça, seules les portions modifiées du fichier sont transmises. C’est le cas des bases de données et des fichiers de stockage des mails.

Mise-à-jour 28 décembre 2012: jusqu’à présent, les fichiers supprimés sur le serveur d’origine n’étaient pas supprimés sur le serveur de backup. En cas de restauration complète d’un backup il n’est pas nécessairement souhaitable de récupérer aussi les fichiers qui avaient été effacés.

L’amélioration permet de retrouver des fichiers effacés il y a longtemps, mais aussi de récupérer un répertoire dans l’état où il était lors du backup le plus récent, ou à n’importe lequel des backups.

On va utiliser les fonctions de hard-linking sur le serveur de backup, que rsync gère magnifiquement bien. Chaque session de backup va générer une arborescence qui reflète fidèlement le contenu du répertoire source lors de cette session de backup. On indique aussi à rsync le nom du répertoire du backup précédent. Chaque fichier identique n’est évidemment pas copié. Néanmoins à l’arrivée, rsync crée un lien (hard link) entre le fichier du backup précédent et le backup en cours. Le même fichier se retrouve dans chacun des répertoires, mais il n’est stocké qu’une seule fois sur le disque du serveur de backup, et plusieurs entrées dans plusieurs répertoires y font référence. Si on efface un de ces fichiers identiques, on décrémente juste le nombre de références ; si ce nombre arrive à zéro, le contenu est effacé aussi.

Mise à jour 5 janvier 2013: Ma modification du 28 décembre amène un nouveau problème. Je procédais comme suit: renommer le backup précédent puis en créer un nouveau. Lorsqu’un fichier est identique entre le backup précédent et celui en cours, un hard-link est créé entre les deux copies identiques de ce fichier.
Problème: si le backup est interrompu en cours de traitement (par exemple suite à un changement d’adresse IP de la connexion ADSL), on se retrouve avec une arborescence incomplète à l’arrivée. Le prochain backup va devoir copier inutilement l’intégralité des fichiers qui manquent, alors que ces fichiers se trouvent dans l’avant-dernière version du backup.
J’adapte la procédure comme suit:

  1. identifier le dernier backup daté
  2. envoyer un nouveau backup en effectuant un différentiel par rapport à ce backup daté
  3. si le backup se termine normalement, dater ce nouveau backup.
  4. (s’il ne se termine pas normalement, le fragment déjà reçu sera réutilisé la prochaine fois)

Quelques détails pratiques maintenant:

Du côté Windows:

Installation de cwrsync freeware (sans interface graphique). Cwrsync s’installe dans Program Files (x86).
L’installation crée un sous-répertoire .ssh qu’il faudra recopier dans c:\users\administrator
Pour être tout-à-fait honnête j’ai installé cwrsync en 2010, et je ne me rappelle plus des détails.
Les commandes de backup proprement dites se trouvent dans un script cwrsync.cmd .
A la fin du script cwrsync.cmd, il va falloir ajouter une ou plusieurs lignes pour chaque répertoire à “backuper”

Je propose d’aller progressivement et de tester chaque étape.

Supposons que le serveur s’appelle backup.demees.net, que l’utilisateur unix sur ce serveur est bkp ; et que les répertoires à backuper sur le serveur Windows sont E:\Dossiers et F:\Photos

Sur le serveur de backup qui tourne sous Linux Debian, se connecter comme root et installer le paquet rsync

apt-get install rsync

Créer un utilisateur:

adduser bkp

(vous lui assignez un password, etc)

Ici vous allez sur le serveur Windows, dans c:\Program Files (x86)\cwrsync\.ssh
Vous ouvrez le fichier id_rsa.pub, copiez le contenu dans le presse-papiers.

Se connecter sous cet utilisateur bkp

mkdir .ssh
cd .ssh
cat > authorized_keys2

et collez le contenu du presse-papiers dans la commande cat du terminal Linux.

Terminez avec ^D

Si tout est correct, le script cwrsync sous Windows a le droit de se logguer sur le serveur Linux avec sa clé publique. Il n’y a pas de transmission de mot de passe.

Si vous avez configuré sshd sur un port non standard (autre que 22) vous veillerez à adapter les “-p 22” dans tous les exemples plus bas.

Maintenant on va lancer un backup d’un répertoire (pas trop grand pour commencer).

Editez le script cwrsync.cmd et ajoutez la ligne suivante à la fin:

rsync -r -t -O  -e "ssh -p 22" /cygdrive/e/Dossiers bkp@backup.demees.net:./testbackup/Dossiers/

Lancez le script, qui devrait demander de confirmer l’authenticité du serveur en face. Répondez “yes”.

A la fin de l’exécution du script, vérifiez le contenu du répertoire testbackup. Vous pouvez ensuite le supprimer.

Si tout va bien, on a fait un tiers du travail. Il faut maintenant automatiser cette tâche sur la machine Windows. Créer un “scheduled job” sous le même compte utilisateur que celui que vous avez utilisé jusqu’ici. Probablement “administrator”.

A vous de voir à quelle fréquence vous le lancerez.

On passe à la suite. J’avais dit que je voulais que mes backups soient encryptés. Nous allons créer un “file system encrypté”, et y déposer les backups.

La solution choisie nécessite les composants suivants sur la machine linux: fuse (inclus dans le kernel ou comme module) ; et encfs.
Remarque: dans l’offre bon marché d’OVH à 6€/mois (serveurs vKS), le composant ‘fuse’ n’est volontairement pas inclus dans le kernel. En plus l’espace disque est vraiment court.

Installer:

apt-get install libfuse2 encfs

Il faut permettre à l’utilisateur bkp d’utiliser la couche fuse.

addgroup  bkp fuse

Il est probable que vous deviez changer la permission sur le device:

chmod 660 /dev/fuse

Se déconnecter de l’utilisateur ‘root’ et se connecter sous ‘bkp’.

La home directory de ‘bkp’ est /home/bkp .

Encfs fonctionne comme suit: on a deux répertoires.
L’un est encrypté sur le disque.
L’autre est montré “en clair” via la couche logicielle encfs. Il est évident que le backup doit lire / écrire dans le second.

Un avantage de encfs est de ne pas nécessiter une préallocation d’espace disque dans une partition ou un gros fichier.

Je propose donc de créer le répertoire encrypté dans /home/bkp/.backup (répertoire caché sans intérêt pour les êtres humains) et le répertoire visible dans /home/bkp/backup

Initialisation:

encfs /home/bkp/.backup /home/bkp/backup

Prendre les réglages par défaut. Donner un mot de passe (idéalement 10 caractères min. avec chiffres, lettres, ponctuations).

Création d’un fichier “marqueur”:

echo OK > /home/bkp/backup/status

ls -l /home/bkp/backup /home/bkp/.backup
backup:
-rw-r--r-- 1 bkp bkp 3 Dec 19 02:00 status
.backup:
-rw-r--r-- 1 bkp bkp 11 Dec 19 02:00 78SOSac6uOk70uMirCsjAGkj

Encfs encrypte non seulement le contenu de chaque fichier, mais aussi leur nom.

Si on reboote le serveur, encfs n’est évidemment pas redémarré, ce qui est le but.
Il faut se connecter sur le serveur, et retaper exactement la même commande que celle utilisée pour l’intialisation. Sans cela, le disque dur ne contient que les versions encryptées, et on n’a pas accès aux fichiers utilisables.

Quelques lignes plus haut j’ai mis “OK” dans un fichier se trouvant dans le répertoire encrypté. Le script Windows pourra vérifier l’existence du fichier et son contenu avant de démarrer le backup.

Faites quelques tests.

Etape suivante: adapter le script cwrsync.cmd sous Windows. On vérifie l’existence du fichier status qui contient “OK”, puis on lance le backup.

rem (lignes à ajouter au bas du script cwrsync.cmd)
CD /D %~dp0
REM création d'une variable "dt" qui contient la date et l'heure au format YYYY-MM-DD-hhmmss. remplacer le blanc dans la date et l'heure par un zéro.

set d=%date: =0%
set t=%time: =0%
set dt=%d:~11,4%-%d:~8,2%-%d:~5,2%-%t:~0,2%%t:~3,2%%t:~6,2%

echo --==-- Starting on %dt% > cwrsync.log

del status.txt
ssh -p 22 bkp@backup.demees.net cat backup/status > status.txt
find "OK" status.txt && goto OK
echo ERROR
c:\blat240\full\blat.exe - -to me@example.com -subject "Server ZZ - backup not done because bkp@backup.demees.net not ready" -server smtp.example.com -f sender@example.com < nul
goto quit
:OK
set src=/cygdrive/e/Dossiers
set dst=Dossiers

REM récupérer le nom du dernier backup daté, dans la variable %last%
for /f "delims=" %%a in ('ssh -p 22 bkp@backup.demees.net "cd backup;ls -d %dst%.20*|tail -1"') do @set last=%%a

REM faire le backup, en cas de succès dater ce backup
rsync -r -t -O -e "ssh -p 22" --delete --link-dest=../%last% --log-file=cwrsync.log %src% bkp@backup.demees.net:backup/%dst%/ && ssh -p 22 bkp@backup.demees.net mv -Tvf backup/%dst% backup/%dst%.%dt%
REM même traitement pour le répertoire Photos
set src=/cygdrive/f/Photos
set dst=Photos
for /f "delims=" %%a in ('ssh -p 22 bkp@backup.demees.net "cd backup;ls -d %dst%.20*|tail -1"') do @set last=%%a
rsync -r -t -O -e "ssh -p 22" --delete --link-dest=../%last% --log-file=cwrsync.log %src% bkp@backup.demees.net:backup/%dst%/ && ssh -p 22 bkp@backup.demees.net mv -Tvf backup/%dst% backup/%dst%.%dt%

REM ===============================

REM envoyer un compte-rendu pas trop volumineux
find /v "cd..t......" cwrsync.log > cwrsync1.log
c:\blat240\full\blat.exe cwrsync1.log -to me@example.com -subject "Server ZZ - backup log" -server smtp.example.com -f sender@example.com

:quit

et la version ‘shell script’

#!/bin/bash
pid=$PPID
mkdir /tmp/$pid
cd /tmp/$pid
dt=`date +%FT%T|sed "s/-//g;s/://g"`
echo --==-- Starting on $dt > bkp-b1.log
rm -f status.txt
ssh -p 22 bkp@backup.demees.net cat backup/status > status.txt
grep OK status.txt
if [ $? != 0 ]; then
echo ERROR
mail -s "Server xxx - backup not done because bkp@backup not ready" me@example.be < /dev/null
cd /tmp
rm -r /tmp/$pid
exit 1
fi
src=/etc
dst=xx-etc
last=`ssh -p 22 bkp@backup.demees.net "(cd backup;ls -d $dst.20*)"|tail -1`
rsync -l -r -t -O -e "ssh -p 22" --delete --link-dest=../$last --log-file=bkp-b1.log $src bkp@backup.demees.net:backup/$dst/ && ssh -p 22 bkp@backup.demees.net mv -Tvf backup/$dst backup/$dst.$dt
grep -v "cd..t......" bkp-b1.log > bkp-b11.log
mail -s "Server xx - backup log" me@example.be <bkp-b11.log
cd /tmp
rm -r /tmp/$pid

 

En cas de nécessité, pour récupérer ces backups, utilisez FileZilla ou WinSCP. Indiquez que les noms de fichiers sont codés en UTF-8.

Le backup avec la date la plus récente reflète fidèlement l’état du serveur lors du dernier backup. Pour retrouver des fichiers effacés il y a longtemps, allez voir dans un des répertoires datés. S’il y a un répertoire non daté, il s’agit d’un backup interrompu et n’est probablement pas complet.

Il n’y a pas de script de maintenance des backups anciens. Pour effacer un backup ancien, utilisez la commande ‘rm -r’. Ne vous attendez pas à récupérer toute la place occupée par ce backup, en raison des hard-links.

(Révisé le 22 décembre 2012)
(Importante révision le 28 décembre 2012: mise en service du backup incrémental)
(Nouvelle révision le 5 janvier 2013, voir commentaires dans le texte)
(Révision le 5 mars 2013, ajout d’un shell script unix)