From 5800685a7034caf5ccae34add9958ca2be819b32 Mon Sep 17 00:00:00 2001 From: Silvio Rhatto Date: Thu, 16 May 2024 21:07:52 -0300 Subject: Borg fixes as pre-generated keyfiles are currently unsupported --- manifests/borg.pp | 4 +++- templates/borg.sh.erb | 66 ++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/manifests/borg.pp b/manifests/borg.pp index a1d82e8..39d4576 100644 --- a/manifests/borg.pp +++ b/manifests/borg.pp @@ -7,7 +7,9 @@ define backup::borg( $user = $::hostname, $host = "${title}.${::domain}", $encryption = 'repokey', - $keyfile = '', + $keyfile = '${title}', + $gpgkey = false, + $gpgpass = false, $order = 95, $periodic_check = absent, $password, diff --git a/templates/borg.sh.erb b/templates/borg.sh.erb index 4c79976..f64cf4e 100644 --- a/templates/borg.sh.erb +++ b/templates/borg.sh.erb @@ -1,29 +1,42 @@ #!/bin/bash +# +# Borg backup procedure for Backupninja # Adapted from https://borgbackup.readthedocs.io/en/stable/quickstart.html#automating-backups +# +# Parameters export SSH_SERVER="<%= @user %>@<%= @host %>" export SSH_PORT="<%= @port %>" - export HOSTNAME=`cat /etc/hostname` +# Set the repository # Setting this, so the repo does not need to be given on the commandline: export BORG_REPO=ssh://$SSH_SERVER:$SSH_PORT//var/backups/remote/$HOSTNAME/borg +# Set the passphrase # Setting this, so you won't be asked for your repository passphrase: export BORG_PASSPHRASE='<%= @password %>' -# or this to ask an external program to supply the passphrase: + +# Optional OpenPGP encryption for the keyfile +GPG_KEY="<%= @gpgkey %>" +GPG_PASS='<%= @gpgpass %>' + +# Setting the password command +# This allows to ask an external program to supply the passphrase: #export BORG_PASSCOMMAND='pass show backup' # Custom keyfile support if [ "<%= @encryption %>" == "keyfile" ] && [ ! -z "<%= @keyfile %>" ]; then - if [ ! -e "<%= @keyfile %>" ]; then - fatal "Keyfile not found: <%= @keyfile %>. Please create it manually." - fi + # Borg does not support providing a pre-generate key file anymore + # Details at https://github.com/borgbackup/borg/issues/7047 + #if [ ! -e "<%= @keyfile %>" ]; then + # fatal "Keyfile not found: <%= @keyfile %>. Please create it manually." + #fi export BORG_KEY_FILE="<%= @keyfile %>" fi -# some helpers and error handling: +# Error handling #info() { printf "\n%s %s\n\n" "$( date )" "$*" >&2; } trap 'info $( date ) Backup interrupted >&2; exit 2' INT TERM @@ -98,6 +111,43 @@ borg prune \ # fatal "Error pruning repository" #fi +# Have an OpenPGP-encrypted copy of the keyfile +# +# This is not ideal, but it's the workaround for configuration management. +# +# Borg does not support using pre-generated keys anymore (as of 2024-05-16), so +# we need an alternative way to access the repository keys if the original +# system becomes unavailable. +# +# The solution is to OpenPGP-encrypt the key file and upload it to the server, +# assuming that the operators have pre-generated the OpenPGP key and have a copy +# of it. They can use the same OpenPGP key used for Duplicity backups. +# +# The level of protection for the key will then be as strong as the OpenPGP key. +# +# Check also https://github.com/borgbackup/borg/issues/7047 +# https://borgbackup.readthedocs.io/en/latest/faq.html#how-important-is-the-home-config-borg-directory +if [ "<%= @encryption %>" == "keyfile" ] && [ ! -z "<%= @keyfile %>" ]; then + if [ ! -z "$GPG_KEY" ] && [ ! -z "$GPG_PASS" ]; then + info "Backing up the OpenPGP-encrypted repository key into the remote destination..." + + echo $GPG_PASS | gpg --passphrase-fd 0 --armor --encrypt \ + --recipient $GPG_KEY --default-key \ + --output $BORG_KEY_FILE.asc \ + --yes \ + $GPG_KEY $BORG_KEY_FILE + + gpg_exit=$? + + chmod 600 $BORG_KEY_FILE.asc + + scp -o Port=$SSH_PORT $BORG_KEY_FILE.asc \ + $SSH_SERVER:/var/backups/remote/$HOSTNAME/borg/keyfile.asc + + gpg_copy_exit=$? + fi +fi + # Use highest exit code as global exit code global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit )) @@ -112,3 +162,7 @@ fi if [ "${global_exit}" != "0" ]; then fatal "Error completing borg action: exit code ${global_exit}" fi + +if [ "${gpg_exit}" != "0" ] || [ "${gpg_copy_exit}" != "0" ]; then + fatal "Error backing the GPG-encrypted copy of the keyfile into the remote repository" +fi -- cgit v1.2.3