Envoyé par unreal
Introduction
Le but de ce dossier est de sauvegarder une machine Mac OS X vers un serveur dédié *nix de façon ultra sécurisée. Les prérequis sont les suivants :
Pour ce faire, nous allons utiliser plusieurs technologies intéressantes, notamment MacFuse, SSHFS et Rsync, selon le schéma suivant :
Cette méthodologie présente plusieurs avantages d'un pointe de vue sécurité :
Les prérequis
Le serveur peut être n'importe quelle machine *nix (Linux, FreeBSD, OpenSolaris...), à partir du moment où le protocole sftp et l'authentification par certificat sont activés. Pour cet article, une machine FreeBSD 8.0 a été utilisée.
Côté client OS X, il faut installer MacFuse et le binaire sshfs pour Macfuse :
Téléchargez le binaire sshfs, copiez-le et rendez-le exécutable :
Le Keypair SSH
Le client devra pouvoir se connecter automatiquement sur le serveur de backup. Vous devez donc générer un keypair SSH et le copier la clef publique sur le serveur de backup.
Sur le client :
Ensuite sur le serveur :
Création de l'image chiffrée
Mac OS X intègre un outil pratique pour manipuler les images de disques qui s'appelle hdiutil. Nous avons utiliser cet outil pour générer une image de disque chiffrée protégée avec un mot de passe complexe, puis scp pour le copier sur le serveur.
Vérifiez qu'il n'est pas nécessaire de taper le mot de passe pour copier le fichier avec scp.
L'image de type sparse occupera initialement quelques centaines de Mo sur le disque, mais s'adaptera automatiquement pour contenir jusqu'à 200Go.
Le script de sauvegarde
Copiez le script suivant dans /usr/local/bin et éditez la configuration, notamment les lignes en gras :
Exécutez-le avec le compte root, et la sauvegarde devrait démarrer automatiquement. Le script est conçu de telle façon à détecter les erreurs pour adopter un comportement intelligent et envoyer des e-mails d'avertissement en cas d'erreur bloquante.
L'exécution normale du script doit ressembler à ceci :
La sauvegarde initiale peut être assez longue, surtout si vous avez beaucoup de données à envoyer. Les sauvegardes successives devraient être rapides grâce à rsync qui n'enverra que les nouveaux fichiers.
Automatisation et conclusion
Vous allez bien entendu utiliser cron pour automatiser l'exécution du script de backup :
Voilà, c'est fini. Vous bénéficiez maintenant d'une sauvegarde automatisée et ultra sécurisée de vos données vers un serveur dédié.
Comme toujours, n'hésitez à me faire des retours via le système de commentaires ou message privé.
Historique
- 20100925 - version initiale
- 20101008 - améliorations du script
Le but de ce dossier est de sauvegarder une machine Mac OS X vers un serveur dédié *nix de façon ultra sécurisée. Les prérequis sont les suivants :
- L'image déposée sur le serveur dédié doit être chiffrée
- La sauvegarde doit être initiée par le client
- La communication entre le client Mac et le serveur doit être sécurisée
- La sauvegarde doit se faire de façon automatisée
- Après la sauvegarde initiale, les sauvegardes successives doivent être rapides
Pour ce faire, nous allons utiliser plusieurs technologies intéressantes, notamment MacFuse, SSHFS et Rsync, selon le schéma suivant :
Cette méthodologie présente plusieurs avantages d'un pointe de vue sécurité :
- L'image de disque sur le serveur est chiffrée en AES 128 ou 256 bits ; elle sera totalement inexploitable si le serveur est compromis
- Comme la sauvegarde est initiée par le client, il sera très complexe de compromettre le client à partir du serveur
- La couche SSHFS protège totalement d'attaques de type man in the middle ; le client connaît l'empreinte du serveur SSH, si celle-ci devait changer la communication serait interrompue
Les prérequis
Le serveur peut être n'importe quelle machine *nix (Linux, FreeBSD, OpenSolaris...), à partir du moment où le protocole sftp et l'authentification par certificat sont activés. Pour cet article, une machine FreeBSD 8.0 a été utilisée.
Côté client OS X, il faut installer MacFuse et le binaire sshfs pour Macfuse :
- http://code.google.com/p/macfuse/downloads/list
- http://code.google.com/p/macfuse/wiki/MACFUSE_FS_SSHFS
Téléchargez le binaire sshfs, copiez-le et rendez-le exécutable :
cp ~/sshfs-static-leopard /usr/local/bin/sshfs
chmod +x /usr/local/bin/sshfs
chmod +x /usr/local/bin/sshfs
Le Keypair SSH
Le client devra pouvoir se connecter automatiquement sur le serveur de backup. Vous devez donc générer un keypair SSH et le copier la clef publique sur le serveur de backup.
Sur le client :
# mkdir ~/.ssh
# chmod 700 ~/.ssh
# ssh-keygen -q -f ~/.ssh/id_rsa -t rsa
# scp ~/.ssh/id_rsa.pub username@hostname:~/id_rsa.pub
# chmod 700 ~/.ssh
# ssh-keygen -q -f ~/.ssh/id_rsa -t rsa
# scp ~/.ssh/id_rsa.pub username@hostname:~/id_rsa.pub
Ensuite sur le serveur :
$ mkdir ~/.ssh
$ chmod 700 ~/.ssh
$ cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
$ mkdir backups
$ chmod 700 ~/.ssh
$ cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
$ mkdir backups
Création de l'image chiffrée
Mac OS X intègre un outil pratique pour manipuler les images de disques qui s'appelle hdiutil. Nous avons utiliser cet outil pour générer une image de disque chiffrée protégée avec un mot de passe complexe, puis scp pour le copier sur le serveur.
Vérifiez qu'il n'est pas nécessaire de taper le mot de passe pour copier le fichier avec scp.
# hdiutil create -size 200g -encryption AES-128 -fs HFS+J -type SPARSE -volname Offsite_Backup Offsite_Backup
Enter a new password to secure "Offsite_Backup.sparseimage": <votremotdepasse>
# scp Offsite_Backup.sparseimage username@hostname:~/backups/
Enter a new password to secure "Offsite_Backup.sparseimage": <votremotdepasse>
# scp Offsite_Backup.sparseimage username@hostname:~/backups/
L'image de type sparse occupera initialement quelques centaines de Mo sur le disque, mais s'adaptera automatiquement pour contenir jusqu'à 200Go.
Le script de sauvegarde
Copiez le script suivant dans /usr/local/bin et éditez la configuration, notamment les lignes en gras :
#!/bin/bash
############################################################
# Filename: securebackup.sh #
# Description: secure push backup script for OS X using #
# encrypted AES sparse disk images and sshfs #
# file transfers. #
# Last update: 20100929 #
# Changelog: v1.0 - initial version #
# v1.1 - improved rsync error handling #
# v1.11 - various bug fixes #
# v1.12 - return value bugfix in senderror #
# v1.13 - fixed PATH #
############################################################
#<Config>
BACKUPHOST=backup.serveur.fr
EMAILTO=root@localhost
SSHFSBIN=/usr/local/bin/sshfs
SSHFSMOUNT=/Volumes/$BACKUPHOST
SSHFSPARAM="toto@$BACKUPHOST:/home/backups"
SPARSEIMGPW=motdepasse
SPARSEIMGPATH=$SSHFSMOUNT/Offsite_Backup.sparseimage
# Space separated list, no trailing slashes.
SYNC_DIR="/net/nas.localdomain/usr/home/exports/backup \
/net/nas.localdomain/usr/home/exports/Web \
/net/nas.localdomain/usr/home/exports/work \
/private/etc \
/private/var/cron/tabs \
/private/var/www \
/Users/unreal \
/usr/local"
#</Config>
export PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
# Functions
function senderror {
MSG=$1
SPARSEMOUNT=$2
echo "The following error occured:"
echo " $MSG"
echo "Backup quitted with the following error: $MSG" | mail -s "Backup error on $HOSTNAME" $EMAILTO
echo
# We'll try to unmount the filesystems anyway.
echo -n "-> Trying to unmount filesystems ... "
[ "$SPARSEMOUNT" ] && hdiutil detach "$SPARSEMOUNT" 2>/dev/null >/dev/null
sleep 2
umount "$SSHFSMOUNT" 2>/dev/null
RV=$?
[ $RV -ne 0 ] && echo "Fail"
[ $RV -eq 0 ] && echo "OK"
exit 1
}
# Check SSHFS isn't already mounted
echo -n "-> Checking mounts ... "
CHECK=`mount | grep $SSHFSMOUNT`
[ "$CHECK" ] && echo "Fail" && senderror "SSHFS already mounted."
echo "OK"
# Mount SSHFS share
echo -n "-> Mounting SSHFS to $SSHFSMOUNT ... "
[ ! -d "$SSHFSMOUNT" ] && mkdir $SSHFSMOUNT
$SSHFSBIN $SSHFSPARAM $SSHFSMOUNT 2>/dev/null
RV=$?
sleep 2
[ $RV -ne 0 ] && echo "Fail" && senderror "sshfs command returned error $RV."
echo "OK"
# Mounting crypted image file
echo -n "-> Mounting $SPARSEIMGPATH ... "
[ ! -f "$SPARSEIMGPATH" ] && echo "Fail" && senderror "Sparse image file not found."
CHECK=`echo -n "$SPARSEIMGPW" | hdiutil attach -stdinpass $SPARSEIMGPATH 2>/dev/null`
RV=$?
[ $RV -ne 0 ] && echo "Fail" && senderror "hdiutil returned error $RV."
# Work out mount path
SPARSEMOUNT=`echo -n "$CHECK" | grep "Apple_HFS" | awk '{ print $3; }'`
echo "OK (mounted to $SPARSEMOUNT)"
# Backup
for ONEDIR in $SYNC_DIR; do
if [ ! -d "$SPARSEMOUNT/$HOSTNAME$ONEDIR" ]; then
mkdir -p "$SPARSEMOUNT/$HOSTNAME$ONEDIR"
fi
echo -n "-> Backing-up $ONEDIR ... "
rsync --archive --delete --compress $ONEDIR `dirname "$SPARSEMOUNT/$HOSTNAME$ONEDIR"` 2>/dev/null >/dev/null
RV=$?
[ $RV -ne 0 ] && [ $RV -ne 23 ] && [ $RV -ne 24 ] && echo "Fail" && senderror "rsync returned error $RV." "$SPARSEMOUNT"
echo -n "OK"
[ $RV -eq 23 ] && echo -n " (partial)"
[ $RV -eq 24 ] && echo -n " (partial, some files vanished before they were copied)"
echo
done
# Unmounting
echo -n "-> Unmounting $SPARSEMOUNT ... "
hdiutil detach "$SPARSEMOUNT" 2>/dev/null >/dev/null
RV=$?
sleep 2
[ $RV -ne 0 ] && echo "Fail" && senderror "hdiutil returned error $RV."
echo "OK"
echo -n "-> Unmounting $SSHFSMOUNT ... "
umount "$SSHFSMOUNT" 2>/dev/null
RV=$?
[ $RV -ne 0 ] && echo "Fail" && senderror "umount command returned error $RV."
echo "OK"
exit 0
############################################################
# Filename: securebackup.sh #
# Description: secure push backup script for OS X using #
# encrypted AES sparse disk images and sshfs #
# file transfers. #
# Last update: 20100929 #
# Changelog: v1.0 - initial version #
# v1.1 - improved rsync error handling #
# v1.11 - various bug fixes #
# v1.12 - return value bugfix in senderror #
# v1.13 - fixed PATH #
############################################################
#<Config>
BACKUPHOST=backup.serveur.fr
EMAILTO=root@localhost
SSHFSBIN=/usr/local/bin/sshfs
SSHFSMOUNT=/Volumes/$BACKUPHOST
SSHFSPARAM="toto@$BACKUPHOST:/home/backups"
SPARSEIMGPW=motdepasse
SPARSEIMGPATH=$SSHFSMOUNT/Offsite_Backup.sparseimage
# Space separated list, no trailing slashes.
SYNC_DIR="/net/nas.localdomain/usr/home/exports/backup \
/net/nas.localdomain/usr/home/exports/Web \
/net/nas.localdomain/usr/home/exports/work \
/private/etc \
/private/var/cron/tabs \
/private/var/www \
/Users/unreal \
/usr/local"
#</Config>
export PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
# Functions
function senderror {
MSG=$1
SPARSEMOUNT=$2
echo "The following error occured:"
echo " $MSG"
echo "Backup quitted with the following error: $MSG" | mail -s "Backup error on $HOSTNAME" $EMAILTO
echo
# We'll try to unmount the filesystems anyway.
echo -n "-> Trying to unmount filesystems ... "
[ "$SPARSEMOUNT" ] && hdiutil detach "$SPARSEMOUNT" 2>/dev/null >/dev/null
sleep 2
umount "$SSHFSMOUNT" 2>/dev/null
RV=$?
[ $RV -ne 0 ] && echo "Fail"
[ $RV -eq 0 ] && echo "OK"
exit 1
}
# Check SSHFS isn't already mounted
echo -n "-> Checking mounts ... "
CHECK=`mount | grep $SSHFSMOUNT`
[ "$CHECK" ] && echo "Fail" && senderror "SSHFS already mounted."
echo "OK"
# Mount SSHFS share
echo -n "-> Mounting SSHFS to $SSHFSMOUNT ... "
[ ! -d "$SSHFSMOUNT" ] && mkdir $SSHFSMOUNT
$SSHFSBIN $SSHFSPARAM $SSHFSMOUNT 2>/dev/null
RV=$?
sleep 2
[ $RV -ne 0 ] && echo "Fail" && senderror "sshfs command returned error $RV."
echo "OK"
# Mounting crypted image file
echo -n "-> Mounting $SPARSEIMGPATH ... "
[ ! -f "$SPARSEIMGPATH" ] && echo "Fail" && senderror "Sparse image file not found."
CHECK=`echo -n "$SPARSEIMGPW" | hdiutil attach -stdinpass $SPARSEIMGPATH 2>/dev/null`
RV=$?
[ $RV -ne 0 ] && echo "Fail" && senderror "hdiutil returned error $RV."
# Work out mount path
SPARSEMOUNT=`echo -n "$CHECK" | grep "Apple_HFS" | awk '{ print $3; }'`
echo "OK (mounted to $SPARSEMOUNT)"
# Backup
for ONEDIR in $SYNC_DIR; do
if [ ! -d "$SPARSEMOUNT/$HOSTNAME$ONEDIR" ]; then
mkdir -p "$SPARSEMOUNT/$HOSTNAME$ONEDIR"
fi
echo -n "-> Backing-up $ONEDIR ... "
rsync --archive --delete --compress $ONEDIR `dirname "$SPARSEMOUNT/$HOSTNAME$ONEDIR"` 2>/dev/null >/dev/null
RV=$?
[ $RV -ne 0 ] && [ $RV -ne 23 ] && [ $RV -ne 24 ] && echo "Fail" && senderror "rsync returned error $RV." "$SPARSEMOUNT"
echo -n "OK"
[ $RV -eq 23 ] && echo -n " (partial)"
[ $RV -eq 24 ] && echo -n " (partial, some files vanished before they were copied)"
echo
done
# Unmounting
echo -n "-> Unmounting $SPARSEMOUNT ... "
hdiutil detach "$SPARSEMOUNT" 2>/dev/null >/dev/null
RV=$?
sleep 2
[ $RV -ne 0 ] && echo "Fail" && senderror "hdiutil returned error $RV."
echo "OK"
echo -n "-> Unmounting $SSHFSMOUNT ... "
umount "$SSHFSMOUNT" 2>/dev/null
RV=$?
[ $RV -ne 0 ] && echo "Fail" && senderror "umount command returned error $RV."
echo "OK"
exit 0
Exécutez-le avec le compte root, et la sauvegarde devrait démarrer automatiquement. Le script est conçu de telle façon à détecter les erreurs pour adopter un comportement intelligent et envoyer des e-mails d'avertissement en cas d'erreur bloquante.
L'exécution normale du script doit ressembler à ceci :
-> Checking mounts ... OK
-> Mounting SSHFS to /Volumes/backup.serveur.fr ... OK
-> Mounting /Volumes/backup.serveur.fr/Offsite_Backup.sparseimage ... OK (mounted to /Volumes/Offsite_Backup)
-> Backing-up /net/nas.localdomain/usr/home/exports/backup ... OK
-> Backing-up /net/nas.localdomain/usr/home/exports/Web ... OK (partial)
-> Backing-up /net/nas.localdomain/usr/home/exports/work ... OK
-> Backing-up /private/etc ... OK
-> Backing-up /private/var/cron/tabs ... OK
-> Backing-up /private/var/www ... OK
-> Backing-up /Users/unreal ... OK
-> Backing-up /usr/local ... OK
-> Unmounting /Volumes/Offsite_Backup ... OK
-> Unmounting /Volumes/backup.serveur.fr ... OK
-> Mounting SSHFS to /Volumes/backup.serveur.fr ... OK
-> Mounting /Volumes/backup.serveur.fr/Offsite_Backup.sparseimage ... OK (mounted to /Volumes/Offsite_Backup)
-> Backing-up /net/nas.localdomain/usr/home/exports/backup ... OK
-> Backing-up /net/nas.localdomain/usr/home/exports/Web ... OK (partial)
-> Backing-up /net/nas.localdomain/usr/home/exports/work ... OK
-> Backing-up /private/etc ... OK
-> Backing-up /private/var/cron/tabs ... OK
-> Backing-up /private/var/www ... OK
-> Backing-up /Users/unreal ... OK
-> Backing-up /usr/local ... OK
-> Unmounting /Volumes/Offsite_Backup ... OK
-> Unmounting /Volumes/backup.serveur.fr ... OK
La sauvegarde initiale peut être assez longue, surtout si vous avez beaucoup de données à envoyer. Les sauvegardes successives devraient être rapides grâce à rsync qui n'enverra que les nouveaux fichiers.
Automatisation et conclusion
Vous allez bien entendu utiliser cron pour automatiser l'exécution du script de backup :
0 5 * * * /usr/local/bin/securebackup.sh
Voilà, c'est fini. Vous bénéficiez maintenant d'une sauvegarde automatisée et ultra sécurisée de vos données vers un serveur dédié.
Comme toujours, n'hésitez à me faire des retours via le système de commentaires ou message privé.
Historique
- 20100925 - version initiale
- 20101008 - améliorations du script
Posté le 24/09/10 à 16:56