Borgmatic Setup

Local Backup Configuration

Create directories:

$ sudo mkdir -p /etc/borgmatic
$ sudo mkdir -p /etc/borg/{keys,security,ssh} /var/lib//borg /var/cache/borg

Create SSH keys:

$ sudo ssh-keygen -t ed25519 -f /etc/borg/ssh/id_ed25519 -N ''

Create the repository encryption passphrase:

$ xkcdpass -n7

Generate borgmatic configuration files for the local backup destination:

$ sudo generate-borgmatic-config --destination /etc/borgmatic/local-nas.yaml

This generates a sample configuration file /etc/borgmatic/local-nas.yaml which then can be customized.

What to Backup

# 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:
        - /etc
        - /home
        - /root
        - /usr/local
        - /var

     # Stay in same file system (do not cross mount points). Defaults to false.
    one_file_system: true

    # Only store/extract numeric user and group identifiers. Defaults to false.
    # numeric_owner: true

    # Store atime into archive. Defaults to true.
    # atime: false

    # Store ctime into archive. Defaults to true.
    # ctime: false

    # Store birthtime (creation date) into archive. Defaults to true.
    # birthtime: false

    # Use Borg's --read-special flag to allow backup of block and other special
    # devices. Use with caution, as it will lead to problems if used when
    # backing up special devices such as /dev/zero. Defaults to false.
    # read_special: false

    # Record bsdflags (e.g. NODUMP, IMMUTABLE) in archive. Defaults to true.
    # bsd_flags: true

    # Mode in which to operate the files cache. See
    # https://borgbackup.readthedocs.io/en/stable/usage/create.html#description for
    # details. Defaults to "ctime,size,inode".
    # files_cache: ctime,size,inode

    # Alternate Borg local executable. Defaults to "borg".
    # local_path: borg1

    # Alternate Borg remote executable. Defaults to "borg".
    # remote_path: borg1

    # Any paths matching these patterns are included/excluded from backups. Globs are
    # expanded. (Tildes are not.) Note that Borg considers this option experimental.
    # See the output of "borg help patterns" for more details. Quote any value if it
    # contains leading punctuation, so it parses correctly.
    # patterns:
        # - R /
        # - '- /home/*/.cache'
        # - + /home/susan
        # - '- /home/*'

    # Read include/exclude patterns from one or more separate named files, one pattern
    # per line. Note that Borg considers this option experimental. See the output of
    # "borg help patterns" for more details.
    # patterns_from:
        # - /etc/borgmatic/patterns

What NOT to Backup

    # 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:
        # - '*.pyc'
        # - ~/*/.cache
        # - /etc/ssl
    exclude_patterns:
        - '**/.cache'
        - '**/cache'
        - '**/.aMule'
        - '**/.beagle'
        - '**/.cache'
        - '**/.thumbnails'
        - '**/.Trash'
        - '**/cache'
        - '**/downloads'
        - '**/Downloads'
        - '**/gtk-gnutella-downloads'
        - '**/Trash'
        - /dev
        - /mnt
        - /proc
        - /run
        - /snap
        - /sys
        - /var/lib/bitcoind
        - /var/lib/clamav
        - /var/lib/container
        - /var/lib/deluge/downloads
        - /var/lib/lxcfs
        - /var/lib/mysql
        - /var/lib/ooni
        - /var/lib/sks
        - /var/lib/sks*
        - /var/lib/transmission-daemon
        - /var/run
        - /var/tmp/*
        - /var/www/mirrors

    # Read exclude patterns from one or more separate named files, one pattern per
    # line. See the output of "borg help patterns" for more details.
    # exclude_from:
        # - /etc/borgmatic/excludes

    # 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

    # If true, the exclude_if_present filename is included in backups. Defaults to
    # false, meaning that the exclude_if_present filename is omitted from backups.
    # keep_exclude_tags: true

    # Exclude files with the NODUMP flag. Defaults to false.
    # exclude_nodump: true

    # 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

Where Backup Data is Stored

    # 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@local-nas.example.net:6883/volume1/BorgBackup/{hostname}

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:
    # The standard output of this command is used to unlock the encryption key. Only
    # use on repositories that were initialized with passcommand/repokey encryption.
    # Note that if both encryption_passcommand and encryption_passphrase are set,
    # then encryption_passphrase takes precedence. Defaults to not set.
    # encryption_passcommand: secret-tool lookup borg-repository repo-name

    # 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: "rasping voucher murkiness cosigner tricking armful suitor"

    # Number of seconds between each checkpoint during a long-running backup. See
    # https://borgbackup.readthedocs.io/en/stable/faq.html#if-a-backup-stops-mid-way-does-the-already-backed-up-data-stay-there
    # for details. Defaults to checkpoints every 1800 seconds (30 minutes).
    # checkpoint_interval: 1800

    # Specify the parameters passed to then chunker (CHUNK_MIN_EXP, CHUNK_MAX_EXP,
    # HASH_MASK_BITS, HASH_WINDOW_SIZE). See https://borgbackup.readthedocs.io/en/stable/internals.html
    # for details. Defaults to "19,23,21,4095".
    # chunker_params: 19,23,21,4095

    # Type of compression to use when creating archives. See
    # https://borgbackup.readthedocs.org/en/stable/usage.html#borg-create for details.
    # Defaults to "lz4".
    # compression: lz4

    # Remote network upload rate limit in kiBytes/second. Defaults to unlimited.
    # remote_rate_limit: 100

    # Command to use instead of "ssh". This can be used to specify ssh options.
    # Defaults to not set.
    # ssh_command: ssh -i /path/to/private/key
    ssh_command: ssh -i /etc/borg/ssh/id_ed25519 -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: /path/to/base
    borg_base_directory: /var/lib//borg

    # Path for Borg configuration files. Defaults to $borg_base_directory/.config/borg
    # borg_config_directory: /path/to/base/config
    borg_config_directory: /etc/borg

    # Path for Borg cache files. Defaults to $borg_base_directory/.cache/borg
    # borg_cache_directory: /path/to/base/cache
    borg_cache_directory: /var/cache/borg

    # Path for Borg security and encryption nonce files. Defaults to $borg_base_directory/.config/borg/security
    # borg_security_directory: /path/to/base/config/security

    # Path for Borg encryption key files. Defaults to $borg_base_directory/.config/borg/keys
    # borg_keys_directory: /path/to/base/config/keys

    # Umask to be used for borg create. Defaults to 0077.
    # umask: 0077

    # Maximum seconds to wait for acquiring a repository/cache lock. Defaults to 1.
    # lock_wait: 5

    # 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}-documents-{now}'
    archive_name_format: '{hostname}-{now}'

    # Bypass Borg error about a repository that has been moved. Defaults to false.
    # relocated_repo_access_is_ok: true

    # Bypass Borg error about a previously unknown unencrypted repository. Defaults to
    # false.
    # unknown_unencrypted_repo_access_is_ok: true

    # Additional options to pass directly to particular Borg commands, handy for Borg
    # options that borgmatic does not yet support natively. Note that borgmatic does
    # not perform any validation on these options. Running borgmatic with
    # "--verbosity 2" shows the exact Borg command-line invocation.
    # extra_borg_options:
        # Extra command-line options to pass to "borg init".
        # init: --make-parent-dirs

        # Extra command-line options to pass to "borg prune".
        # prune: --save-space

        # Extra command-line options to pass to "borg create".
        # create: --no-files-cache

        # Extra command-line options to pass to "borg check".
        # check: --save-space

For How Long Backups are Stored

# 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: 3H
    keep_within: 6H

    # Number of secondly archives to keep.
    # keep_secondly: 60

    # Number of minutely archives to keep.
    # keep_minutely: 60

    # Number of hourly archives to keep.
    # keep_hourly: 24
    keep_hourly: 8

    # Number of daily archives to keep.
    keep_daily: 7

    # Number of weekly archives to keep.
    # keep_weekly: 4
    keep_weekly: 4

    # Number of monthly archives to keep.
    # keep_monthly: 6
    keep_monthly: 6

    # Number of yearly archives to keep.
    # keep_yearly: 1
    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: sourcehostname
    prefix: '{hostname}-'

How Backup Data is Verified

# Consistency checks to run after backups. See
# https://borgbackup.readthedocs.org/en/stable/usage.html#borg-check and
# https://borgbackup.readthedocs.org/en/stable/usage.html#borg-extract for details.
consistency:
    # List of one or more consistency checks to run: "repository", "archives", "data",
    # and/or "extract". Defaults to "repository" and "archives". Set to "disabled" to
    # disable all consistency checks. "repository" checks the consistency of the
    # repository, "archives" checks all of the archives, "data" verifies the integrity
    # of the data within the archives, and "extract" does an extraction dry-run of the
    # most recent archive. Note that "data" implies "archives".
    checks:
        # - repository
        # - archives

        # Check repository consistency once a week
        - name: repository
          frequency: 1 week

        # Check the last 14 archies every 2 weeks
        - name: archives
          frequency: 2 weeks

        # Do an extraction dry-run of the most recent archive every month.
        - name: extract
          frequency: 1 month

        # Verify the integrity of the data within the archives every 3 months.
        - name: data
          frequency: 3 months

    # Paths to a subset of the repositories in the location section on which to run
    # consistency checks. Handy in case some of your repositories are very large, and
    # so running consistency checks on them would take too long. Defaults to running
    # consistency checks on all repositories configured in the location section.
    # check_repositories:
        # - user@backupserver:sourcehostname.borg

    # Only check the last 14 archives when doing "archives" consistency checks.
    check_last: 14

    # When performing the "archives" check, 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: sourcehostname
    prefix: '{hostname}-'

What To Do Before and After

# 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 before creating a
    # backup, run once per configuration file.
    before_backup:
        # - echo "Starting a backup."
        - sudo -u mysql rm -rf /var/backups/mariadb/full/*
        - sudo -u mysql mariabackup --backup --target-dir=/var/backups/mariadb/full

    # List of one or more shell commands or scripts to execute before pruning, run
    # once per configuration file.
    # before_prune:
        # - echo "Starting pruning."

    # List of one or more shell commands or scripts to execute before consistency
    # checks, run once per configuration file.
    # before_check:
        # - echo "Starting checks."

    # List of one or more shell commands or scripts to execute after creating a
    # backup, run once per configuration file.
    after_backup:
        # - echo "Finished a backup."
        - sudo -u mysql rm -rf /var/backups/mariadb/full/*

    # List of one or more shell commands or scripts to execute after pruning, run once
    # per configuration file.
    # after_prune:
        # - echo "Finished pruning."

    # List of one or more shell commands or scripts to execute after consistency
    # checks, run once per configuration file.
    # after_check:
        # - echo "Finished checks."

What To Do on Errors

    # 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.
    on_error:
        - /usr/local/bin/borgmatic-notify "{configuration_filename}" "{repository}" "{error}" "{output}"

Remote Backup Configuration

Copy the configuration file local-nas.yaml to remonte-nas.yaml:

$ sudo cp /etc/borgmatic/local-nas.yaml /etc/borgmatic/remote-nas.yaml

Change the repository to the remote location in the copied file:

# 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@remote-nas.example.net:6883/volume1/BorgBackup/{hostname}

Repository Setup

The backup destination stores its data in Borg backup repositories.

These Borg backup repositories have to be properly initialized, before data can be store in them.

Repositories should be encrypted, especially if a remote backup location is not fully trusted. Encryption has be enabled at repository init time. It cannot be changed later.

When using one of the repokey and keyfile encryption modes, the passphrase AND the keyfile are both required to access the repository.

Local Network Location

Initialize the the local network repository:

$ sudo borgmatic init --config /etc/borgmatic/local-nas.yaml \
    --encryption keyfile-blake2

The keyfile will be created and stored in the directory set by the configuration setting borg_keys_directory. If you didn’t change the example provided above, you should find it in the /etc/borg/keys/ directory.

Remote Network Location

Initialize the the remote network repository:

$ sudo borgmatic init --config /etc/borgmatic/remote-nas.yaml \
    --encryption keyfile-blake2

Safeguard Keys and Passwords

Warning

To be able to access the backups you need:

  1. The private SSH key to access the storage server holding the repository.

  2. The Borg keyfile holding the key, which is used to encrypt the backup data in the repository.

  3. The Borg repokey password used to unlock the keyfile.

If one of these things are lost, you will no longer be able to access the backup for restoration.

Store them in a safe place and make sure you can get to them, in case you have to restore any data.