commit 1e2b15036ac88c95bb218566a0e45679c673a6b2 Author: Paul Scheunemann Date: Thu Aug 24 23:27:49 2017 +0200 inital commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cdd7c19 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +config.sh diff --git a/backupscript.sh b/backupscript.sh new file mode 100755 index 0000000..f0b99a3 --- /dev/null +++ b/backupscript.sh @@ -0,0 +1,109 @@ +#!/bin/bash + +# dir to backup + +cd $(dirname $0) + +usage() { + echo "backup script with snapshots" + echo "$0 [-x exclude dir] [-k N] " + echo + echo " -x excludes sub directory" + echo " -k defines how many snapshots to keep (default 7)" + echo " -q supress verbose output" + echo +} + +# read configuration variables +source config.sh + +BDIR="" +EXCLUDE="" + +#### READ PARAMETERS + +while getopts ":x:hqk:" opt; do + case $opt in + x) + EXCLUDE="${EXCLUDE} --exclude ${SNAPSHOTDIR}/${OPTARG}" + ;; + h) + usage + exit 0 + ;; + q) + QUIET="--quiet" + ;; + k) + KEEPLAST="${OPTARG}" + ;; + \?) + echo "ERROR: Invalid option: -$OPTARG" >&2 + usage + exit 1 + ;; + :) + echo "ERROR: Option -$OPTARG requires an argument." >&2 + usage + exit 1 + ;; + esac +done +shift $((OPTIND-1)) + +BDIR=${1} + +if [ -z "$BDIR" ]; then + echo "ERROR: Missing backup directory!" >&2 + usage + exit 2 +fi + +#### END READ PARAMETERS + +# umount and close everything if it is mounted before +uuid=$(cat /proc/sys/kernel/random/uuid) + +if ! ./lock.sh haslock; then + umount -v $SNAPSHOTDIR + cryptsetup close snapshot-decrypt + lvremove -f vg01/crypt-snapshot + + mkdir -p $SNAPSHOTDIR + + # create snapshot of data volume + sync + lvcreate -l100%FREE -s -n crypt-snapshot /dev/vg01/data-crypt || exit 1 + + # decrypt snapshot with key on unencrypted partition + echo mounting snapshot + cryptsetup open --type luks --key-file /data/_lukskeyfile /dev/vg01/crypt-snapshot snapshot-decrypt || exit 2 + + # mount the freshly decrypted backup + mount -o ro /dev/mapper/snapshot-decrypt $SNAPSHOTDIR || exit 3 +fi + +./lock.sh lock $uuid + +export RESTIC_PASSWORD=${BACKUP_PASSWORD} + +echo "Backup path: $SNAPSHOTDIR/$BDIR" +# backup the snapshot +# use -q for quiet mode (when run as a cron job) +$RESTIC --repo $URI $EXCLUDE $QUIET backup $SNAPSHOTDIR/$BDIR + +./lock.sh unlock $uuid + +if ! ./lock.sh haslock; then + # at this point we no longer need the snapshot and can unmount it + umount $SNAPSHOTDIR + cryptsetup close snapshot-decrypt + lvremove -f vg01/crypt-snapshot +fi + +# delete everything older than the last X snapshots +$RESTIC --repo $URI $QUIET forget --keep-last $KEEPLAST --path "$SNAPSHOTDIR/$BDIR" + +unset RESTIC_PASSWORD + +exit 0 diff --git a/config.sh.example b/config.sh.example new file mode 100755 index 0000000..51c6687 --- /dev/null +++ b/config.sh.example @@ -0,0 +1,18 @@ +# where to mount the LVM snapshots +SNAPSHOTDIR="/tmp/snapshot" + +# default number of backups that are kept, per path per host. +# will be overwritten by -k +KEEPLAST=7 + +# location of backup repository, hostname may be defined +# in .ssh/config +# at this location an initialized repository must exist +# (this can be done with `restic init`) +URI="sftp:backup:/backup" + +# Password that was supplied to `restic init` +BACKUP_PASSWORD="Password" + +# location of the static restic executable +RESTIC="/usr/local/bin/restic" diff --git a/crontab.example b/crontab.example new file mode 100644 index 0000000..bc778de --- /dev/null +++ b/crontab.example @@ -0,0 +1,8 @@ +# backup mail, once every 2 hours +30 */2 * * * /root/backup/backupscript.sh -k 20 mail +# backup userdirs +0 5 * * tue /root/backup/backupscript.sh -k 3 nfs +# backup everything else, every morning at 3AM +0 3 * * * /root/backup/backupscript.sh -k 7 -x mail -x nfs . +# clean up once a day at 12:10 (takes several hours) +10 12 * * * /root/backup/prune.sh diff --git a/prune.sh b/prune.sh new file mode 100755 index 0000000..d90efd7 --- /dev/null +++ b/prune.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# read configuration variables +source config.sh + +export RESTIC_PASSWORD=${BACKUP_PASSWORD} + +$RESTIC --repo $URI $QUIET prune + +unset RESTIC_PASSWORD