Petite problématique de sauvegarde chiffrée à travers le réseau, dans un conteneur. Au programme :
LUKS
pour le chiffrement- Configuration
LXC
mknod
(obscure)BURP
(BackUp and Restore Program)
Contraintes
- Stockage délégué à l’hébergeur via un stockage réseau SFTP ou CIFS
- Minimisation de l’espace occupé via de la sauvegarde incrémentale (ça coûte des sous, hein)
- Installation du système de backup isolée dans un conteneur LXC
Configuration LXC
Dans le fichier config
de votre machine LXC, ajouter ces lignes :
# /dev/loop0
lxc.cgroup.devices.allow = b 7:0 rwm
# /dev/mapper/control
lxc.cgroup.devices.allow = c 10:236 rwm
# /dev/mapper/<votre luks>
lxc.cgroup.devices.allow = b 253:* rwm
Redémarrez le conteneur mais pas avec reboot
.
Une fois que c’est fait, il vous faudra avoir chargé le module loop
sur la machine hôte et créé le node loop0
dans le conteneur :
mknod /dev/loop0 b 7 0
LUKS
Premièrement, montons notre stockage réseau. Pour cela j’ai une entrée fstab
avec le point de montage. On oubliera pas de peupler le fichier backup-credentials
:
echo '//backup-host/backup /root/srv-backup-cifs cifs iocharset=utf8,rw,credentials=/root/backup-credentials,uid=root,gid=root,file_mode=0600,dir_mode=0700,noauto 0 0' >> /etc/fstab
mkdir /root/srv-backup-cifs
mount /root/srv-backup-cifs
Création d’un fichier sparse
de 1Tio. Je n’ai pas cet espace de stockage, mais si un jour il y en a besoin, le fichier est déjà prêt. Bon enfin c’est juste pour faire joujou hein.
cd /root/srv-backup-cifs
dd if=/dev/zero of=luks.backup.raw count=0 seek=1024G
cryptsetup luksFormat luks.backup.raw # passez les options que vous souhaitez pour chiffrer votre conteneur
Une fois que c’est fait, on va pouvoir ouvrir notre LUKS et y créer un système de fichier afin de stocker normalement nos fichiers :
cryptsetup luksOpen luks.backup.raw luks_backup # --key-file vous sera utile pour stocker une passphrase dans un fichier afin de monter le volume sans intervention manuelle. À conserver à l’abrit des regards indiscrets…
mkfs.ext4 /dev/mapper/luks_backup
BURP
Cette solution de sauvegarde et restauration est simple, légère (129KB!) , en mode client/serveur, gère les sauvegardes incrémentales et leur restauration, utilise SSL pour les communications, se configure très facilement… et tout un tas d’autres choses, j’en parlerai une autre fois.
Et voici un exemple de configuration qui va bien :
---
burp_server_clients:
- { cname: '01-mail', password: 'secret' }
burp_server_timer_args:
- '1s'
burp_server_script_pre: '/root/mount-backup.sh'
En tout cas, par défaut, BURP sauvegarde dans /var/spool/burp
.
Bon bah, il ne nous reste plus qu’à faire notre montage :
mount /dev/mapper/luks_backup /var/spool/burp
Voici la configuration serveur BURP qui nous intéresse :
mode = server
directory = /var/spool/burp
working_dir_recovery_method = delete
user=root
group=root
Tous les fichiers seront stockés en root:root
dans le répertoire vu plus haut. Et voici la configuration d’un client :
mode = client
server = host-backup-burp.local
cname = 01-mail
user=root
group=root
include = /var/vmails/
exclude_fs = sysfs
exclude_fs = tmpfs
min_file_size = 0 Mb
max_file_size = 0 Mb
Une fois que nous aurons lancé un backup sur le client et que celui-ci sera terminé (burp -a b
), nous aurons un petit nouveau dans /var/spool/burp
:
├── 01-mail
│ ├── 0000001 2015-04-15 16:28:36
│ │ └── data
│ │ └── t
│ │ └── var
│ │ └── vmails
... bla bla bla bla bla bla bla bla bla bla bla ...
│ └── current -> 0000001 2015-04-15 16:28:36
Si je recommance un backup un peu plus tard, un nouveau dossier daté sera créé et le pointeur current
sera déplacé sur ce nouveau dossier. Et je n’aurai en tout que le différentiel du backup.
Scripter BURP
Pour s’assurer que nos backup seront bien faits sur notre luks, et pas notre machine locale, ajoutons un script qui se lancera à chaque connexion d’un client :
server_script_pre=/root/mount-backup.sh
mount-backup.sh
#!/bin/sh
if [ ! -e /dev/loop0 ]; then
mknod /dev/loop0 b 7 0 || exit 1
fi
if [ "$(mount|grep "/var/spool/burp"|grep -v grep)" = "" ]; then
mount /root/srv-backup-cifs || exit 1
cryptsetup luksOpen /root/srv-backup-cifs/luks.backup.rawdisk luks_backup --key-file /root/luks_backup_keyfile 2>&1 || exit 1
mount /dev/mapper/luks_backup /var/spool/burp || exit 1
else
echo "already mounted"
fi
C’est un peu moche et pas franchement résistant à la panne… que se passe-t-il si coupure réseau ? Le mieux serait de démonter notre "disque" à chaque fin de backup si possible (= pas d’autre backup en cours).
Je ne sais pas si une unité systemd
serait plus efficace dans ce genre de job, en tout cas ça serait à tester.
Conclusion
Il me semble n’avoir rien oublié, aussi si ça ne fonctionne pas, un petit mail et je corrige.