diff --git a/README.md b/README.md index 465c245..8c43d6f 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,67 @@ # borgwrapper Wrapper to simplify backups with borgbackup +# Installation +Put the script somewhere practical + + cp borgwrapper.sh /usr/local/bin/borgwrapper + chown root. /usr/local/bin/borgwrapper + chmod 750 /usr/local/bin/borgwrapper + # Configuration By default borgwrapper expects the configuration to be located at `/etc/borgwrapper/config.sh`. Ensure restrictive permissions on this file as it exposes the passphrase. - chown root:root config.sh + chown root. config.sh chmod 600 config.sh - + Example cron jobs: - + # Run the backup daily - 23 1 * * * /usr/local/sbin/borgwrapper.sh backup - + 23 1 * * * /usr/local/bin/borgwrapper backup + # Verify the backups once a month - 40 17 23 * * /usr/local/sbin/borgwrapper.sh verify + 40 17 23 * * /usr/local/bin/borgwrapper verify + +# Borg server preparation +Install borg and then + + adduser --system --group --shell /bin/bash borg + mkdir /srv/borg + chown borg. /srv/borg + chmod 755 /srv/borg +Generate the needed passwordless ssh-keys as root (the user you run the backup as) on the client + + ssh-keygen +Copy the content of the generated public key in /root/.ssh/ to `/home/borg/.ssh/authorized_keys` on the server, with +some restrictions so it looks something like this: + + command="borg serve --restrict-to-path /srv/borg/",no-pty,no-agent-forwarding,no-port-forwarding,no-X11-forwarding, no-user-rc ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDeCInOLjv0hgzI0u1b/p4yYnCEV5n89HIXF1hrLor+ZQ7lSUii21tpn47Aw8RJJAjfDCwCdQ27MXjpzNelBf4KrlAiN1K3FcnGGIiE3XFNoj4LW7oAjzjFgOKC/ea/hXaCI6E8M/Pn5+MhdNN1ZsWNm/9Zp0+jza+l74DQgOE33XhSBjckUchqtBci7BqoCejy2lVvboFA231mSEpPValcKmG2qaNphAkCgAPjtDOx3V6DGQ8e7jfA2McQYxfju6HlpWPUx/li6VJhRa5huczfJ3J/sdfu123s/lgTW4rG5QNng1vt1FOIZ/TkaEsPt2wzD2Qxdwo70qVts3hrd+r root@client # Usage ## Initialize backup repo - (. /etc/borgwrapper/config.sh; export BORG_PASSPHRASE; borg init "$REPO") + borgwrapper init ## Backup - borgwrapper.sh backup + borgwrapper backup ## Verify backups - borgwrapper.sh verify + borgwrapper verify ## Unlock after unclean exit - borgwrapper.sh unlock + borgwrapper unlock ## Run other borg commands -Run in subshell if you do not want the passphrase stored in the current shell even after the commands have exited. +### Wrapped and easy +Use `exec `. `BORG_REPO` is exported to the environment so use `::` when the repo +argument is required. + +Example: + + borgwrapper exec mount :: /mnt +### Borg directly +Run in subshell if you do not want the passphrase stored in the current shell after the command have exited. Examples: - (. /etc/borgwrapper/config.sh; export BORG_PASSPHRASE; borg list "$REPO") - (. /etc/borgwrapper/config.sh; export BORG_PASSPHRASE; borg mount "$REPO" /mnt) + (. /etc/borgwrapper/config.sh; export BORG_PASSPHRASE; borg mount "$BORG_REPO" /mnt) diff --git a/src/borgwrapper.sh b/src/borgwrapper.sh index 0515fbb..ea54502 100755 --- a/src/borgwrapper.sh +++ b/src/borgwrapper.sh @@ -11,6 +11,11 @@ print_usage () { echo " MODE backup|verify|unlock" } +borg_init () { + ${BORG} init "${BORG_REPO}" +} + + borg_backup () { EXCLUDE_CMD=() @@ -21,7 +26,7 @@ borg_backup () { ${BORG} create --info --stats \ --compression lz4 \ --numeric-owner \ - "${REPO}"::"{hostname}-$(date -u +'%Y%m%dT%H%M%SZ')" \ + "${BORG_REPO}"::"{hostname}-$(date -u +'%Y%m%dT%H%M%SZ')" \ "${PATHS[@]}" \ "${EXCLUDE_CMD[@]}" } @@ -36,29 +41,43 @@ borg_prune () { --keep-weekly=${KEEP_WEEKLY} \ --keep-monthly=${KEEP_MONTHLY} \ --keep-yearly=${KEEP_YEARLY} \ - "${REPO}" + "${BORG_REPO}" } borg_verify () { - ${BORG} check --info "${REPO}" + ${BORG} check --info "${BORG_REPO}" } borg_unlock () { # Use if borgbackup is not shut down cleanly and complains about lock files - ${BORG} break-lock "${REPO}" + ${BORG} break-lock "${BORG_REPO}" } +borg_exec () { + export BORG_REPO + ${BORG} "$@" +} source "${CONFIG}" || exit 1 export BORG_PASSPHRASE -if [[ ${MODE} == "backup" ]]; then +if [[ ${MODE} == "init" ]]; then + borg_init +elif [[ ${MODE} == "backup" ]]; then borg_backup borg_prune elif [[ ${MODE} == "verify" ]]; then borg_verify elif [[ ${MODE} == "unlock" ]]; then borg_unlock +elif [[ ${MODE} == "exec" ]]; then + if [[ $# -le 1 ]]; then + echo "ERROR: No borg arguments given" + exit 1 + fi + + shift + borg_exec "$@" else print_usage fi diff --git a/src/config.sh.example b/src/config.sh.example index 3ef835e..94dceb0 100644 --- a/src/config.sh.example +++ b/src/config.sh.example @@ -1,5 +1,5 @@ BORG="/usr/bin/borg" -REPO="user@reposerver:/srv/borg/$(hostname -f)" +BORG_REPO="user@reposerver:/srv/borg/$(hostname -f)" BORG_PASSPHRASE="longandcomplexpassphrase" PATHS=( "/etc"