System Configuration Backup
The system backup contains system-wide configuration files, keys, certificates (i.e. SSH keys) and the datra about 3rd-party software package repositories and installed packages. This includes:
The
/etc
directory;The
/opt
directory;The
/usr/local
directory;The
/var/lib
directory;A list of currently installed Ubuntu software packages (apt);
A list of currently installed Python packages (pip);
Borg Preparation
Add configuration and keys directory:
$ sudo mkdir -p /etc/borg/{keys,ssh}
Add cache and security directories:
$ sudo mkdir -p /var/lib/borg/{cache,security}
Create SSH private and public key:
$ sudo ssh-keygen -t ed25519 -C "BorgBackup@$(hostname)" -f /etc/borg/ssh/id_ed25519
$ sudo chmod 0600 /etc/borg/ssh/id_ed25519
$ sudo cat /etc/borg/ssh/id_ed25519.pub
Install the public key on the backup server:
$ sudo ssh-copy-id -i /etc/borg/ssh/id_ed25519.pub borg-backup@nas.example.net
The backup server needs then to setup that public key for use with this specific Borg client by defining a ssh forced command, that points Borg to this clients repository.
Mail Notification Script
The /etc/borgmatic/notify.sh
shell script will send us a mail message,
whenever something goes wrong during backups, pruning or a repository check.
#!/usr/bin/bash
#
# Notify user of borgmatic backup error.
#
# /etc/notify.sh "{configuration_filename}" "{repository}" "{error}" "{output}"
mail -s "Borgmatic Error on ${HOST}" "${USER}" <<EOF
Borgmatic backup on ${HOST} failed.
Configuration file: $1
Repository: $2
Error Message: $3
Command output, if any: $4
For more information, query the systemd journal on ${HOST}.
EOF
Borgmatic Configuration
Generate a new borgmatic configuration file:
$ sudo generate-borgmatic-config
This generates a sample configuration file /etc/borgmatic/config.yaml
.
What to Backup and Where
# Where to look for files to backup, and where to store those backups. See
# https://borgbackup.readthedocs.io/en/stable/quickstart.html and
# https://borgbackup.readthedocs.io/en/stable/usage.html#borg-create for details.
location:
# List of source directories to backup (required). Globs and tildes are expanded.
source_directories:
- /boot
- /etc
- /opt
- /root
- /usr/local
- /var
# Paths to local or remote repositories (required). Tildes are expanded. Multiple
# repositories are backed up to in sequence. See ssh_command for SSH options like
# identity file or port.
repositories:
- ssh://borg-backup@nas.example.net/volume1/BorgBackup/{hostname}
# Any paths matching these patterns are excluded from backups. Globs and tildes
# are expanded. See the output of "borg help patterns" for more details.
# Any paths matching these patterns are excluded from backups. Globs and tildes
# are expanded. See the output of "borg help patterns" for more details.
exclude_patterns:
- '**/.cache'
- '**/cache'
- /dev
- /lost+found
- /mnt
- /proc
- /run
- /snap
- /sys
- /var/lib/container
- /var/lib/lxcfs
- /var/lib/ooni
- /var/run
- /var/tmp/*
# Exclude directories that contain a CACHEDIR.TAG file. See
# http://www.brynosaurus.com/cachedir/spec.html for details. Defaults to false.
exclude_caches: true
# Exclude directories that contain a file with the given filenames. Defaults to not
# set.
exclude_if_present:
- .nobackup
# Path for additional source files used for temporary internal state like
# borgmatic database dumps. Note that changing this path prevents "borgmatic
# restore" from finding any database dumps created before the change. Defaults
# to ~/.borgmatic
borgmatic_source_directory: /tmp/borgmatic
How to Store the Backups
# Repository storage options. See
# https://borgbackup.readthedocs.io/en/stable/usage.html#borg-create and
# https://borgbackup.readthedocs.io/en/stable/usage/general.html#environment-variables for
# details.
storage:
# Passphrase to unlock the encryption key with. Only use on repositories that were
# initialized with passphrase/repokey encryption. Quote the value if it contains
# punctuation, so it parses correctly. And backslash any quote or backslash
# literals as well. Defaults to not set.
encryption_passphrase: "********"
# Command to use instead of "ssh". This can be used to specify ssh options.
# Defaults to not set.
ssh_command: ssh -i /etc/borg/ssh/id_ed25519 -o BatchMode=yes -o VerifyHostKeyDNS=yes
# Base path used for various Borg directories. Defaults to $HOME, ~$USER, or ~.
# See https://borgbackup.readthedocs.io/en/stable/usage/general.html#environment-variables for details.
borg_base_directory: /var/lib//borg
# Path for Borg configuration files. Defaults to $borg_base_directory/.config/borg
borg_config_directory: /etc/borg
# Path for Borg cache files. Defaults to $borg_base_directory/.cache/borg
borg_cache_directory: /var/lib/borg/cache
# Path for Borg encryption key files. Defaults to $borg_base_directory/.config/borg/keys
borg_keys_directory: /etc/borg/keys
# Name of the archive. Borg placeholders can be used. See the output of
# "borg help placeholders" for details. Defaults to
# "{hostname}-{now:%Y-%m-%dT%H:%M:%S.%f}". If you specify this option, you must
# also specify a prefix in the retention section to avoid accidental pruning of
# archives with a different archive name format. And you should also specify a
# prefix in the consistency section as well.
archive_name_format: '{hostname}-{now}'
How Long to Keep Backups
# Retention policy for how many backups to keep in each category. See
# https://borgbackup.readthedocs.org/en/stable/usage.html#borg-prune for details.
# At least one of the "keep" options is required for pruning to work. See
# https://torsion.org/borgmatic/docs/how-to/deal-with-very-large-backups/
# if you'd like to skip pruning entirely.
retention:
# Keep all archives within this time interval.
keep_within: 6H
# Number of hourly archives to keep.
keep_hourly: 8
# Number of daily archives to keep.
keep_daily: 7
# Number of weekly archives to keep.
keep_weekly: 4
# Number of monthly archives to keep.
keep_monthly: 6
# Number of yearly archives to keep.
keep_yearly: 1
# When pruning, only consider archive names starting with this prefix.
# Borg placeholders can be used. See the output of "borg help placeholders" for
# details. Defaults to "{hostname}-". Use an empty value to disable the default.
prefix: '{hostname}-'
What To Do on Errors
# Shell commands, scripts, or integrations to execute at various points during a borgmatic
# run. IMPORTANT: All provided commands and scripts are executed with user permissions of
# borgmatic. Do not forget to set secure permissions on this configuration file (chmod
# 0600) as well as on any script called from a hook (chmod 0700) to prevent potential
# shell injection or privilege escalation.
hooks:
# List of one or more shell commands or scripts to execute when an exception
# occurs during a "prune", "create", or "check" action or an associated
# before/after hook.
# Supported variables:
# configuration_filename
# repository
# error
# output
on_error:
- /etc/borgmatic/notify.sh "{configuration_filename}" "{repository}" "{error}" "{output}"
# List of one or more shell commands or scripts to execute before running all
What To Do Before and After
# List of one or more shell commands or scripts to execute before running all
# actions (if one of them is "create"). These are collected from all configuration
# files and then run once before all of them (prior to all actions).
# before_everything:
# - echo "Starting actions."
# List of one or more shell commands or scripts to execute after running all
# actions (if one of them is "create"). These are collected from all configuration
# files and then run once before all of them (prior to all actions).
# after_everything:
# - echo "Completed actions."
Secure and Validate Configuration
To prevent potential shell injection or privilege escalation, do not forget to set secure permissions on borgmatic configuration files (chmod 0600) and scripts (chmod 0700) invoked by hooks.
$ sudo chmod 0600 /etc/borgmatic/config.yml
$ sudo chmod 0700 /etc/borgmatic/notify.sh
$ sudo validate-borgmatic-config
Initialize Repository
$ sudo borgmatic init --encryption repokey
Interactive Backup Test
$ sudo borgmatic --verbosity 1 --files
Systemd Service Files
Service
Start a system backup once, but only if connected to a network and not running on battery.
Systemd service file: /etc/systemd/system/borgmatic.service
:
[Unit]
Description=borgmatic backup
Wants=network-online.target
After=network-online.target
ConditionACPower=true
[Service]
Type=oneshot
# 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.
ExecStartPre=sleep 1m
# Don't shutdown, sleep or idle during backups.
ExecStart=systemd-inhibit --who="borgmatic" --why="Prevent interrupting scheduled backup" /usr/local/bin/borgmatic --syslog-verbosity 1
# Note that systemd-inhibit requires dbus and dbus-user-session to be installed.
Schedule
Schedule the system backups once every day at a random time between midnight and 6 AM. or if a scheduled backup time was missed, due to the system powered off or asleep. Don’t wake up the system just for doing a backup.
Systemd timer file /etc/systemd/system/borgmatic.timer
:
[Unit]
Description=Run borgmatic system backup
[Timer]
# Schedule the start of the sevice to every day at midnight.
OnCalendar=daily
# Delay the start of the service by a radmon time of up to 6 hours
RandomizedDelaySec=6h
# Only wake up the system for this service after 8 hours or more.
#AccuracySec=8h
# Catch up on missed runs of the service when the system was powered down.
Persistent=true
[Install]
WantedBy=timers.target
Activate
$ sudo systemctl enable --now borgmatic.timer