From 42daa9e35ee33c86bfe938ef19cf45e6cc613b17 Mon Sep 17 00:00:00 2001 From: Ludwig Behm Date: Wed, 5 Apr 2023 20:17:06 +0200 Subject: [PATCH] working init.sh script and readme --- README.md | 56 ++++++++++++++++++++++++++++- init.sh | 104 +++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 150 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index c054502..021b1db 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,57 @@ # borg-backup-scripts -borg backup scripte used on KrautSpace infra \ No newline at end of file +borg backup scripte used on KrautSpace infra + +## Requirements +``` +sudo apt install borg +``` + +## Usage + +### Initialization + +``` +sudo ./init.sh remote_site_1 --host=whatever.your-storagebox.de --port=23 --login=whatever --directory=/home/borg +``` + +What this does: + + * Creates a config directory at `/etc/borg/remote_site_1`. + * Creates a passphrase for borg. + * Creates a ssh keypair for the ssh connection to your remote ssh backup destination host. + * Deploys the ssk public key to the remote ssh account using `ssh-copy-id`. + * Checks if the destination path is usable. + * Initializes the borg repository. + * Prints out the borg repository status if initialization was successfull. + * Attempts to continue the init process if called multiple times. + +### Service installation + +``` +# on productive system: copy systemd-units in /etc/systemd/system +sudo ./install.sh + +# on development system: link systemd-units from current directory +sudo ./install_as_link.sh +``` + +### Service activation + +``` +sudo systemctl enable borg-backup@remote_site_1.timer +sudo systemctl enable borg-prune@remote_site_1.timer +``` + +## FAQ + +### Why so much `sudo`? + +> Good question!\ +> The borg backup process requires priviledges to read everything you want to backup.\ +> The systemd-units sandbox the borg process to a read-only view of the filesystem. + +### Can I trust this code? + +> Never trust anything from the internet.\ +> Download and verify what it does. It should be somewhat readable. diff --git a/init.sh b/init.sh index 262650a..04be8db 100755 --- a/init.sh +++ b/init.sh @@ -1,7 +1,11 @@ #!/bin/bash -NAME="$1" -DEST="$2" +SELF="$0" +HOST="" +PORT="22" +REMOTE_PATH="borg" +NAME="" +LOGIN="$(whoami)" die () { echo $1 >&2 @@ -10,16 +14,98 @@ die () { generate_passphrase() { tr -dc A-Za-z0-9 " -[ "x$DEST" == "x" ] && die "Usage: $0 " + install --directory --owner=$(id -u) --group=$(id -g) --mode=600 "$CONFIGDIR" || die "Can't create directory $CONFIGDIR" + + umask 177 + + generate_passphrase > "$CONFIGDIR/borg_passphrase" + ssh-keygen -t ed25519 -N "" -q -f "$CONFIGDIR/ssh_key" -C "borg access from $(hostname --long)" + exec ssh-copy-id -i "$CONFIGDIR/ssh_key.pub" -p $PORT "$LOGIN@$HOST" +} +test_ssh() { + ssh -q -o "BatchMode=yes" -i "$CONFIGDIR/ssh_key" -p "$PORT" "$LOGIN@$HOST" "mkdir -p $REMOTE_PATH" \ + || die "SSH connection attempt failed." + return 0 +} +test_repo_exists() { + ssh -q -o "BatchMode=yes" -i "$CONFIGDIR/ssh_key" -p "$PORT" "$LOGIN@$HOST" "cat $REMOTE_PATH/README" 2>/dev/null | grep -q "This is a Borg Backup repository." + return $? +} +invoke_borg() { + ( + export BORG_RSH="ssh -i $CONFIGDIR/ssh_key" + export BORG_REPO="ssh://$LOGIN@$HOST:${PORT}${REMOTE_PATH}" + export BORG_PASSPHRASE_FD=0 + exec /usr/bin/borg $@ < "$CONFIGDIR/borg_passphrase" + ) +} +init_repo() { + echo "> init repo" + invoke_borg init -e repokey-blake2 || die "failed to init borg repo" +} +show_repo() { + echo "> testing repo connection" + invoke_borg info || die "failed to access borg repo" +} + +usage() { + die "Usage: $SELF PROFILE_NAME --host=server --port=22 --login=backup-user --directory=/backup/path" +} + +for arg in "$@"; do + case "$arg" in + -p*) + PORT="${arg#-p}" + ;; + --port=*) + PORT="${arg#--port=}" + ;; + -l*) + LOGIN="${arg#-l}" + ;; + --login=*) + LOGIN="${arg#--login=}" + ;; + -h*) + HOST="${arg#-h}" + ;; + --host=*) + HOST="${arg#--host=}" + ;; + -d*) + REMOTE_PATH="${arg#-d}" + ;; + --directory=*) + REMOTE_PATH="${arg#--directory=}" + ;; + -*) + usage + ;; + *) + NAME="$arg" + esac +done + +[ "x$NAME" == "x" ] && usage CONFIGDIR="/etc/borg/$NAME" -[ -d "$CONFIGDIR" ] && die "Config directory already exists: $CONFIGDIR" +echo "> checking config" +[ -e "$CONFIGDIR" ] || init_config_dir || die "Failed setting up config directory and ssh connection" +[ -d "$CONFIGDIR" ] || die "Config directory isn't valid: $CONFIGDIR" +[ -r "$CONFIGDIR/borg_passphrase" ] || die "File isn't readable: $CONFIGDIR/borg_passphrase" +[ -r "$CONFIGDIR/ssh_key" ] || die "File isn't readable: $CONFIGDIR/ssh_key" -mkdir -p "$CONFIGDIR" +# write config every time, parameter may change with each invocation +echo "BORG_REPO=ssh://$LOGIN@$HOST:${PORT}${REMOTE_PATH}" > "$CONFIGDIR/config.env" +[ -r "$CONFIGDIR/config.env" ] || die "File isn't readable: $CONFIGDIR/config.env" -echo "BORG_REPO=$DEST" > "$CONFIGDIR/config.env" -generate_passphrase > "$CONFIGDIR/borg_passphrase" -ssh-keygen -t ed25519 -N "" -q -f "$CONFIGDIR/ssh_key" +echo "> testing ssh and destination path" +test_ssh || die "Can't establish ssh connection! Try: ssh-copy-id -i $CONFIGDIR/ssh_key.pub -p $PORT $LOGIN@$HOST" + +echo "> testing borg repo" +test_repo_exists || init_repo +show_repo