Add borg
This commit is contained in:
parent
a79b5de5ff
commit
c5be15b7bf
94
borg/backup.sh
Normal file
94
borg/backup.sh
Normal 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 won’t 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
8
borg/borg-daily.service
Normal 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
10
borg/borg-daily.timer
Normal 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
48
install/borg.sh
Executable 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/
|
Reference in a new issue