Backup avec Borg via ssh(fs) sur Synology
Tant qu'à faire un peu de ménage sur notre dédié, je me suis décidé à changer de mode de backup en passant à Borg.
Le postulat
- Utiliser Borg (avec l'encyrption + passphrase)
- Faire des backups de chaque VM (hebergé dans XEN) quotidiennement
- Garder une rétention correct (7 journalières; 4 hebdomadaires; 6 mensuelles)
- Tout envoyer sur un NAS Synology (en utilisant SSHFS)
Les prérequis
- NAS Synology, SSH + SFTP d'activé/configuré
- un script ssh pour envoyer l'IP public vers le dédié (pas nécéssaire si IP fixe)
- borgbackup & sshfs d'installé sur les clients
Dans mon cas, j'utilise un script sur mon synology qui récupère son IP public et qui l'envoie dans un fichier "ip_syn" sur le serveur m0le periodiquement
Les tâches
- Créer un utilisateur "backup" sur le synology avec SSH + SFTP + SSH key
- Configurer sshfs avec une clé SSH sur le client
- Installer, initialiser et tester le repo Borg
- Automatiser le tout avec un script
Création de l'utilisateur backup
Tout se passe depuis l'interface web, il faut s'assurer que l'utilisateur a le droit dans un dossier, disons /Backup (monté dans /volume1/Backup/)
Pour que la connexion par clé ssh fonctionne, il faut :
- Que l'utilisateur fasse partie du groupe administrators pour avoir accès au login SSH
- Activer le "User Home" Service dans Users > Advanced. Cela permet d'avoir un "vrai" répertoire pour l'utilisateur et pouvoir stocker les clés SSH de l'utilisateur (dans /var/services/homes/<user>/.ssh/authorized_keys
- Avoir les bons paramètres de sécurités/accès dans le dossier .ssh et autoriser la connexion par clé
On peut s'en sortir en exécutant ces commandes :
chmod 755 /var/services/homes/<user> chmod 700 /var/services/homes/<user>/.ssh chmod 600 /var/services/homes/<user>/.ssh/* chown -R <user>:users /var/services/homes/<user>/.ssh
Il faut également s'assurer que ces deux lignes soit décommenté dans /etc/ssh/sshd_config:
PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys
Installation de la clé ssh + sshfs + borg
Pour installer les dépendances sous Debian:
m0le# apt install sshfs
On passe à la génération de la clé ssh + l'envoi sur le synology
m0le# ssh-keygen -t rsa -b 4096 // Je genère une clé sans passphrase (pour automatiser le montage avec sshfs) m0le# ssh-copy-id <user>@<ip_synology> -p <port> // j'envoie la clé vers le synology m0le# ssh <user>@<ip_synology> -p <port> // Je vérifie que j'arrive bien à me connecter au server, sans demander de mot de passe.
On teste l'existence d'un dossier "Backup" accessible sur le synology
backup@synology$ cd Backup // j'utilise mon utilisateur dédié "backup" backup@synology Backup$ touch test // Je crée un fichier
On crée enfin le répertoire local pour monter le répertoire Backup avec sshfs
m0le# mkdir -p /mnt/syno // Je créer le repertoire pour le montage via SSHFS m0le# sshfs <user>@<ip_synology>/Backup/ /mnt/syno -p <port> // je monte le dossier Backup de mon synology sur le server m0le m0le# ls -l /mnt/syno // Si le fichier "test" s'affiche, c'est tout bon ! m0le# rm /mnt/syno/test // J'en ai plus besoin
Installation et initialisation de BorgBackup
On va dabord créer un repo qui va héberger nos "archives".
(les archives stockeront nos fichiers, le repo est l'endroit ou seront inventorier ces archives)
m0le# apt install borgbackup // installation de borgbackup m0le# borg init --encryption=repokey /mnt/syno/<repo> // création du repo en prenant soin de créer un mot de passe ! m0le# borg create /mnt/syno/<repo>::test /etc/ // Je créer une sauvegarde du dossier "/etc" dans un archive nommé "test" dans mon repo "/mnt/syno/<repo>"
Faire des tests et les supprimer
m0le# borg create --stats /mnt/syno/<repo>::test2 /etc/ // Je crée une deuxième archive "test2" du dossier /etc/ : Ca devrait être bcp plus rapide car "test" existe déjà. m0le# borg list /mnt/syno/<repo>::test2 // Si je liste le contenu du dossier "/etc", c'est tout bon ! m0le# borg delete /mnt/syno/<repo>::test // Je supprimer mes tests m0le# borg delete /mnt/syno/<repo>::test2 // Je supprimer mes tests
Script d'automatisation
Si tout va bien jusqu'ici, c'est qu'on a de quoi créer des archives Borg (manuellement pour l'instant), sur un repertoire de notre synology via sshfs.
Plutôt pas mal, on va donc automatiser ça ! Voilà ce que le script (cf source) fait :
- Il monte le répertoire sshfs
- Il crée un backup avec le nom de la machine + date courante
- Il effectue le nettoyage des archives si besoin (rétention)
- Il démonte le répertoire de backup
Évidemment, il faudra faire vos modifs comme celles que j'ai apportées par rapport à la source (cf les paramètres au debut)
#!/bin/bash # Mount parameters mount="/mnt/syno/" # Borg parameters repo="/mnt/syno/m0le" pass="legrosmotdepasse!!" backup_dir="/etc /root /usr/local/bin" # Synology parameters syno_user="backup" syno_ip=`cat /home/ip_syn` syno_port="22" syno_dir="/Backup/" # Setting this, so the repo does not need to be given on the commandline: export BORG_REPO=${repo} # Setting this, so you won't be asked for your repository passphrase: export BORG_PASSPHRASE=${pass} # or this to ask an external program to supply the passphrase: export BORG_PASSCOMMAND='pass show backup' # some helpers and error handling: info() { printf "\\n%s %s\\n\\n" "$( date )" "$*" >&2; } trap 'echo $( date ) Backup interrupted >&2; exit 2' INT TERM info "Mount ${mount} from ssh://${syno_user}@${syno_ip}:${syno_port}/${syno_dir}" sshfs ${syno_user}@${syno_ip}:${syno_dir} ${mount} -p ${syno_port} info "Starting backup: ${backup_dir}" # 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 lz4 \\ --exclude-caches \\ --exclude '/home/*/.cache/*' \\ --exclude '/var/cache/*' \\ --exclude '/var/tmp/*' \\ \\ ::'{hostname}-{now}' \\ $backup_dir \\ backup_exit=$? 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=$? # use highest exit code as global exit code global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit )) info "Unmounting ${mount}" umount ${mount} 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}
Il ne reste plus qu'à exécuter le script, vérifier l'archive et son contenu et enfin rajouter un petit cron qui va bien 😉