Archived
1
0
Fork 0
This commit is contained in:
Casper V. Kristensen 2022-05-10 01:25:47 +02:00
parent a79b5de5ff
commit c5be15b7bf
4 changed files with 160 additions and 0 deletions

94
borg/backup.sh Normal file
View file

@ -0,0 +1,94 @@
#!/bin/bash
# Desktop notification
function notify() {
if [ -x "$(command -v notify-send)" ]; then
# https://stackoverflow.com/questions/28195805/running-notify-send-as-root/49533938#49533938
local display=":$(ls /tmp/.X11-unix/* | sed 's#/tmp/.X11-unix/X##' | head -n 1)"
local uid=$(id -u caspervk)
sudo -u caspervk DISPLAY=$display DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus notify-send --expire-time=0 --icon=backup "$@"
fi
}
notify "Borgbackup: Started"
# Avoid UnicodeError
export LANG=en_US.UTF-8
# Ask an external program to supply the repository passphrase:
export BORG_PASSCOMMAND='cat /usr/local/etc/borg/passphrase.key'
# When running Borg using an automated script, ssh might still ask for a password, even if there is an SSH key for
# the target server. Use this to make scripts more robust:
export BORG_RSH='ssh -oBatchMode=yes'
# Set repository location
# Note: because of the way the server is set up, the repo resides in `/home/borg/repos/<hostname>/` on the server.
export BORG_REPO=ssh://borg@sigma.caspervk.net:222/./auto-full
# Initialize remote repository (doesn't matter if it already is).
borg init --encryption=repokey-blake2
# Backup directories into an archive named after the machine and current utc time.
# Patterns:
# A backup root (starting point) path starts with the prefix R, followed by a path.
# An include rule starts with the prefix +.
# An exclude rule starts with the prefix -.
# An exclude-norecurse rule starts with !.
borg create \
--filter AME \
--show-rc \
--stats \
--compression zstd \
--remote-ratelimit 0 \
--exclude-caches \
\
--pattern '! /dev' \
--pattern '! /proc' \
--pattern '! /sys' \
--pattern '! /var/run' \
--pattern '! /var/tmp' \
--pattern '! /run' \
--pattern '! /tmp' \
--pattern '! /lost+found' \
--pattern '! /var/cache' \
--pattern '! /**/found.000/*' \
--pattern '! /mnt' \
\
--pattern '! /home/*/.steam' \
--pattern '! /home/*/GOG Games' \
--pattern '! /home/*/.cache' \
--pattern '! /home/*/Downloads' \
--pattern '! /home/*/.local/share/Trash' \
\
--pattern '+ /media/caspervk/C/Users/Casper/Desktop' \
--pattern '+ /media/caspervk/C/Program Files (x86)/World of Warcraft/_classic_' \
--pattern '- /media' \
\
--pattern '- /media/caspervk/Backup/Downloads' \
--pattern '- /media/caspervk/Backup/monero' \
--pattern '- /media/caspervk/Backup/Programmer/VirtualBox' \
--pattern '+ /media/caspervk/Backup' \
::'{hostname}-{utcnow}' \
/
backup_exit=$?
# Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly archives:
# Note that as the repo is append-only, prune wont free disk space, but merely tag data as deleted in a new
# transaction. As soon as we write to the repo in non-append-only mode (e.g. prune, delete or create archives from an
# admin machine), it will remove the deleted objects permanently (including the ones that were already marked as
# deleted, but not removed, in append-only mode).
borg prune \
--list \
--show-rc \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 6
prune_exit=$?
notify "Borgbackup: Finished"
# use highest exit code as global exit code
global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit ))
exit ${global_exit}

8
borg/borg-daily.service Normal file
View file

@ -0,0 +1,8 @@
[Unit]
Description=Daily full system borg backup
After=network.target network-online.target
[Service]
Type=oneshot
ExecStartPre=/bin/sh -c 'until host sigma.caspervk.net; do sleep 10; done'
ExecStart=/usr/local/sbin/backup.sh

10
borg/borg-daily.timer Normal file
View file

@ -0,0 +1,10 @@
[Unit]
Description=Daily full system borg backup
[Timer]
OnCalendar=*-*-* 00:00:00
RandomizedDelaySec=6h
Persistent=true
[Install]
WantedBy=timers.target

48
install/borg.sh Executable file
View file

@ -0,0 +1,48 @@
#!/bin/bash
set -e
# Packages
sudo apt update
sudo apt upgrade
sudo apt install -y borgbackup
# Backup script - not symlinked to avoid potential privilege escalation
sudo cp borg/backup.sh /usr/local/sbin/backup.sh
sudo chown root:root /usr/local/sbin/backup.sh
sudo chmod 744 /usr/local/sbin/backup.sh
# Passphrase
if [ ! -f /usr/local/etc/borg/passphrase.key ]; then
echo '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
echo '@@ PLEASE BACKUP BORG PASSPHRASE: @@'
pwgen 32 1 | sudo tee /usr/local/etc/borg/passphrase.key
echo '@@ (/usr/local/etc/borg/passphrase.key) @@'
echo '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
read -p 'Press any key to continue..'
sudo chmod 600 /usr/local/etc/borg/passphrase.key
fi
# Systemd service and timer - not symlinked to avoid potential privilege escalation
sudo cp borg/borg-daily.service /etc/systemd/system/
sudo cp borg/borg-daily.timer /etc/systemd/system/
sudo chown root:root /etc/systemd/system/borg-daily.service /etc/systemd/system/borg-daily.timer
sudo systemctl enable borg-daily.timer
# SSH
ssh-keyscan -t ed25519 -p 222 sigma.caspervk.net | sudo tee /root/.ssh/known_hosts # add backup server to known_hosts
sudo ssh-keygen -t ed25519 # generate key for the root user
echo "Please add the following to ~borg/.ssh/authorized_keys:"
echo "command=\"mkdir -p ~/repos/$(hostname); cd ~/repos/$(hostname); borg serve --append-only --restrict-to-path ~/repos/$(hostname)\",restrict $(sudo cat /root/.ssh/id_ed25519.pub)"
ssh sigma.caspervk.net -p 222
# To setup the server:
# sudo apt install borgbackup
# sudo adduser --disabled-password borg
# sudo su borg
# cd ~
# mkdir repos/
# chmod 700 repos/