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

  1. Créer un utilisateur "backup" sur le synology avec SSH + SFTP + SSH key
  2. Configurer sshfs avec une clé SSH sur le client
  3. Installer, initialiser et tester le repo Borg
  4. 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 :

  1. Que l'utilisateur fasse partie du groupe administrators pour avoir accès au login SSH
  2. 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//.ssh/authorized_keys
  3. 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 :

  1. Il monte le répertoire sshfs
  2. Il crée un backup avec le nom de la machine + date courante
  3. Il effectue le nettoyage des archives si besoin (rétention)
  4. 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 😉

Source

sshfs/ssh key sur Synology
Borg backup commands + script

Comments

Comment by zarakoff on 2019-06-15 14:40:42 +0200

Salut,
Bon petit tuto, mais je vais néanmoins faire part de ma mésaventure
Sur la base du script, j'en ai fait 3. L'un pour sauvegarder mon nas A vers un nas B, le suivant pour sauvegarder /home vers le nas B et enfin le 3ème pour sauvegarder / vers nas B (en excluant quelques répertoires néanmoins).
les scripts (que je nommerai nas.sh, home.sh et root.sh) fonctionnaient parfaitement lorsqu'ils étaient lancés manuellement.
Les scripts nas.sh et home.sh fonctionnaient parfaitement lorsqu'ils sont lancés via cron.
Par contre, le script root.sh ne fonctionnait pas lorsqu'il était lancé par cron. En creusant un peu, j'ai vu un message dans un log (que j'ai mis pour tracer) qui me disait read: connection reset by peer
Le problème se situait (selon moi) au niveau du montage via sshfs qui montait bien le file système du syno mais le démontait rapidement
Quand je regardais dans les logs du synology, je voiyais ceci :
info 2019/06/10 21:40:03 backup: SFTP client [backup] from [192.168.1.2] logged in through SFTP.
info 2019/06/10 21:40:59 backup: SFTP client [backup] from [192.168.1.2] logged out the server with totally [102.21 MB] uploaded and [ 18.99 MB] downloaded.
On voit donc que le script fonctionnait et la sauvegarde s'était bien lancée
Lorsque le script root.sh etait lancé, on voit ça :
warning 2019/06/10 21:41:02 SYSTEM: User [backup] from [192.168.1.2] failed to log in via [SSH] due to authorization failure.
On peut donc remarque que le disque n'était pas monté.
D'autre part, on constate que lorsque le script "fonctionne" (donc nas.sh ou home.sh), on voit apparaitre la notion de SFTP alors que lorsque le script ne "fonctionne pas" (donc root.sh), on voit apparaitre non pas SFTP mais ssh
Si je lançais le script root.sh manuellement, je me retrouvais avec un succès au niveau des logs et ma sauvegarde fonctionne.
En reprenant le tuto, et après quelques essais, je me suis aperçu que ma clé rsa générée pour le compte root (nécessaire pour backup /) n'était pas prise en compte, bien qu'étant connecté en root. En fait de root, j'étais connecté sous mon compte puis faisait un su pour basculer en root. Je pense que le problème vient de là.
En me connectant en root (directement de la console), et en générant ma clé (et en l'exportant bien évidemment), tout est rentré dans l'ordre.

Merci encore pour ce tuto bien expliqué.