On l'entend souvent : Pour protéger vos données vous devez les sauvegarder. En pratique on néglige presque tous ce conseil avisé jusqu'au jour où l'inévitable arrive et où vous perdez en un instant le moral et une partie de votre vie.
Un rm -rf
depuis un compte administrateur, un disque dur défaillant ou ayant subi une chute, une clé USB perdue ou détruite, du matériel volé, des CD-ROM devenus illisibles au bout de quelques années, une intrusion sur un système etc.
Puis on s'oriente vers des services de récupération (Seagate, Chronodisk, Ontrack) et on se rend compte des prix exorbitants pratiqués sans garantie de réussite du processus; il faut compter entre 150 et 800€ selon la gravité de la panne. Ce jour-là on se mord les doigts de ne pas avoir pris quelques heures pour sauvegarder ses données.
En informatique, sauvegarder est primordial. L'excuse du "j'ai perdu tous mes fichiers" ne tient pas ! Ce n'est vraiment pas de chance si ça arrive avec un système de sauvegarde, mais sans ce dernier c'est insérer des propos déplacés ici.
De plus, sauvegarder c'est bien, mais chiffrer la sauvegarde et la rendre illisible en cas de vol, c'est mieux ! Sauvegarder sur plusieurs supports, c'est encore mieux !
Évitez le Cloud (commits Dropbox), si vous ne leur rapportez rien, alors vos données n'ont pas de valeur et ils s'en foutent ! Ça parait êxtrême ou aller de soi ? Pensons au nombre de gens et d'entreprises qui faisaient confiance à MegaUpload pour stocker leurs fichiers légaux !
MegaUpload a clairement informé les utilisateurs de cette spécificité à travers la Foire Aux Questions (FAQ) et ses conditions d’utilisation. Les internautes « n’ont aucun droit de propriété sur aucun des fichiers stockés sur les serveurs de MegaUpload, ils assument le risque de perte ou d’indisponibilité de leurs données et que MegaUpload peut mettre un terme aux activités du site sans préavis ».
Ex-utilisateurs de MegaUpload en Europe, vos fichiers sont perdus.
LeaseWeb a effacé tous les serveurs de MegaUpolad. [...] Ces fichiers végétaient sur les serveurs de l’hébergeur depuis au moins le 19 janvier 2012, date de fermeture de la célèbre plateforme. Mais tout cet espace occupé par des pétabytes de fichiers représentait aussi un manque à gagner pour l’hébergeur qui ne l’affectait pas à de nouveaux clients.
Le Cloud gratuit est toxique pour la vie privée et pour les données des utilisateurs. Fuyez-le, décentralisez vos activités.
=> On n'est jamais mieux servi que par soi-même.
Les scripts proposés ici (et sur Github : auto_backups) permettent une sauvegarde automatique décrémentale sur système de fichiers chiffré LUKS (Linux Unified Key Setup), vers un disque dur externe. La durée de la première sauvegarde dépend évidemment de la quantité et du type de fichiers concernés. À titre d'exemple, je dispose de 30Go de photos, documents, codes; le tout est sauvegardé presque tous les jours en moins de 30 secondes.
À lire : La moitié des groupes de presse français viendrait de perdre toute trace de leurs abonnés.
Y a-t-il une backup dans l'avion ?
Sommaire
LUKS : Container chiffré et partition cachée
Créer, monter, démonter
Outils:
gparted
: La boîte à outils de référence (ne gère pas le système de fichiers LUKS).gnome-disk-utility
: cf. tuto.partitionmanager
: Gère LUKS à partir de la version 2.
La procédure décrite par la suite est manuelle c.-à-d. avec GParted et les outils en ligne de commande.
Il faut tout d'abord créer une partition ext4 de taille suffisante (libérer de l'espace par redimensionnement d'une partition déjà existante par exemple). Peu importe le système de fichiers choisi dans cette phase car il sera écrasé par le système de fichiers LUKS.
Création d'une nouvelle partition sur GParted.
Identifier la partition d'accueil. Pour cela il existe des tas d'outils:
$ lsblk -f
NAME FSTYPE LABEL UUID MOUNTPOINT
sda
├─sda1 /boot/efi
├─sda2 /pedoporn
├─sda3 /nsa_backdoor
├─sda4 /media/windows_backdoor_for_everyone
├─sda5 /media/DATA
├─sda6 /google_backdoor
├─sda7 [SWAP]
├─sda8 /home
├─sda9 /
└─sda10 /docker_backdoor
sdb
├─sdb1
└─sdb2
# ou:
$ blkid
/dev/sdb2: UUID="d9ad7a7b-24c6-4995-9c53-4afa352a9416" TYPE="ext4" PARTUUID="69a6bda8-e1a0-4dc5-8452-1eaf50d7fd77"
# ou tout simplement:
$ ls -la /dev/disk/by-uuid/
lrwxrwxrwx 1 root root 10 sept. 1 20:41 d9ad7a7b-24c6-4995-9c53-4afa352a9416 -> ../../sdb2
Chez moi la partition est la seconde présente sur le disque externe sdb
; soit : /dev/sdb2
.
Installer le paquet cryptsetup
si ce n'est pas déjà fait :
$ sudo apt-get install cryptsetup
Créer la partition LUKS sur cette partition (Attention, ceci écrasera tout son contenu !):
$ sudo cryptsetup luksFormat -c aes -h sha256 /dev/sdb2
Les options de chiffrement ont une incidence sur les performances de lecture/écriture.
Ici cela importe peu car il s'agit d'un disque externe, mais c'est un point qu'il convient de prendre en compte dans le cas d'un chiffrement généralisé d'un système d'exploitation. Renseignez-vous sur les algos (AES, AES-CBC, AES-XTS, modes d'opération cryptographiques) !
Faites des tests :
$ cryptsetup benchmark
# Tests approximatifs en utilisant uniquement la mémoire (pas de stockage E/S).
PBKDF2-sha1 936228 iterations per second
PBKDF2-sha256 686240 iterations per second
PBKDF2-sha512 464794 iterations per second
PBKDF2-ripemd160 652099 iterations per second
PBKDF2-whirlpool 222911 iterations per second
# Algorithm | Key | Encryption | Decryption
aes-cbc 128b 577,2 MiB/s 2092,5 MiB/s
serpent-cbc 128b 67,2 MiB/s 273,1 MiB/s
twofish-cbc 128b 175,3 MiB/s 335,3 MiB/s
aes-cbc 256b 424,3 MiB/s 1565,3 MiB/s
serpent-cbc 256b 83,5 MiB/s 284,7 MiB/s
twofish-cbc 256b 175,9 MiB/s 333,8 MiB/s
aes-xts 256b 1732,8 MiB/s 1732,0 MiB/s
serpent-xts 256b 292,1 MiB/s 278,9 MiB/s
twofish-xts 256b 326,8 MiB/s 329,8 MiB/s
aes-xts 512b 1326,8 MiB/s 1334,7 MiB/s
serpent-xts 512b 290,8 MiB/s 279,7 MiB/s
twofish-xts 512b 328,4 MiB/s 330,7 MiB/s
Ouvrir la partition LUKS qui jouera le rôle d'un container (nommé cryptdisk
dans la commande suivante), abritant la partition contenant réellement les fichiers :
$ sudo cryptsetup luksOpen /dev/sdb2 cryptdisk
Création du système de fichier ext4 dans la partition chiffrée :
$ sudo mkfs.ext4 /dev/mapper/cryptdisk
C'est quoi ext4 ?
Il s'agit d'un système de fichiers performant et extrêmement résistant aux problèmes de fragmentation rencontrés en particulier avec le FAT/NTFS de Microsoft. Ces particularités sont expliquées entre autres par:
- Une pré-allocation des fichiers sur le disque avec garantie de la contiguïté de l'espace réservé.
- Une allocation différée de l'espace, basée sur une mise en cache précédant un vidage de gros blocs de données, permettant de meilleures performances et une réduction de la fragmentation du fichier final.
- Une allocation multi-blocs évitant des requêtes successives lors de l'agrandissement d'un fichier et garantissant là encore, la contiguïté de l'espace demandé.
TL;DR : NTFS c'est la spatio-merde; il n'y a pas de fragmentation des fichiers sous GNU/Linux.
Création du point de montage :
$ sudo mkdir /media/cryptdisk
Montage :
$ sudo mount /dev/mapper/cryptdisk /media/cryptdisk
Attribution des droits :
Lors de son premier montage, une partition appartient au compte root. Vous devez vous l'approprier en changeant les droits sur la racine. (Cela explique la remarque courante : "gna gna gna Linux c'est dla merde on peut pas mettre de fichiers sur son disque externe".)
$ sudo chown -R cazeneuve:cazeneuve
où cazeneuve
est votre nom d'utilisateur.
Note de la rédaction
Chiffrer ses fichiers avec un tel nom est assez... contradictoire. Mais si vous êtes ici c'est que vous avez des choses à cacher non ? Ce tuto aidera sans aucun doute certaines personnes à cacher les casseroles qu'ils ont au cul.
Cordialement, bisous <3.
Démontage manuel et fermeture du volume chiffré :
$ sudo umount /media/cryptdisk
$ sudo cryptsetup luksClose cryptdisk
Montage automatique
Après déverrouillage, un nouveau point de montage est disponible sur le système : la partition cachée dans le container LUKS.
$ ls -la /dev/disk/by-uuid/
lrwxrwxrwx 1 root root 10 sept. 1 21:16 c968bc41-a980-4900-9490-00b2a5ed1d4e -> ../../sdb2
lrwxrwxrwx 1 root root 10 sept. 1 21:16 86cee552-66b9-4ab7-92f5-f401ee37de01 -> ../../dm-0
$ blkid
/dev/sdb2: UUID="c968bc41-a980-4900-9490-00b2a5ed1d4e" TYPE="crypto_LUKS" PARTUUID="917abaf8-7ad9-4ca8-b046-36116322c557"
/dev/mapper/luks-c968bc41-a980-4900-9490-00b2a5ed1d4e: UUID="86cee552-66b9-4ab7-92f5-f401ee37de01" TYPE="ext4"
Repérer son UUID (Universal Unique Identifier):
Ici 86cee552-66b9-4ab7-92f5-f401ee37de01
est l'UUID de la partition ext4, cachée dans un container LUKS dont l'UUID est c968bc41-a980-4900-9490-00b2a5ed1d4e
.
Définir les options de montage en éditant le fichier /etc/fstab
:
# <file system> <mount point> <type> <options> <dump> <pass>
UUID=86cee552-66b9-4ab7-92f5-f401ee37de01 /media/cryptdisk ext4 defaults,noatime,nodiratime,noauto 0 2
Le paramètre noauto
est là pour empêcher une tentative de montage qui ralentirait le démarrage (c'est un disque externe !).
Au cas où il s'agirait d'un disque fixe, et qu'il faudrait le monter au démarrage, il faut savoir que la configuration des paramètres du volume chiffré se fait dans le fichier /etc/crypttab
. Dans ce fichier, la colonne <key file>
permet de spécifier un fichier capable de déverrouiller le volume chiffré sans saisie du mot de passe.
Cas d'utilisation : Le système se déverrouille uniquement si un périphérique contenant la clé est branché. Autrement la NSA va se faire voir...
Exemple :
# <target name> <source device> <key file> <options>
cryptdisk UUID=c968bc41-a980-4900-9490-00b2a5ed1d4e none luks,timeout=10
À la fin de cette partie vous devriez avoir un système capable de monter la partition cachée de façon autonome. Il est bon de connaître l'existence des commandes de gestion vues jusque-là, mais en général les environnements de bureau s'en chargent à votre place.
Exemple sur KDE (existe-t-il d'autres bureaux qui valent le coup ? :o)
Rsync : Sauvegarde
Pour faire des sauvegardes, vous pouvez utiliser un système propriétaire, payant, cher, très cher, buggé, inefficace, ou alors vous utilisez rsync. rsync permet de faire entre autres, de la sauvegarde décrémentale. rsync sert notamment à réaliser des sauvegardes à distance en se reposant sur une excellente optimisation des transferts.
Une sauvegarde incrémentielle consiste à réaliser une sauvegarde complète le jour J. Le jour J+1, la sauvegarde incrémentielle est réalisée par référence au jour J. Le jour J+2, la sauvegarde incrémentielle est réalisée par référence au jour J+1. Et ainsi de suite.
Une sauvegarde décrémentale consiste à obtenir une sauvegarde complète comme sauvegarde la plus récente et des sauvegardes différentielles pour les plus anciennes.
Merci Wikipédia.
Avec la sauvegarde décrémentale, les jours précédents sont des diffs du jour courant. La restauration du jour courant est aisée, et on peut supprimer les vieilles sauvegardes sans devoir faire un point de restauration complet comme avec la sauvegarde incrémentielle (faire un nouveau jour J).
Vous l'avez compris, il est inutile de sauvegarder la totalité des fichiers chaque jour; étant donné qu'une grande partie des fichiers ne change que très rarement, on ne conserve que les données modifiées.
Architecture
À la racine du répertoire de sauvegarde on trouve :
- Le dossier de la dernière sauvegarde,
- Les dossiers des jours précédents,
- Les logs conservant les modifications.
Logigramme décrivant les actions réalisées lors du processus de sauvegarde décrémentale. Oui, c'est fait avec Inkscape et ça m'a pris 20 minutes; et non, pour une fois le logiciel n'a pas planté !
Rsync
Voici la commande utilisée :
rsync --stats -av --force --ignore-errors --delete --delete-excluded \
--exclude-from=exclude_file \
--include-from=include_file \
--backup --backup-dir="$(date +%Y-%m-%d)/" \
"source/dir/" "current/" \
&> log_file.log
Description des paramètres :
-a, --archive archive mode; equals -rlptgoD (no -H,-A,-X)
-r, --recursive recurse into directories
-l, --links copy symlinks as symlinks
-p, --perms preserve permissions
-t, --times preserve modification times
-g, --group preserve group
--devices preserve device files (super-user only)
--specials preserve special files
-D same as --devices --specials
-o, --owner preserve owner (super-user only)
-v, --verbose increase verbosity
--stats give some file-transfer stats
--delete
supprime les fichiers qui sont dans le répertoire de destination et pas dans le répertoire source
--ignore-errors
delete even if there are I/O errors
--force
force la suppression de répertoires même non-vides
--backup
crée des sauvegardes des fichiers avant de les écraser en les écrivant sur eux-mêmes
--backup-dir=`date +%Y-%m-%d`
crée un répertoire de backup daté pour ces sauvegardes
--exclude-from=FILE
This option is related to the --exclude option, but it specifies a FILE that contains exclude patterns (one per line).
Blank lines in the file and lines starting with ';' or '#' are ignored.
--include-from=FILE
This option is related to the --include option, but it specifies a FILE that contains include patterns (one per line).
Blank lines in the file and lines starting with ';' or '#' are ignored.
Note also that excluding a directory prevents it not only from being copied but also from being traversed, so this effectively excludes everything below it. See this rsync filter primer for more information.
If you exclude a directory, this excludes everything below it.
If you include a directory, this doesn't automatically include its contents. In recent versions, --include='directory/***' will do that.
* : any substring of a single directory component (i.e. never matches /);
** : matches any path substring.
Exemple de syntaxe:
+ Users
+ Users/Cazeneuve
+ Users/Cazeneuve/Desktop
+ Users/Cazeneuve/Desktop/**
- *
# ou plus rapide:
+ Users
+ Users/Cazeneuve
+ Users/Cazeneuve/Desktop/***
- *
Script final :
#!/bin/bash
########################################
# Script for incremental rsync backups #
# Return 1 on errors, 0 otherwise #
########################################
# Names of saved directories
BACKUP_NAME_WINDOWS="windows"
BACKUP_NAME_DATA="DATA"
BACKUP_NAME_DEBIAN="home"
# Paths of directories to save
SRC_WINDOWS="/media/windows/"
SRC_DEBIAN="/home/Lex/"
SRC_DATA="/media/DATA/"
# PS : Include patterns have to be specified
# as argument of backup_process function.
# Mount point of the partition/volume where the backup will be made
MOUNT_POINT="/media/cryptdisk"
# Root directory of backup stuff
BACKUP_ROOT="backups"
########################################
# From here on out, you probably don't #
# want to change anything unless you #
# know what you're doing. #
########################################
CURRENT_DATE=$(date +%Y-%m-%d)
# Directory where the script and include/exclude files are stored
SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
EXIT_VALUE=0
check_directories()
{
# Check the existence of the directory where the last backup will be put
# Param: Directory name
#echo "Checking ${MOUNT_POINT}/${BACKUP_ROOT}/$1_current/ ..."
if [ ! -d "${MOUNT_POINT}/${BACKUP_ROOT}/$1_current/" ]; then
echo -n "Init backup dir..."
mkdir -p "${MOUNT_POINT}/${BACKUP_ROOT}/$1_current/"
# get the exit code from the last command executed
if [ $? -ne 0 ]; then
echo -e " [${RED}FAIL${NC}]"
# Stop the script
exit 1
else
# 0 on success
echo -e " [ ${GREEN}OK${NC} ]"
return 0
fi
fi
}
backup_process()
{
# Check directory & do the backup process
# Param 1: Path of directory to save
# Param 2: Name used for the destination
# Param 3 (optional): File with patterns that will filter the source files
#check_directories $BACKUP_NAME_WINDOWS
check_directories $2
echo -n "Backup $2 in progress..."
LOG_FILE="${MOUNT_POINT}/${BACKUP_ROOT}/log_$2_$(date +%Y-%m-%d_%Hh-%Mm-%Ss).log"
rsync --stats -av --force --ignore-errors --delete --delete-excluded \
--exclude-from="${SCRIPT_DIR}/exclude_all" \
--include-from=$3 \
--backup --backup-dir="${MOUNT_POINT}/${BACKUP_ROOT}/$2_${CURRENT_DATE}/" \
$1 "${MOUNT_POINT}/${BACKUP_ROOT}/$2_current/" \
&> ${LOG_FILE}
# get the exit code from the last command executed
if [ $? -ne 0 ]; then
echo -e " cf log [${RED}FAIL${NC}]"
# Update exit value
EXIT_VALUE=1
return 1
else
# 0 on success
echo -e " [ ${GREEN}OK${NC} ]"
return 0
fi
}
#########################################
if df | grep -q $MOUNT_POINT; then
# Check include files here as third parameter !
backup_process $SRC_WINDOWS $BACKUP_NAME_WINDOWS "${SCRIPT_DIR}/include_windows"
backup_process $SRC_DEBIAN $BACKUP_NAME_DEBIAN
backup_process $SRC_DATA $BACKUP_NAME_DATA "${SCRIPT_DIR}/include_DATA"
else
echo -e "ERROR: Can't find mount point ! [${RED}FAIL${NC}]"
EXIT_VALUE=1
fi
# Uncomment these lines if the script is not run through systemd (in user env)
#if [ $EXIT_VALUE -ne 0 ]; then
# kdialog --passivepopup "Some errors occured !"
#else
# kdialog --passivepopup "Backup is done."
#fi
exit $EXIT_VALUE
Pour adapter le script il suffit de renseigner les paramètres BACKUP_NAME_*
qui correspondent aux noms des dossiers sauvegardés dans le dossier principal de sauvegarde BACKUP_ROOT
.
Un paramètre SRC_*
fait référence à chaque BACKUP_NAME_*
. Il s'agit du répertoire contenant les fichiers à sauvegarder.
Les différents dossiers sont traités vers la fin du script par autant d'appels à la fonction backup_process
.
Exemple:
backup_process $SRC_DATA $BACKUP_NAME_DATA "${SCRIPT_DIR}/include_DATA"
Le 3ième paramètre, optionel, fait référence à un fichier listant les dossiers qui doivent être pris en compte dans le dossier SRC_*
. La syntaxe de ce fichier est expliquée au début du chapitre avec les paramètres de rsync.
Systemd : Automatisation
Concrètement on veut que le système lance le script de sauvegarde après qu'on ait déverrouillé le container.
Pour lancer un script au montage d'une partition (et non au branchement d'un périphérique) il faut utiliser systemd en créant un service dédié (cf. tuto précédent) ! N'allez pas vous perdre avec udev qui reconnait et monte les périphériques mais qui est incapable de lancer des actions en fonction de la présence/absence d'une partition spécifique.
Avec udev, le script essaiera de se lancer au branchement du périphérique; soit avant qu'on ait pu avoir le temps de déverrouiller le container.
Copier le code de ce service systemd dans un fichier auto-backup-cryptdisk.service
placé dans /etc/systemd/system
:
# List mount targets: systemctl list-units -t mount
[Unit]
# Contains information about the service.
Description=Auto backup of the system to a LUKS encrypted partition.
Requires=media-cryptdisk.mount
# Launch after mounting the partition
After=media-cryptdisk.mount
[Service]
# Action of the service itself
ExecStart=/home/MY_USERNAME/backups/script.sh
[Install]
WantedBy=media-cryptdisk.mount
Activer le service :
$ systemctl enable auto-backup-cryptdisk.service
Created symlink from /etc/systemd/system/media-cryptdisk.mount.wants/auto-backup-cryptdisk.service to /etc/systemd/system/auto-backup-cryptdisk.service.
Recharger le démon systemd :
$ systemctl --system daemon-reload
Le script se lance dès le déverrouillage du container. On peut visualiser la sortie de ce dernier via la commande suivante :
$ systemctl status auto-backup-cryptdisk.service
● auto-backup-cryptdisk.service - Auto backup of the system to a LUKS encrypted partition.
Loaded: loaded (/etc/systemd/system/auto-backup-cryptdisk.service; enabled)
Active: inactive (dead) since jeu. 2016-09-01 15:38:51 CEST; 2s ago
Process: 7140 ExecStart=/home/Lex/Desktop/backups/script.sh (code=exited, status=0/SUCCESS)
Main PID: 7140 (code=exited, status=0/SUCCESS)
sept. 01 15:38:17 kali script.sh[7140]: Backup windows in progress... [ OK ]
sept. 01 15:38:25 kali script.sh[7140]: Backup home in progress... [ OK ]
sept. 01 15:38:38 kali script.sh[7140]: Backup DATA in progress... [ OK ]
F
Possible la même chose mais vers un ftp ?