Borg backups from my archlinux workstation to a synology NAS
Since I setup my workstation with sway (see this article), the last thing I need to add is a backup solution. On OS X you have Time Machine, on Windows there’s also a backup system but on linux you have to roll your own.
# Research
I’m a fervent user of syncthing, a continuous file synchronization program. This runs on my Android phone, my workstation, my home computer and a raspberry pi. It helps syncing my photos and my passwords on every devices. But this is not a backup solution in my opinion. At first, I wanted to use this syncthing tool to backup the whole computer and by digging I found out that syncthing users usually backed up their syncthing databse with rsync or Borg. I never heard of Borg and went to read their documentation. It’s one of the most used software to do backups as it supports:
- multiple repositories (spaces where to backup to)
- deduplicating content (allows space efficient storage)
- cross-platform, uses mostly ssh
- can mount backups as devices
- encrypt data
# Setting the synology up
On the synology, I used the SynoCommunity borgbackup package. Once installed, go create a shared folder named “borgbackup”.
Then, the trick is to create a specific RSA key that will be used by SSH to authenticate the backup user. You can create a specific group/user for your backups, I was lazy to do so and I don’t think it has much benefits. I’ll therefore use my computer username to connect.
Once the key is created with ssh-keygen -f ~/.ssh/id_rsa_borgbackup -C "borg@pm.me"
, I copied the key to the synology in ~/.ssh/authorized_keys
. Note that the synology home directory needs 755
permissions, as always ssh permissions should be:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Now there’s a trick for borg which is to restrict the ssh key to the borg command using in the ~/.ssh/authorized_keys
file:
command="/usr/local/bin/borg serve --restrict-to-path /volume2/borgbackup",restrict ssh-rsa AAAAKEYHERE... borg@pm.me
Once setup you can try to connect with ssh using:
ssh -vvvT -i ~/.ssh/id_rsa_borgbackup user@host
Where host
is your synology ip/hostname, -vvvT
is to test the connection using debug verbosity.
# Setting borg updates on archlinux
You can use borg directly, I think that using borgmatic
helps with the configuration as everything is setup through a yaml file.
As usual, I’m not fond of running things via root
and I’ll backup only things in my home directory. Therefore I’ll use borgmatic
as my usual username.
Let’s first install borgmatic.
Then, my configuration file is located in ~/.config/borgmatic/config.yaml
, you can find the whole configuration here and the configuration reference on the borgmatic website.
Let’s go over the important bits:
location:
# Backup source
source_directories:
- /home/soyuka
# Repository, redactedhostname is the synology location
repositories:
- soyuka@redactedhostname:/volume2/borgbackup/syk-xp5
# The borg executable path on the synology
remote_path: /usr/local/bin/borg
# You'll see later that we can use `--dry-run` to see what actually gets
# backed-up, I chose to remove non-useful data, mostly dotfiles, caches and
# browser configurations
patterns:
- '- /home/*/Downloads'
- '- /home/*/.cache'
- '- /home/*/.cargo'
- '- /home/*/.circleci'
- '- /home/*/.cmake'
- '- /home/*/.*-gyp'
- '- /home/*/.fzf*'
- '- /home/*/.hyperdrive'
- '- /home/*/.ipfs*'
- '- /home/*/.kube'
- '- /home/*/.local'
- '- /home/*/.minikube'
- '- /home/*/.mozilla'
- '- /home/*/.npm'
- '- /home/*/.nvm'
- '- /home/*/.phpls'
- '- /home/*/.pipewire-media-session'
- '- /home/*/.pki'
- '- /home/*/.PlayOnLinux'
- '- /home/*/.pm2'
- '- /home/*/.rustup'
- '- /home/*/.standard-c14-cache'
- '- /home/*/.steam*'
- '- /home/*/.step'
- '- /home/*/.symfony'
- '- /home/*/.tor-browser'
- '- /home/*/.vmware'
- '- /home/*/.vscode-oss'
- '- /home/*/.wine'
- '- /home/*/.yarn'
- '- /home/*/.config/chromium'
- '- /home/*/.config/Slack'
- '- /home/*/.config/WebTorrent'
- '- /home/*/.config/Cypress'
- '- /home/*/.config/Beaker Browser'
- '- /home/*/.config/lutris'
- '- /home/*/.config/obs-studio'
- '- /home/*/.config/Dat Desktop'
- '- /home/*/.config/IPFS Desktop'
- '- /home/*/.config/VirtualBox'
- '- /home/*/.config/discord'
- '- /home/*/.config/Keybase/Cache'
- '- /home/*/.config/Code - OSS'
- '- /home/*/.antigen'
- '- /home/*/.tmux/plugins'
- '- /home/*/Documents/My Games'
- '- /home/*/.vim/plugged'
# Some patterns we exclude from the backup
exclude_patterns:
- '*node_modules*'
- '*vendor*'
- '*var/cache'
storage:
# Change how ssh works using our previously setup key
ssh_command: ssh -p specialport -i ~/.ssh/id_rsa_borgbackup
Now even if you have no clue what to ignore, just set up the ssh_command
with the repository and initialize the borg repository using:
borgmatic -v2 init --encryption repokey --storage-quota 512G
-v2
is for verbose (we may need to see SSH issues), we’ll use a repokey
encryption strategy (other exist see here for more informations). I used a storage quota of 512G which is twice the amount of my SSD.
At this point you’ll enter a passphrase that’ll be used to encrypt the backup. This key can be specified as the environment variable BORG_PASSPHRASE
for later commands. For example, let’s do a dry-run backup:
BORG_PASSPHRASE=redacted borgmatic --verbosity 1 --files --dry-run
Adapt the patterns
configuration to your needs and when you like it, remove the --dry-run
argument to backup.
# Automatic backups
On Archlinux, I’m using systemd, and I’ll setup borgmatic using systemd timers. On the borgmatic documentation they’ll propose two files:
I used both and put them under ~/.config/systemd/user
. Note that as I’m not running this as root, I have to remove some of the security flags, the borgmatic.service
looks more like this:
[Unit]
Description=borgmatic backup
Wants=network-online.target
After=network-online.target
ConditionACPower=true
[Service]
Type=oneshot
# Certain borgmatic features like Healthchecks integration need MemoryDenyWriteExecute to be off.
# But you can try setting it to "yes" for improved security if you don't use those features.
MemoryDenyWriteExecute=no
# Lower CPU and I/O priority.
Nice=19
CPUSchedulingPolicy=batch
IOSchedulingClass=best-effort
IOSchedulingPriority=7
IOWeight=100
Restart=no
# Prevent rate limiting of borgmatic log events. If you are using an older version of systemd that
# doesn't support this (pre-240 or so), you may have to remove this option.
LogRateLimitIntervalSec=0
# Delay start to prevent backups running during boot. Note that systemd-inhibit requires dbus and
# dbus-user-session to be installed.
ExecStartPre=sleep 1m
ExecStart=systemd-inhibit --who="borgmatic" --why="Prevent interrupting scheduled backup" /usr/bin/borgmatic --syslog-verbosity 1
Last but not least, I’ll add the BORG_PASSPHRASE
environment variable using systemctl --user edit bormatic.service
and by adding:
[Service]
Environment="BORG_PASSPHRASE=redacted"
This will be added to the service.
Use systemctl enable --user --now borgmatic.timer
to enable the timer which runs daily by thefault.
You can also execute the service right now by executing systemctl start --user borgmatic
.
# When did the backup last run?
Backups are good but only when you’re sure that they do run. To do so, I’ll just check the journalctl --user borgmatic.service
. When a backup has run, the last lines will be:
Sep 29 10:49:56 syk-xp5 borgmatic[3233766]: INFO Archive consistency check complete, no problems found.
Sep 29 10:49:56 syk-xp5 borgmatic[3233766]: INFO
Sep 29 10:49:56 syk-xp5 borgmatic[3233766]: INFO summary:
Sep 29 10:49:56 syk-xp5 borgmatic[3233766]: INFO /etc/borgmatic/config.yaml: Successfully ran configuration file
Sep 29 10:49:56 syk-xp5 systemd[1]: borgmatic.service: Succeeded.
Sep 29 10:49:56 syk-xp5 systemd[1]: Finished borgmatic backup.
Let’s just grab the date at which Finished bormatic backup.
and add this date to my bottom waybar:
In .config/waybar/scripts/backup
:
journalctl --user -u borgmatic.service --no-pager | grep -i 'Finished borgmatic backup.' | awk '{print $1 " " $2 " " $3}'
In the waybar config:
"custom/backup": {
"format": "{} ⏲️",
"interval": 3600,
"exec": "~/.config/waybar/scripts/backup"
}
Which outputs the last backup date :).
Hope this helps! You can find all my configuration files on github/soyuka/dotfiles.