Outils pour utilisateurs

Outils du site


technique:admin-systeme:borg

Borg Backup

Install

Est un outil de backup sur disque qui déduplique, compresse, et chiffre. C'est du python propre avec un format ouvert.

La version 1.1.5 supporte la compression zstd (merci Facebook) et améliore des aspects de sécurités par rapport à la série 1.0.x (et par rapport à un trou de la 1.1.3 ou .4).

$ echo 'deb http://ftp.debian.org/debian stretch-backports main' | sudo tee /etc/apt/sources.list.d/backports.list
$ sudo apt update
$ sudo apt install -t stretch-backports borgbackup

Borg n'a pas de démons. Sa command-line ressemble à git. Il sait gérer des remote repo over SSH. Il utilise des variables d'environnement.

Borg ne supporte pas vraiment le mode "pull". La philosophie est de déclencher via cron le programme borg sur la machine à sauvegarder, en lui indiquant un dépôt distant sur le serveur de backup. Il n'y a pas de "director" ou de planificateur.

Il n'est pas conseillé (ni pratique) de sauver plusieurs machines dans un seul repo borg car borg lock() le dépôt entier pendant une sauvegarde… Un repo par machine est le plus simple.

Dépôt distant

Sur la machine de backup (ici itn-tls1) :

$ sudo chsh backup
#Changing the login shell for backup
#Enter the new value, or press ENTER for the default
#        Login Shell [/usr/sbin/nologin]: /bin/sh
#
$ sudo ssh-keygen
Generating public/private rsa key pair.
#Enter file in which to save the key (/root/.ssh/id_rsa): /root/.ssh/id_rsa
#Enter passphrase (empty for no passphrase): 
#Enter same passphrase again: 
#[...]
 
$ sudo mkdir ~backup/{.ssh,borg}
$ sudo chown backup: ~backup/{.ssh,borg}
$ echo 'command="borg serve --restrict-to-path /var/backups/borg/<nom-machine-a-sauver>",restrict ssh-rsa  [...] root@r1'| sudo -u backup tee -a /var/backups/.ssh/authorized_keys
 
$ sudo ls -l /var/backups/.ssh/authorized_keys
#-rw-r--r-- 1 backup backup 465 juin   9 20:59 /var/backups/.ssh/authorized_keys

À ce stade, on a assez pour initialiser le repo distant. Il sera chiffré avec une passphrase que seul r1 a sur son disque (+ copie dans le keepass pour restaurer sur une autre machine si on perd totalement r1) :

Sur la machine à sauvegarder (ici r1) :

$ sudo borg init -e repokey ssh://backup@itn-tls1.tetaneutral.net:22/var/backups/borg/r1
#Enter new passphrase: 
#Enter same passphrase again: 
#Do you want your passphrase to be displayed for verification? [yN]: n
$ cat | sudo tee /root/borg-passphrase
# Coller la passphrase choisie puis retour chariot puis Ctrl+D
$ chmod 400 /root/borg-passphrase

Configuration et plannification

A présent, on veut l'environnement qui va bien pour les autres commandes borg

/etc/default/borg
# Setting this, so the repo does not need to be given on the commandline:
export BORG_REPO=ssh://backup@itn-tls1.tetaneutral.net:22/var/backups/borg/<nom-machine-a-sauver>
 
# or this to ask an external program to supply the passphrase:
export BORG_PASSCOMMAND='cat /root/borg-passphrase'
 
# Sleep time in seconds before actually starting borg create command
SLEEP_BEFORE_BORG_CREATE=$RANDOM

$RANDOM tire un nombre au hasard en 0 et 32768.

Borg utilise des fichiers chunk et est gentil avec le filesystem (écritures linéaires…) donc il n'y a pas de gros problèmes à prévoir si plusieurs borg se font concurrence sur un même serveur de backup à la même heure.

/root/.bashrc
# [...]
# Config is now in /etc/default/borg
[ -r /etc/default/borg ] && . /etc/default/borg
$ sudo -i
 
root@r1:~# borg info
Repository ID: b784187fcc5781e693bab3c4125dee4396b5e3a8b6c84cbcc99a3918cd1c6618
Location: ssh://backup@itn-tls1.tetaneutral.net:22/var/backups/borg/r1
Encrypted: Yes (repokey)
Cache: /root/.cache/borg/b784187fcc5781e693bab3c4125dee4396b5e3a8b6c84cbcc99a3918cd1c6618
Security dir: /root/.config/borg/security/b784187fcc5781e693bab3c4125dee4396b5e3a8b6c84cbcc99a3918cd1c6618
------------------------------------------------------------------------------
                       Original size      Compressed size    Deduplicated size
All archives:                   0 MB                 0 MB                 0 MB
 
                       Unique chunks         Total chunks
Chunk index:                       0                    0

A présent, on veut automatiser la sauvegarde journalière.

Astuce pour sauver "/", y compris les fichiers masqués sous les point de montages virtuels tel que /dev. FIXME: Je ne suis pas encore super certain que ça soit bien en toute circonstance ça.

/etc/fstab
root@r1:~# cat /etc/fstab 
# /etc/fstab: static file system information.
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
# [...]
# Pour borg-backup (avec submount des autres partitions listées ici)
/		/mnt/rootfs	none	bind		0	0
/etc/borg-create.sh
#!/bin/sh
 
# Config is now in /etc/default/borg
[ -r /etc/default/borg ] && . /etc/default/borg
 
# some helpers and error handling:
info() { printf "\n%s %s\n\n" "$( date --rfc-3339=seconds )" "$*" >&2; }
trap 'echo $( date --rfc-3339=seconds ) Backup interrupted >&2; exit 2' INT TERM
 
if [ $SLEEP_BEFORE_BORG_CREATE -gt 0 ]; then
	info "Sleeping $SLEEP_BEFORE_BORG_CREATE seconds"
	sleep $SLEEP_BEFORE_BORG_CREATE
fi
 
info "Starting backup"
 
# Backup the most important directories into an archive named after
# the machine this script is currently running on:
 
borg create                                    \
    --verbose                                  \
    --filter AME                               \
    --list                                     \
    --stats                                    \
    --show-rc                                  \
    --compression zstd                         \
    --exclude-caches                           \
    --exclude '/mnt/rootfs/home/*/.cache/*'    \
    --exclude '/mnt/rootfs/tmp/*'              \
    --exclude '/mnt/rootfs/var/backups/*'      \
    --exclude '/mnt/rootfs/var/cache/*'        \
    --exclude '/mnt/rootfs/var/tmp/*'          \
                                               \
    ::'{hostname}-{now}'                       \
    /mnt/rootfs/
 
backup_exit=$?
 
info "NOT Pruning repository"
#info "Pruning repository"
#
# Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly
# archives of THIS machine. The '{hostname}-' prefix is very important to
# limit prune's operation to this machine's archives and not apply to
# other machines' archives also:
#
#borg prune                          \
#    --list                          \
#    --prefix '{hostname}-'          \
#    --show-rc                       \
#    --keep-daily    7               \
#    --keep-weekly   4               \
#    --keep-monthly  6               \
#
#prune_exit=$?
prune_exit=0
 
# use highest exit code as global exit code
global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit ))
 
if [ ${global_exit} -eq 1 ];
then
    info "Backup and/or Prune finished with a warning"
fi
 
if [ ${global_exit} -gt 1 ];
then
    info "Backup and/or Prune finished with an error"
fi
 
exit ${global_exit}

Borg déduplique, garder 400 versions d'une backup ne coûte en général pas plus cher que la taille non compréssée d'une seule version complète !

L'heure de démarrage sera au hasard entre 21:00:00 et (21h + 32768s), soit 06:06:08, donc très probablement avant les cron.{daily,weekly,monthly} de 6h25 et +.

/etc/cron.d/borg
# /etc/cron.d/borg: crontab entries for backing up this system
 
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
 
0 21 * * *       root    nice -n10 /etc/borg-create.sh
 
# EOF

Premier backup

Pour tester le script, le lancer en root. Il va attendre probablement longtemps. Pour esquiver ça killall sleep est une solution un peu brutale mais probablement très pertinente.

$ sudo -i
root@r1:~# /etc/borg-create.sh

Borg fait un checkpoint toutes les 5 minutes, si le transfert initial est très long et qu'internet coupe, c'est pas grave, borg reprendra au prochain coup là où il en était.

Pas de problèmes si la cron déclenche la sauvegarde alors qu'elle tourne déjà, borg ne fera pas de bêtises.

Explorer et restaurer

En root c'est + simple (sinon sudo -E après avoir chargé /etc/default/borg).

$ sudo -i
 
borg list
#r1-2018-06-10T20:33:08         Sun, 2018-06-10 20:33:09 [a15bf4...]
cd /mnt
mkdir tmp
borg mount ::r1-2018-06-10T20:33:08 /mnt/tmp
 
# On peut parcourir le backup comme un vrai filesystem
cd tmp/mnt/rootfs/
ls
#bin   dev  home        initrd.img.old  lib64	   media  opt	root  sbin  sys  usr  vmlinuz
#boot  etc  initrd.img  lib	       lost+found  mnt	  proc	run   srv   tmp  var  vmlinuz.old
 
# Test à blanc de restauration (liste ce qui serait copié / supprimé)
rsync -n -ai --delete ./home/lpouzenc /home/
# Restauration
rsync -ai --delete ./home/lpouzenc /home/
# Et hop mon homedir est restauré en date du 2018-06-10T20:33:08 !
# On démonte le filesystem virtuel du backup (fuse)
cd /mnt
fusermount -u /mnt/tmp
technique/admin-systeme/borg.txt · Dernière modification: 2018/06/10 22:06 par Ludovic