Introduction
This guide will show you how to create compressed, deduplicated, and encrypted backups of your server's home directory automatically using Borg, storing them on an offsite location.
Prerequisites
- A fully-updated Ubuntu Linux 20.04 server.
- (Referred to as the "primary server")
- A fully-updated Ubuntu Linux 20.04 server for offsite backups.
- (Referred to as the "offsite server")
- A non-root sudo user and SSH access to both servers.
You can adapt this guide for other Linux distributions with slight modifications. Borg is compatible with many operating systems.
1. Install Borg
On both the primary server and offsite server, install BorgBackup.
$ sudo apt install borgbackupBefore creating a backup, ensure you have sufficient disk space on both machines. Borg requires a few gigabytes of free space on the primary server in order to function.
$ df -hLog into the offsite server and create a directory for Borg to use as a repository for the backups. Borg stores backups in a repository as a collection of archives.
$ mkdir /home/user/backupOn the primary server initialize a repository at the directory just created, where username is the remote user with read/write access to the backup directory, and offsite_server is the IP address of the remote server. When prompted, enter a strong passphrase to encrypt the repository.
$ borg init --encryption=repokey username@offsite_server:/home/user/backup
[...]
IMPORTANT: you will need both KEY AND PASSPHRASE to access this repo!
Use "borg key export" to export the key, optionally in printable format.
Write down the passphrase. Store both at safe place(s).Borg saves a key in the repository in the config file that needs to be present in order to access the repository. Export this key in case the file ever becomes corrupted or lost. Both the key and passphrase are needed to access the repository.
Create a directory to store the key on the primary server.
$ mkdir -p /home/user/.config/borg/keysExport the key to this directory.
$ borg key export username@offsite_server:/home/user/backup /home/user/.config/borg/keys/backup_repo_keyTo import the key if the file ever becomes damaged, change
exporttoimport.
Set the BORG_REPO and BORG_PASSPHRASE environment variables to prevent reentering these details in this session.
$ export BORG_REPO='username@offsite_server:/home/user/backup'
$ export BORG_PASSPHRASE='your repository passphrase'2. Passwordless SSH Access
Before creating a backup, configure Borg to connect to the offsite server without a password.
On the primary server, create a key pair for Borg.
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/your_home/.ssh/id_rsa):Save the key as /home/user/.ssh/id_rsa_borg and do not enter a passphrase.
Add the new public key to the offsite server.
$ ssh-copy-id -i '/home/user/.ssh/id_rsa_borg' username@offsite_serverOnce complete, ensure you are able to log in to the offsite server without a passphrase using the new keyfile.
$ ssh -i '/home/user/.ssh/id_rsa_borg' username@offsite_serverTo increase security, limit the keyfile to be used for Borg only and dissallow remote logins.
On the offsite server, edit the authorized_keys file.
$ sudo nano /home/user/.ssh/authorized_keysFind the public key you added earlier. For example:
ssh-rsa AAAAB3Nza[...]q34Pk= user@example.comInsert the command directive below before ssh-rsa to limit the key to the borg command and a specific path only. Be sure to change /home/user/backup to the path of the backup repository created earlier. The line will look like this:
command="borg serve --restrict-to-path /home/user/backup",restrict,no-pty,no-agent-forwarding,no-port-forwarding ssh-rsa AAAAB3Nza[...]q34Pk= user@example.comSave and exit the file and return to the primary server.
Attempt to log in using the keyfile and verify access is denied.
$ ssh -i '/home/user/.ssh/id_rsa_borg' username@offsite_server
PTY allocation request failed on channel 0Press Enter to receive the second message.
$LOG ERROR borg.archiver Remote: Borg 1.1.11: Got unexpected RPC data format from client.
Connection to <IP> closed.Once verified, export the BORG_RSH environment variable to tell Borg to use this keyfile in this session.
$ export BORG_RSH='ssh -i /home/user/.ssh/id_rsa_borg'2. Test a Backup
On the primary server, test a backup of a file or folder in the home directory. Name it something appropriate and ensure you are not prompted for a passphrase.
$ borg create ::backup_name /home/user/path/to/fileTo exclude a file or directory from a backup use --exclude=path/to/file/. For example, if you want to exclude the .cache directory when creating a backup, use:
$ borg create --exclude='/home/user/.cache' ::backup_name /home/user/path/to/fileNote: Include the full path when specifying what to exclude. For instance, use
/home/user/.cacherather than.cache. Use multiple --exclude=path/to/file/ directives when excluding multiple files and directories. You may also use an exclude file if you have many exclusion patterns.
List the backups created in the repository using the list command, ensuring the backup archive just created is there.
$ borg list
backup_name Wed, 2020-09-22 12:59:37 [f2cd0350f6cde7d58bb429fe67fg7f11h35f5bd6cdaz1b6d4d5e7b304gjjf81f]Test a restore of the backup using borg extract. By default, Borg restores the full path of the backup to the current directory. For example in this guide, Borg restores the directories /home/user/path/to/file. To avoid writing any data, include --dry-run in the command.
$ borg extract --dry-run ::backup_nameTo extract a single file in an archive, use: $ borg extract ::backup_name /file/to/restore
When finished, you may delete the test backup archive.
$ borg delete ::backup_name3. Setup Automated Backups
To automate a backup of the home directory, create a backup script to be run daily via cron on the primary server.
$ nano borg-backup.shEnter the following, changing details where necessary. This script makes a backup of the /home directory, excluding extraneous files, using the prune command to keep a backup for each day of the week, one for each week and one for each month, automatically deleting extra backups to save space.
#!/bin/sh
# Backup home directory to a remote location using Borg.
# To restore: borg extract username@offsite_server:/path/to/backup_repo::backup_name
export BORG_RSH='ssh -i /home/user/.ssh/id_rsa_borg'
export BORG_REPO='username@offsite_server:/home/user/backup'
export BORG_PASSPHRASE='your repository passphrase'
# Backup /home excluding cache & downloads
borg create -v --stats ::$(hostname)-$(date +"%d-%b-%Y") /home \
--exclude '/home/*/.cache' \
--exclude '/home/*/.ccache' \
--exclude '/home/$USER/Downloads' \
# Prune extra backups
borg prune --prefix $(hostname)- --keep-daily=7 --keep-weekly=4 --keep-monthly=12
exit 0Save and exit the file.
Make the script executable.
$ chmod +x borg-backup.shTest the script to ensure the backup completes successfully.
$ ./borg-backup.shMove the script to /etc/cron.daily to be executed automatically each day.
$ mv borg-backup.sh /etc/cron.dailyConclusion
You have now successfully set up secure, automated backups of your server's home directory to an offsite location with BorgBackup.