Linux : Backup avec Rsync et SSH versus TAR over SSH
Par Yoann le lundi, 16 mars 2009, 17:55 - L1nuX and c0 - Lien permanent
Voici un billet faisant suite à une problématique récente sur la sauvegarde de serveurs.
J'utilisais jusqu'a maintenant un "tar over ssh" pour faire mes sauvegarde, mais ceci s'avère aujourd'hui trop consommateur de bande passante du fait qu'il re-sauvegarde l'intégratilé des données tous les jours.
Je vous details la problématique, ainsi qu'une solution avec "rsync over ssh" dans la suite du billet.
Attention : Ce billet est en cours de rédaction.
Contexte :
Je dispose d'un serveur avec beaucoup de To disponible pour stocker mes sauvegardes, mais celui-ci n'est pas accesible depuis l'internet (pas d'adresse IPV4 public). Ce serveur de stockage lui peut par contre accéder a l'internet à travers du NAT.
Les sauvegardes ne peuvent donc être initié qu'a partir du serveur de stocakge et non pas a partir des hosts à sauvegarder.
Je ne veux pas non plus faire tourner un dameon rsync sur chacun des hosts, pour un problème de sécurité.
Les deux intératifs a prendre en compte sont :
- SSH n'ecoute pas forcement sur le port 22 (par default)
- L'utilisateur backup n'a pas les droits de lecture du tous les fichiers a sauvegarder, pourtant il faudra bien les sauvegarders.
La solution TAR over SSH
La solution TAR over SSH, utilisée jusqu'a maintenant fonctionnait comme ceci :
- L'utilisateur backup sur chacun des hosts a sauvegarder est présent dans le fichier /etc/sudoers
Cmnd_Alias TAR=/bin/tar backup ALL=NOPASSWD:TAR
Il peut ainsi a traver la commande TAR accèder en lecture à tous les fichiers.
Depuis le serveur de stocakge, il me suffit alors de lancer la commande suivante pour sauvegarder completement le repertoire /etc/ du server hosts à sauvegarder :
ssh -p 22 backup@server_ip "/usr/bin/sudo tar zpcf - /etc/ " > /backup/etc.tgz
- Nous pouvons choisir le port SSH
- Grace a sudo nous pouvons acceder a tous les fichiers via la commande tar
- Le résultat du TAR n'est pas ici renvoyé vers un fichier, mais vers la connexion SSH qui à l'autre bout va créer le fichier TGZ.
La solution RSYNC over SSH
La solution RSYNC over SSH, fonctionne comme ceci :
- L'utilisateur backup sur chacun des hosts a sauvegarder est présent dans le fichier /etc/sudoers
Cmnd_Alias RSYNC=/bin/tar backup ALL=NOPASSWD:RSYNC
Il peut ainsi a traver la commande RSYNC accèder en lecture à tous les fichiers.
Depuis le serveur de stocakge, il me suffit alors de lancer la commande suivante pour sauvegarder completement le repertoire /etc/ du server hosts à sauvegarder :
rsync -av --delete --inplace --rsync-path='sudo rsync' --rsh="ssh -p22" backup@server_ip:/etc/ /backup/etc/
- Nous pouvons choisir le port SSH
- Grace a sudo nous pouvons acceder a tous les fichiers via la commande RSYNC
- L'avantage ici d'utiliser rsync, c'est qu'il ne transfert que les nouveaux fichiers, ceux qui ont été mis à jours, et efface ceux qui n'existe plus.
Mise en pace de la solution de sauvegarde avec RSYNC over SSH
Mise en place des accès SSH sans authentification
Sur le serveur de stocakge (depuis l'utilisateur root) :
ssh-keygen -t dsa
Generating public/private dsa key pair. Enter file in which to save the key (/root/.ssh/id_dsa): /root/.ssh/id_dsa already exists. Overwrite (y/n)? y Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_dsa. Your public key has been saved in /root/.ssh/id_dsa.pub. The key fingerprint is: c7:4a:70:a4:de:eb:68:84:6f:f3:05:5f:09:dd:31:b5 backup02
Ne pas indiquer de passphrase, pour une authentification sans mot de passe. (dans ce cas seul la clef publique fera office d'identification)
Sur les hosts à sauvegarder :
Il nous suffit maintenant juste de copier le contenu du fichier /root/.ssh/id_dsa.pub du serveur de stocakge sur les hosts à sauvegader à la fin du fichier /home/backup/.ssh/authorized_keys. (Il se peut que ce fichier n'existe pas, il suffit de le créer).
Test :
Vous pouvez maintenant vous connecter en SSH sur les serveurs hosts avec l'utilisateur backup sans avoir à rentrer de mots de passe.
ssh backup@server_ip -p 22
Mise en place des outils pour les sauvegardes
Sur les hosts à sauvegarder :
Installer rsync et sudo
apt-get install rsync sudo
Editer le fichier /etc/sudoers pour y rajouter :
Cmnd_Alias RSYNC=/usr/bin/rsync exploit ALL=NOPASSWD:RSYNC
Notez qu'il vous faudra (même en root) changer les droits du fichier avant de l'éditer et les remettre avant de relancer sudo :
chmod 700 /etc/sudoers
Editer le fichier
chmod 440 /etc/sudoers /etc/init.d/sudo restart
Sur le serveur de stocakge :
Toutes les sauvegardes seront stocker dans le repertoire /backup comme ceci /backup/<host>/<date_YYYY-MM-DD>/
Pour lancer une sauvegarde manuellement :
rsync -av --progress --inplace --rsync-path='sudo rsync' --rsh='ssh -p22' backup@:/etc/ /backup/ /2009-03-10/etc/
Voici maintenant un script bash permettant de gérer les sauvegardes :
Celui, regarde tout d'abort si une sauvegarde de la veille existe, et si c'est le cas, il copie les fichiers de la veille dans le repertoire du jours avant de lancer le rsync, ce qui permet de limiter l'utilisation de bande passante tout en gardant un historique de sauvegardes.
#!/bin/bash
LocalBackupBase="/backup"
#---------- La configuration des hosts a backup ce trouve en fin de fichier ----------#
DateToday=$(date +%Y-%m-%d)
DateYesterday=$(date --date='1 days ago' +%Y-%m-%d)
RSYNC="/usr/bin/rsync"
function BackupDir() {
# Initialise Variables
RemoteLogin=$1;
RemoteHost=$2;
RemotePort=$3;
RemoteBackupDir=$4;
LocalBackupDir="$LocalBackupBase/$RemoteHost/$DateToday/$RemoteBackupDir";
echo " > [BACKUP-DIR] Backup $RemoteBackupDir on $RemoteHost to $LocalBackupDir"
if [ ! -d "$LocalBackupBase/$RemoteHost/$DateToday/$RemoteBackupDir" ]; then
echo " | Today local backup directory not exist : $LocalBackupBase/$RemoteHost/$DateToday/$RemoteBackupDir";
if [ ! -d "$LocalBackupBase/$RemoteHost/$DateYesterday/$RemoteBackupDir" ]; then
echo " | Yesterday backup directory not exist : $LocalBackupBase/$RemoteHost/$DateYesterday/$RemoteBackupDir";
echo " | Create today backup directory : $LocalBackupBase/$RemoteHost/$DateToday/$RemoteBackupDir";
mkdir -p $LocalBackupBase/$RemoteHost/$DateToday/$RemoteBackupDir
else
echo " | Yesterday backup directory exist : $LocalBackupBase/$RemoteHost/$DateYesterday/$RemoteBackupDir";
echo " | Create today backup directory : $LocalBackupBase/$RemoteHost/$DateToday";
mkdir -p $LocalBackupBase/$RemoteHost/$DateToday/
echo " | Copy file from yesterday to today backup directory";
mkdir -p $LocalBackupBase/$RemoteHost/$DateToday/$RemoteBackupDir
cp -R $LocalBackupBase/$RemoteHost/$DateYesterday/$RemoteBackupDir $LocalBackupBase/$RemoteHost/$DateToday/$RemoteBackupDir
fi
fi
echo " | Start at $(date +%Y-%m-%d) $(date +%H:%M:%S)"
$RSYNC -av --inplace --rsync-path='sudo rsync' --rsh="ssh -p$RemotePort" $RemoteLogin@$RemoteHost:$RemoteBackupDir $LocalBackupDir >> $LocalBackupBase/$RemoteHost/$DateToday/rsync-$DateToday.log
echo " | Finish at $(date +%Y-%m-%d) $(date +%H:%M:%S)"
}
function DeleteOlderThan() {
DayAgo=$1;
DateRemove=$(date --date="$DayAgo days ago" +%Y-%m-%d)
NumRemove=$(date --date="$DayAgo days ago" +%Y%m%d)
echo " > [DEL] Remove backup directory older than $DayAgo - $DateRemove"
for Host in `find $LocalBackupBase -maxdepth 1 -type d`; do
if [ $Host != $LocalBackupBase ]; then
for line in `find $Host -maxdepth 1 -type d`; do
if [ $line != $Host ]; then
DirDate=`echo "$line" | sed -e "s/\(.*\)\/\(.*\)\-\(.*\)\-\(.*\)/\2\3\4/"`
if [ $DirDate -lt $NumRemove ]; then
echo " | Remove backup directory : $line";
rm $line -Rf
fi
fi
done
fi
done
}
#---------- Parametrage des backups ----------#
#---------- Ne pas oublier d'installer sudo et rsync sur les hosts a backup ----------#
#On efface les backup de plus de 7 jours
DeleteOlderThan 7
#Backup du repertoire /tmp/ sur le host n°1 - accès SSH sur le port 22 (standard)
BackupDir backup 22 /tmp/
#Backup du repertoire /tmp/ sur le host n°2 - accès SSH sur le port 2222
BackupDir backup 2222 /tmp/
Commentaires
Votre information est très utile pour moi car j'ai eu le même problème récemment.
Ah les scripts bash pour gérer les sauvegardes... :)
A l'occasion, allez jeter un coup d'oeil à rsnapshot, c'est redoutablement simple et efficace.
Bonne continuation