Borg Backup Setup Guide

As part of my search for a reliable backup solution for my Linux-based servers, Borg Backup consistently emerged as a top contender. Consequently, I decided to set it up and evaluate its performance firsthand. My experience has been highly favorable, as the software exhibits exceptional speed and efficient data deduplication capabilities.

To provide a comprehensive guide for installing and configuring Borg Backup, it is essential to understand that this solution operates through a client-server architecture. The client initiates the backup process by pushing archives to the server, where they are ultimately stored. Furthermore, Borg Backup can be customized to restrict the client’s access to only its own files and not those from other clients. This guide is written for Debian based distros.

Borg Backup Layout


Install Borg on the backup server.

  1. The first step is to install borg on the backup server this will be where the backup will be saved. Installing from Pypi seems to be the best way to get a updated version. The ones in the repos do not seemed to be kept up to date as much as I would like to see.

    apt update && apt install libssl-dev libacl1-dev python3 pkg-config python3-pip -y
    pip install -U pip setuptools wheel && pip install pkgconfig
    pip install borgbackup
    
  2. After we get borg installed the next step is to setup a new user for Server A. This step is not totally necessary but it does provide a another step of seperation from the different backup locations.

    sudo adduser --disabled-password server_A
    
  3. Move to the newly created user

    sudo su - server_A
    
  4. Then I create a backup folder in the users home directory

    mkdir backup
    
  5. Setup the SSH directory.

    mkdir .ssh && chmod 700 .ssh
    touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys
    
  6. Open the SSH Authorized Keys

    nano .ssh/authorized_keys
    

SSH Key Explanation

SSH keys are a form of authentication used in Secure Shell (SSH) protocol to securely access remote servers. With SSH keys, instead of using a password each time you log in, you generate a pair of cryptographic keys: a private key on your local machine and a public key on the remote server.

The private key is kept secret on your local machine, while the public key is shared with the remote server and added to its authorized_keys file. When you attempt to log in using SSH, the client sends the corresponding public key to the server, which verifies it against the public keys in its authorized_keys file. If the verification passes, the server generates a temporary private key and shares it with the client, allowing secure access to the remote server for that session.

Here is a good guide to review if you want to study ssh keys more.

On Server A

  1. Create a ssh key for to connect to the backup server.

    ssh-keygen -t ed25519 -f .ssh/id_ed25519_backup
    

On Backup Server

  1. Add this to the file. Take care to add the whole thing on one line.

    command="borg serve --restrict-to-repository /home/server_A/backup",restrict Ed25519 Key_Data_Goes_Here server_A
    

    Lets break that down a little as it is not your average line in a authorized_keys file. The ’ command=“borg serve –restrict-to-repository /home/server_A/backup” ’ starts the Borg Server only when the ssh key that follow signs in. You may want to look into the –append-only only option details are on the borg doc site for ransomeware prevention.

    Take the SSH Public key that was created in the previous step and place it after the word ‘restrict’ on the same line in the Authorized Keys file on the backup Server.


On Server A

  1. Install borg just like on the server.

    apt update && apt install libssl-dev libacl1-dev python3 pkg-config python3-pip -y
    pip install -U pip setuptools wheel && pip install pkgconfig
    pip install borgbackup
    
  2. The next step is to initialize a backup repository. Change the backup server ip address. One thing that works great is to have all these server linked over Tailscale or some other overlay network.

    borg -v init --encryption=repokey-blake2 server_A@backup_Servers_IP:/home/server_A/backup/
    
  3. Add a strong password to the backup. It is preferred to use only numbers and letters as symbols need to be properly escaped to transfer over ssh reliably and that is far beyond the scope of this guide.

  4. Next enter the following command and and then save this in a safe place like a password manager. You may need both this key and the password to restore the backup.

    borg key export --paper ssh://server_A@backup_Servers_IP/home/server_A/backup
    
  5. Now that we have the repository setup the next things is to make a script that we will run on every day to make a backup.

    nano /root/borgbackrun.sh
    
  6. Here are the contents of the backuprun.sh file. These may need to be changed to meet you needs.

    #!/bin/sh
    
    # Setting this, so the repo does not need to be given on the commandline:
    export BORG_REPO=server_A@@backup_Servers_IP:/home/server_A/backup
    
    # See the section "Passphrase notes" for more infos.
    export BORG_PASSPHRASE='XYZl0ngandsecurepa_55_phrasea&&123'
    
    
    # some helpers and error handling:
    info() { printf "\n%s %s\n\n" "$( date )" "$*" >&2; }
    trap 'echo $( date ) Backup interrupted >&2; exit 2' INT TERM
    
    info "Starting backup"
    
    # Backup the most important directories into an archive named after
    # the machine this script is currently running on:
    
    /usr/local/bin/borg create          \
        --verbose                       \
        --filter AME                    \
        --list                          \
        --stats                         \
        --show-rc                       \
        --compression zstd,11           \
        --exclude-caches                \
        --exclude 'home/*/.cache/*'     \
        --exclude 'var/tmp/*'           \
        --exclude 'var/cache/*'         \
        --exclude 'var/lib/*'           \
        --exclude 'root/.cache/*'       \
                                        \
        ::'{hostname}-{now}'            \
        /etc                            \
        /home                           \
        /root                           \
        /var
    
    backup_exit=$?
    
    info "Pruning repository"
    
    # Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly
    # archives of THIS machine. The '{hostname}-*' matching is very important to
    # limit prune's operation to this machine's archives and not apply to
    # other machines' archives also:
    
    /usr/local/bin/borg prune           \
        --list                          \
        --glob-archives '{hostname}-*'  \
        --show-rc                       \
        --keep-daily    7               \
        --keep-weekly   4               \
        --keep-monthly  6
    
    prune_exit=$?
    
    # actually free repo disk space by compacting segments
    
    info "Compacting repository"
    
    /usr/local/bin/borg compact
    
    compact_exit=$?
    
    # use highest exit code as global exit code
    global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit ))
    global_exit=$(( compact_exit > global_exit ? compact_exit : global_exit ))
    
    if [ ${global_exit} -eq 0 ]; then
        info "Backup, Prune, and Compact finished successfully"
    elif [ ${global_exit} -eq 1 ]; then
        info "Backup, Prune, and/or Compact finished with warnings"
    else
        info "Backup, Prune, and/or Compact finished with errors"
    fi
    
    exit ${global_exit}
    

    Change permissions so that only the owner can view, read and exicute.

    chmod 700 /root/borgbackrun.sh
    

    The final step is to create a cron job that runs daily to run the backup.

    crontab -e
    
  7. Add the following line the bottom of the cron file then save. This will run at 11PM. All logs that borg generates will be in /var/log/daily-backup.log.

    0 23 * * * /root/borgbackrun.sh >> /var/log/daily-backup.log 2>&1
    
  8. If you run this script to can verfy it will finish correctly.

    bash /root/borgbackrun.sh
    

This is the last of the guide. In a future guide I will show how I use Uptime Kuma to monitor this backup and make sure it does not silently fail.

Repeat steps 2 - 16 for each additional client you wish to add.

comments powered by Disqus