Auteur Sujet: Linux: Script bash de sauvegarde incrémentielle basé sur SSH  (Lu 3231 fois)

0 Membres et 1 Invité sur ce sujet

vivien

  • Administrateur
  • *
  • Messages: 38 758
    • Twitter LaFibre.info
Script bash simple pour faire une sauvegarde incrémentielle et différentielle d'un serveur et garder plusieurs sauvegardes, en ne stockant que les différentes entre-elles

Je pense que l'actualité va rappeler à beaucoup la nécessite de faire des sauvegardes à distance.

Pour un particulier ou une petite entreprise, c'est n'est pas forcément simple.

Voici le script que j'utilise depuis 10 ans, basé sur un script crée par Bad Max que j'ai adapté à mon besoin par exemple en vérifiant que le port SSH est ouvert avant de lance la sauvegarde, sans quoi cela fait une sauvegarde vide et la sauvegarde suivant est une sauvegarde intégrale.

Le principe se base sur des liens physique proposé par Linux : Cela permet de donner plusieurs noms/chemin d'accès à un même fichier en pointant sur un numéro de fichier. En interne, Linux enregistre les fichiers sur la base d'un numéro (appelé numéro d'index ou inode) et pas sur la base d'un nom. Un fichier peut donc avoir plusieurs noms, et existera tant qu'il est utilisé dans une des sauvegarde. Quand aucune sauvegarde n'utilise l'inode le fichier est supprimé. Contrairement aux liens symboliques, les liens physique ne peuvent pointer que vers un autre élément du même système de fichiers.

Donc chacune des sauvegarde appariait comme une sauvegarde complète et non une sauvegarde différentielle. Toutefois sur le disque dur la place occupée est celle d'une sauvegarde différentielle pour toutes les sauvegardes, sauf la plus ancienne qui prend la place d'une sauvegarde complète.

Le script bash :

#!/bin/bash
# Script de sauvegarde incrémentale d'un serveur ou PC Linux via SSH
# Version du 11/03/2021 pour Ubuntu / Debian / Raspbian / Linux Mint
# Dépendance à installer : sudo apt install tcptraceroute
# Pour ne pas demander de mot de passe, il faut une connexion SSH avec une clé au format RSA
# Créé par Olivier Bedouet (Bad Max) et Vivien Guéant
# Ce script est un logiciel libre que vous pouvez redistribuer ou modifier suivant la GNU GPLv3

#### Paramètres à personnaliser ####
DOMAINE=monserveur.fr # nom de domaine du serveur à sauvegarder
NB_INCR=7 # Nombre de sauvegardes incrémentiel à garder
PORT_SSH=2222 # port où le SSH du serveur écoute (22 par défaut)
DEBIT_MAX=9000 # limite de bande passante, en ko par seconde, pour que la sauvegarde ne sature pas le réseau
REP_SAV=/home/sauvegarde # dossier où placer la sauvegarde en local
REP_SRC='
monserveur.fr:/etc/apache2
monserveur.fr:/home/mondossier1
monserveur.fr:/home/mondossier2
monserveur.fr:/home/mondossier3
' # Liste des dossiers à sauvegarder sur le serveur distant
FILE_ERR=${REP_SAV}/${DOMAINE}/log-${DOMAINE}.err # Emplacement du fichier qui log les éventuelles erreurs

#### Étape N°1: Test de l'ouverture du port TCP utilisé par SSH ####
echo -n "Test de l'ouverture du port ${PORT_SSH} : "
ttr=`tcptraceroute -q 1 ${DOMAINE} ${PORT_SSH} 2>&1`
if echo "${ttr}" | egrep -i "\[open\]" >/dev/null 2>&1
then
   echo "Port ${PORT_SSH} ouvert sur ${DOMAINE}"
else # Port SSH fermé, on quitte pour ne pas avoir une sauvegarde vide
   echo "Port ${PORT_SSH} fermé sur ${DOMAINE} : pas de sauvegarde"
   echo
   echo "!!!! ÉCHEC DE LA SAUVEGARDE !!!!"
   exit
fi

#### Étape N°2: Création du fichier de log des erreurs ####
if [ ! -d ${REP_SAV}/${DOMAINE} ]
then # le dossier pour le fichier de log manque, on le crée
   mkdir ${REP_SAV}/${DOMAINE}
fi
rm -f ${FILE_ERR}

#### Étape N°3: Efface la sauvegarde la plus ancienne ####
if [ -d ${REP_SAV}/${DOMAINE}/sav.${NB_INCR} ]
then
   echo -n "Efface derniere sauvegarde n-${NB_INCR} : "
   rm -fr ${REP_SAV}/${DOMAINE}/sav.${NB_INCR} 2>${FILE_ERR}
   cat ${FILE_ERR}
   echo "terminé"
fi

#### Étape N°4: Décale les autres sauvegardes ####
i=${NB_INCR}
while [ $i -gt 0 ]
do
   j=`expr $i - 1`
   if [ -d ${REP_SAV}/${DOMAINE}/sav.$j ]
   then
      echo -n "Sauvegarde n-$j "
      mv -v ${REP_SAV}/${DOMAINE}/sav.$j ${REP_SAV}/${DOMAINE}/sav.$i 2>>${FILE_ERR}
      cat ${FILE_ERR}
   fi
   i=`expr $i - 1`
done

#### Étape N°5: Contrôle de la présence de sav.1 ####
if [ ! -d ${REP_SAV}/${DOMAINE}/sav.1 ]
then # sav.1 n’existe pas / plus, on le crée
   mkdir ${REP_SAV}/${DOMAINE}/sav.1
fi

#### Étape N°6: Lancement de la sauvegarde avec rsync ####
echo "=================================================================================="
echo "${DOMAINE} -- Lancement de la sauvegarde incrémentale  -- `date`"
/usr/bin/rsync --verbose -a -e "ssh -p ${PORT_SSH}" --delete \
  --link-dest=${REP_SAV}/${DOMAINE}/sav.1 --stats --bwlimit=${DEBIT_MAX} ${REP_SRC} \
  ${REP_SAV}/${DOMAINE}/sav.0 2>>${FILE_ERR}
echo
echo "${DOMAINE} -- Fin de la sauvegarde incrémentale  -- `date`"

#### Étape N°7: Affichage des éventuelles erreurs ####
if [ -s ${FILE_ERR} ] ; then
  echo "=================================================================================="
  echo "Attention, il y a eu des erreurs lors de la sauvegarde :"
  cat ${FILE_ERR}
fi
Je rappelle que le script doit être rendu exécutable : (à adapter selon le nom et emplacement de votre script)
chmod +x /home/sauvegarde/sauvegarde-monserveur.sh

vivien

  • Administrateur
  • *
  • Messages: 38 758
    • Twitter LaFibre.info
Linux: Script bash de sauvegarde incrémentielle basé sur SSH
« Réponse #1 le: 11 mars 2021 à 09:26:58 »
Je pense mettre ce script sur GitHub, mais je voulais voir si il n'était pas possible de l'améliorer avant.
Par exemple j'aimerais bien a ne pas recopier le nom de domaine pour chaque dossier à sauvegarder, alors qu'il y a une variable pour le nom de domaine, mais je n'ai pas réussi à mettre le contenu d'une variable dans une autre variable.

Pour l'utilisation, pour ne pas avoir à rentrer le mot de passe ssh à chaque sauvegarde, il faut utiliser une connexion par clés.

Coté serveur de sauvegarde :
Générez une clé au format RSA avec la commande ssh-keygen : $ ssh-keygen -t rsa
On propose une "passphrase" : Enter passphrase (empty for no passphrase):
Appuyer pour entrer pour de pas rentrer de "passphrase" car elle sera demandé à chaque connexion.
Le répertoire de l’utilisateur contient maintenant un répertoire .ssh dans lequel id_rsa.pub contient la clé publique.
id_rsa contient la clef privée qui doit rester sur la machine.
Pour récupérer la clef : cat  ~/.ssh/id_rsa.pub

Côté serveur sauvegardé :
Allez dans le répertoire .ssh du compte auquel vous souhaitez accéder pour faire la sauvegarde.
Éditez le fichier authorized_keys (créez-le s’il n’existe pas) : nano ~/.ssh/authorized_keys
Copiez-y sur une nouvelle ligne le contenu du fichier id_rsa.pub du client : Le serveur de sauvegarde. Sauvegardez.

Indispensable :
Tentez une première connexion, pour valider le key fingerprint :

ECDSA key fingerprint is 3b:bb:2b:6b:3d:60:97:0a:8a:b8:34:8a:c1:be:c7:26.
Are you sure you want to continue connecting (yes/no)? yes
Aucun mot de passe n’est pas demandé.

A la connexion suivante, le key fingerprint n'est pas demandé.

vivien

  • Administrateur
  • *
  • Messages: 38 758
    • Twitter LaFibre.info
Linux: Script bash de sauvegarde incrémentielle basé sur SSH
« Réponse #2 le: 11 mars 2021 à 09:37:16 »
Le script ne demande aucune interaction.

Il va lister les nouveaux fichiers et fichiers modifiées qu'il sauvegarde.

A la fin du script, il afficher le fichier qui log les erreurs, si il y en a eu.

Vous pouvez utiliser ce script pour sauvegarder des PC de votre réseau ou des PC distants, du moment que vous pouvez vous connecter par SSH.
Je l'utilise par exemple pour sauvegarder le PC de ma mère qui est sous Ubuntu.
Je n'ai par contre pas trouvé de solution pour sauvegardé des PC Windows.

eupalynos

  • Client Bbox fibre
  • *
  • Messages: 41
  • Annecy (74)
Linux: Script bash de sauvegarde incrémentielle basé sur SSH
« Réponse #3 le: 11 mars 2021 à 14:56:58 »
Bonjour,

J'utilise peu ou prou le même principe pour mes sauvegardes.

J'utilise le code retour de rsync pour savoir s'il y a une erreur (code retour != 0) car la présence de données sur stderr n'est pas forcément synonyme d'erreur d'exécution.

Mais il y a une subtilité : si les fichiers sauvegardés sont en cours d'utilisation (ce qui peut être le cas pour moi), il peut arriver qu'un fichier disparaisse pendant le processus de sauvegarde. Dans ce cas-là rsync renvoi le code erreur 24 : Partial transfer due to vanished source files. Dans mon script je ne considère pas cela comme une erreur mais juste un warning.

Au lieu de numéroter les sauvegardes (et d'avoir à les renuméroter), je les suffixent avec un horodatage $(date "+%Y-%m-%d_%H:%M:%S") plutôt qu'un nombre incrémental.

Il suffit de récupérer la liste des dossiers des sauvegardes réalisées. Par ordre de tri, le premier est le plus ancien (donc celui à supprimer), le dernier est celui qui sert de base à la sauvegarde incrémentale (--link-dest).

Du coup avec l'horodatage on peut également, et assez simplement, agir plus finement en comparant avec la date du jour. Par exemple, sur la base d'une sauvegarde journalière, on peut décider de garder les 7 dernières sauvegarde mais aussi, par exemple, de conserver les premières sauvegarde de chaque mois pendant 6 mois...

Un autre intérêt de l'horodatage est qu'on voit immédiatement la date d'une sauvegarde (qui devient indépendante du mtime du dossier correspondant).

A+

fttmeh

  • Client Orange Fibre
  • *
  • Messages: 161
  • Hauts-de-Seine
Linux: Script bash de sauvegarde incrémentielle basé sur SSH
« Réponse #4 le: 14 mars 2021 à 18:41:42 »
Générez une clé au format RSA avec la commande ssh-keygen : $ ssh-keygen -t rsa
On propose une "passphrase" : Enter passphrase (empty for no passphrase):


Une clé basée sur l'algorithme Ed25519 offre une meilleure sécurité et de bonnes performances. Si dispo, c'est recommandée.
Plus d'info : https://wiki.archlinux.org/index.php/SSH_keys#Ed25519

ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/id_ed25519

kgersen

  • Modérateur
  • Client Free Pro
  • *
  • Messages: 8 052
  • Paris (75)
Linux: Script bash de sauvegarde incrémentielle basé sur SSH
« Réponse #5 le: 14 mars 2021 à 20:02:01 »
Bien préciser que c'est pour un backup simple de fichiers. Tout ce qui est base de données ou autres applications utilisant un ensemble de fichiers ouverts en permanence doit faire l'objet d'un traitement spécial pour le backup (c'est toujours utile de rappeler cela).






KalNightmare

  • Client Orange Fibre
  • *
  • Messages: 99
  • Massy 91
Linux: Script bash de sauvegarde incrémentielle basé sur SSH
« Réponse #6 le: 14 mars 2021 à 20:35:34 »
Je pense mettre ce script sur GitHub, mais je voulais voir si il n'était pas possible de l'améliorer avant.
Par exemple j'aimerais bien a ne pas recopier le nom de domaine pour chaque dossier à sauvegarder, alors qu'il y a une variable pour le nom de domaine, mais je n'ai pas réussi à mettre le contenu d'une variable dans une autre variable.

Il faut mettre le contenu entre "". Entre '' il n'y pas de remplacement.

Citer
FOO="bar"

toto="$FOO"
echo $toto => BAR

tutu='$FOO'
echo $tutu => $FOO

kgersen

  • Modérateur
  • Client Free Pro
  • *
  • Messages: 8 052
  • Paris (75)
Linux: Script bash de sauvegarde incrémentielle basé sur SSH
« Réponse #7 le: 14 mars 2021 à 22:39:45 »
après plutôt que réinventer la roue... y'a https://rdiff-backup.net/ qui existe depuis 20 ans + et fais cela et bien plus.

Invarion

  • Client MilkyWan (AS57199)
  • *
  • Messages: 120
  • Montpellier 34
Linux: Script bash de sauvegarde incrémentielle basé sur SSH
« Réponse #8 le: 14 mars 2021 à 23:01:48 »
après plutôt que réinventer la roue... y'a https://rdiff-backup.net/ qui existe depuis 20 ans + et fais cela et bien plus.
Ou https://www.borgbackup.org/  ;)

FloBaoti

  • Client FAI autre
  • *
  • Messages: 1 073
  • 34
Linux: Script bash de sauvegarde incrémentielle basé sur SSH
« Réponse #9 le: 15 mars 2021 à 07:58:58 »
Ou Duplicity  ;)

Edit vivien, je rajoute le lien : https://doc.ubuntu-fr.org/duplicity

eupalynos

  • Client Bbox fibre
  • *
  • Messages: 41
  • Annecy (74)
Linux: Script bash de sauvegarde incrémentielle basé sur SSH
« Réponse #10 le: 15 mars 2021 à 08:21:10 »
Bonjour,

Il y tout de même un avantage certain au backup incrémentiel rsync par rapport aux solutions de type rdiff-backup ou similaire : il n'y a besoin d'aucun outil pour accéder aux fichiers qui conservent tous leurs attributs (structure des répertoires, timestamp, permissions...).

Un simple cp (ou scp) permet de restaurer un fichier à la date souhaitée.

Du coup, c'est simple de vérifier l'intégrité d'un backup.

Et comme la sauvegarde incrémentielle utilise des hard link pour les fichiers qui n'ont pas été modifiés, au niveau espace disque ça reste correct.

Personnellement, je trouve que c'est le meilleur compromis.

A+


kgersen

  • Modérateur
  • Client Free Pro
  • *
  • Messages: 8 052
  • Paris (75)
Linux: Script bash de sauvegarde incrémentielle basé sur SSH
« Réponse #11 le: 15 mars 2021 à 14:31:31 »
Bonjour,

Il y tout de même un avantage certain au backup incrémentiel rsync par rapport aux solutions de type rdiff-backup ou similaire : il n'y a besoin d'aucun outil pour accéder aux fichiers qui conservent tous leurs attributs (structure des répertoires, timestamp, permissions...).

Un simple cp (ou scp) permet de restaurer un fichier à la date souhaitée.

Du coup, c'est simple de vérifier l'intégrité d'un backup.

Et comme la sauvegarde incrémentielle utilise des hard link pour les fichiers qui n'ont pas été modifiés, au niveau espace disque ça reste correct.

Personnellement, je trouve que c'est le meilleur compromis.

A+

un simple cp suffit pour restaurer depuis rdiff-backup vu que c'est aussi un miroir.  on conserve aussi les attributs.

et pour restaurer une ancienne version:
la version d'il y a 10 jours:
rdiff-backup -r 10D chemin_back_up chemin_destination
la version du 3 mars 2021:
rdiff-backup -r 2021-03-05 chemin_backup chemin_destination
niveau simplicité on peut difficilement faire mieux

niveau espace disque on peut choisir de conserver soit par rapport a un age ou soit par rapport a un nombre max de versions ou un mix des deux (genre: max les 20 dernières versions de chaque fichier et/ou max 1 an d'ancienneté).

le seul truc qui manque par rapport a un rsync c'est l'option --bwlimit pour limiter la bande passante utilisée lors d'un backup.