sauvegarde dans fichier chiffré

De Linux France
Aller à : navigation, rechercher

Introduction

Voici comment sauvegarder:

  • quoi: n'importe quoi (dans l'exemple fourni: les fichiers créés ou modifiés sous un répertoire donné et tous ses sous-répertoires)
  • où: dans un fichier chiffré (ici désigné par le nom « cargo »), par exemple placé dans un smartphone, une clé USB, un disque dur externe...

Limitations

Paramètres potentiels, pour le moment en dur:

  • loop0, et avorte s'il est déjà employé
  • nom du fichier abritant les paramètres de filtrage rsync

Préparation

Environnement

  1. installer « sudo » et le paramétrer de sorte qu'il accepte qu'il ne réclame pas de mot de passe lorsqu'en employé par votre compte utilisateur (documentation)
  2. installer « logger »
  3. créer un répertoire de montage du cargo nommé « /mnt/backup_tel »: sudo mkdir -p /mnt/backup_tel

Créer le cargo

Conventions:

  • toutes ces commandes sont à saisir dans un même terminal, afin de préserver la variable d'environnement nécessaire
  • pour monter un cargo existant (déjà créé) on se contentera des commandes placées dans les lignes commençant par « (+existant+) »
  1. monter le système de fichiers du périphérique (téléphone...). Ici: en /mnt/usbb
  2. déterminer l'espace de stockage disponible sur le système de fichiers (conserver un peu d'espace libre): df -h /mnt/usbb
  3. décider du nom du sous-répertoire qui abritera le cargo (ici: « /data/ »)
  4. mkdir /mnt/usbb/data
  5. cd /mnt/usbb/data
  6. si le cargo est nommé « bckNatAndroid1.data » et occupera 3,5 Go : dd if=/dev/zero of=bckNatAndroid1.data count=3500 bs=1M # 'urandom' plutôt que 'zero' est plus sûr mais plus lent, préférer 'zéro' si le fichier sera d'emblée quasi rempli. Si le périphérique sous-jacent l'accepte ajouter "conv=sparse" afin de créer un fichier sparse
  7. (+existant+) attacher un loopback grâce auquel un fichier sera perçu en tant que périphérique accessible par blocs (« block device ») montable: sudo losetup -f bckNatAndroid1.data
  8. détermination du loopback utilisé que l'on place dans une variable d'environnement: sudo export NAT_LOOPBACK=$(losetup -j bckNatAndroid1.data|cut -f1 -d:)
  9. (+existant+) vérification: echo $NAT_LOOPBACK , un nom de fichier loopback doit apparaître
  10. formatage d'un espace LUKS (chiffré): sudo cryptsetup -y luksFormat /dev/$NAT_LOOPBACK
  11. (+existant+) ouverture de l'espace LUKS: sudo cryptsetup luksOpen /dev/$NAT_LOOPBACK backup_tel
  12. création d'un fs, qui sera posé sur un espace LUKS: sudo mkfs.ext4 -m 0 /dev/mapper/backup_tel
  13. (+existant+) montage du fs (en clair): sudo mount /dev/mapper/backup_tel /mnt/usbLuks
  14. création, dans le fs chiffré, d'un répertoire qui abritera la sauvegarde, par exemple « home/toto_recent », où toto remplace votre nom de connexion (le mien est nat, j'emploie donc « home/nat_recent »): sudo mkdir -p /mnt/usbLuks/home/nat_recent ; sudo chown nat.nat /mnt/usbLuks/home/nat_recent ; sudo chmod u+rx /mnt/usbLuks/home ; sudo chmod u+rxw /mnt/usbLuks/home/nat_recent

À ce stade vous pouvez utiliser le répertoire chiffré, en /mnt/usbLuks/home/nat_recent/

Démontage, après utilisation:

  1. démontage du fs chiffré: sudo umount /mnt/usbLuks
  2. fermeture de l'espace LUKS: sudo cryptsetup luksClose backup_tel
  3. détachement du loopback: sudo losetup -d $NAT_LOOPBACK

Documentation relative à la création (anglais)

Adapter le script publié ci-après puis l'invoquer afin d'effectuer une première sauvegarde.

Préparer le filtrage

(étape optionnelle)

Si certains fichiers ne doivent pas être ainsi sauvegardés créer un fichier (par exemple /home/nat/bin/utis/rsyncList_of_notbackuped_files.txt ) recelant les filtres de leurs noms (syntaxe rsync). Exemple:

/.mozilla/firefox/*/Cache/***
/.xsession-errors*
/Mail/**/.overview

Préparer le script

Éditer le script proposé afin d'y établir les contenus des variables-paramètres (au début).

Si aucun filtrage (lire section précédente) n'est nécessaire supprimer, dans le script, les paramètres correspondants destinés à rsync (--exclude-from et --delete-excluded ligne 74).

Utilisation

Sauvegarder

Pour sauvegarder:

  1. monter le système de fichiers recelant le cargo. Dans le cas d'un appareil Android le connecter via un câble USB, cliquer sur l'icone correspondante USBAndroid1.png puis sur le bouton invitant à « Activer le périphérique de stockage USB »
  2. invoquer le script fourni ci-dessous
  3. démonter le système de fichiers recelant le cargo. Sous Android on sélectionnera l'icone de gestion de l'USB afin de désactiver le périphérique de stockage.

Restaurer

Le mode d'utilisation de rsync proposé dans le script préserve, dans le cargo, les fichiers détruits sur le système de fichiers sauvegardé donc mieux vaut, afin de ne pas créer de fantôme (sens 3), restaurer en recopiant chaque fichier souhaité.

Script

#!/bin/bash
# Purpose: backup files (crypted)
# Action: copies each new/modified file into a filesystem which is
# crypted and sits in a file. The file may be on some removable device
# (a smartphone, USB token...)
# Homepage (French): http://wiki.linux-france.org/wiki/sauvegarde_dans_fichier_chiffr%C3%A9
 
VERSION=0.12
 
# Name of the directory to backup
SRCDIR=~nat
 
# The filesystem storing the crypted file will be mounted under
# (attached to) a directory named "$MNTPNTPREF"x , 'x' being one of
# the POTENTIALDEV's elements
# The script will check every combination until it finds $CRYPTFILNAM
MNTPNTPREF=/mnt/usb
POTENTIALDEV="b c d e f"
 
# File (containing the encrypted filesystem) pathname
CRYPTFILNAM=/data/bckNatAndroid1.data
 
# Local directory used as a mounting point for the encrypted filesystem
MOUNTDIR=/mnt/backup_tel
 
# Target directory (where the backup will be written to)
TARGETDIR="$MOUNTDIR"/home/nat_recent
 
# oldest backuped (modified) file age (in days)
BCK_DAYS=444
 
function checkmountpoint
{
    mountpoint -q $1 || return
    echo $1 already mounted, aborting
    exit 11	
}
 
checkmountpoint /mnt/backup_tel
 
read -ra MYDEVICE <<< "$POTENTIALDEV"
for MYDEVICE in ${POTENTIALDEV[@]} ; do
    if [[ -s "$MNTPNTPREF""$MYDEVICE""$CRYPTFILNAM" ]]; then break; fi
done
 
CFNAM="$MNTPNTPREF""$MYDEVICE""$CRYPTFILNAM"
 
if [[ ! -s "$CFNAM" ]]; then
    echo I can not find "$CRYPTFILNAM"
    echo 'Please connect (USB) the peripheral, request/accept/command mounting,'
    echo 'wait for the filesystem to be mounted, then re-invoke me'
    exit 4
fi
 
sudo losetup -a|grep '^/dev/loop0'
RETVAL=$?
if [[ $RETVAL -eq 0 ]] ; then
    echo loop0 already in use
    exit 5
fi
 
if [[ $RETVAL -ne 1 ]] ; then
    echo loop0: detection problem
    exit 6
fi
 
cd $SRCDIR || { echo Cannot reach SRCDIR ; exit 7 ; }
sudo ionice -c3 -p $$
sudo losetup /dev/loop0 "$CFNAM" || { echo Cannot losetup ; exit 8; }
sudo cryptsetup luksOpen /dev/loop0 backup_tel || { echo Cannot luksOpen ; sudo losetup -d /dev/loop0 ; exit 9; }
sudo mount /dev/mapper/backup_tel /mnt/backup_tel || { echo Cannot mount backup_tel ; sudo cryptsetup luksClose backup_tel ; sudo losetup -d /dev/loop0 ; exit 10; }
[[ -d "$TARGETDIR" ]] || { echo Cannot find TARGETDIR ; sudo cryptsetup luksClose backup_tel ; sudo losetup -d /dev/loop0; exit 11 ; }
# 'find' pourrait être lancé en tâche de fond, avant montage cargo,
# mais tout pb doit stopper le script + la liste des fichiers pourrait
# être 'vieille' lors du démarrage de rsync
sudo find . -type f -mtime -"$BCK_DAYS" > /tmp/rsyncBckTEL || { echo Cannot collect filenames ; sudo umount /mnt/backup_tel ; sudo cryptsetup luksClose backup_tel ; sudo losetup -d /dev/loop0; exit 12; }
echo Backup started
read
 
# useful rsync options: --stats --progress
sudo rsync -v -a --delete \
    --files-from=/tmp/rsyncBckTEL \
    --exclude-from=/home/nat/bin/utis/rsyncList_of_notbackuped_files.txt --delete-excluded \
    --inplace \
    . "$TARGETDIR"
ERR="$?"
[[ "$ERR" -ne 0 ]] && { echo BEWARE: rsync somewhat failed: $ERR ; }
 
# si saturation (TODO: la détecter) proposer (ne pas exécuter, trop dangereux!): find "$TARGETDIR" -type f -mtime +"$BCK_DAYS" -print0 | xargs -0 -r rm
# puis ré-invocation de ce script
 
sudo umount /mnt/backup_tel
sudo cryptsetup luksClose backup_tel
sudo losetup -d /dev/loop0
 
# le cargo est démonté, mais pas le fs l'abritant (que ce script n'a pas monté donc ne démontera pas).
# using 'sync' to reduce dataloss risk (unplugging the USB 'drive' w/o unmounting it first)
# we may instead use either:
# - a Perl script calling fsync (from File::Sync) for the cargo file (AFAIK it will send to the disk all data waiting to written to it(?))
# - mount -o remount $MNTPNTPREF
#... but it won't work if the fs was mounted w/o any /etc/fstab directive, or if the active mounting options are not those declared in this file
# - a dedicated utility to fsync the cargo file and it's directory
# - syncfs (future!)
echo sync, please wait
sync
 
if [[ "$ERR" -ne 0 ]] ; then
    echo I am "$0", and backuped $SRCDIR on $CFNAM, error $ERR
    logger -p user.err -t backup_phone -- Done, error $ERR
else
    echo I am "$0", and backuped $SRCDIR on $CFNAM
    logger -p user.info -t backup_phone -- Done, OK
fi
exit $ERR