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 borgbackup
Before 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 -h
Log 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/backup
On 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/keys
Export the key to this directory.
$ borg key export username@offsite_server:/home/user/backup /home/user/.config/borg/keys/backup_repo_key
To import the key if the file ever becomes damaged, change
export
toimport
.
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_server
Once 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_server
To 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_keys
Find the public key you added earlier. For example:
ssh-rsa AAAAB3Nza[...]q34Pk= user@example.com
Insert 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.com
Save 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 0
Press 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/file
To 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/file
Note: Include the full path when specifying what to exclude. For instance, use
/home/user/.cache
rather 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_name
To 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_name
3. 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.sh
Enter 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 0
Save and exit the file.
Make the script executable.
$ chmod +x borg-backup.sh
Test the script to ensure the backup completes successfully.
$ ./borg-backup.sh
Move the script to /etc/cron.daily
to be executed automatically each day.
$ mv borg-backup.sh /etc/cron.daily
Conclusion
You have now successfully set up secure, automated backups of your server's home directory to an offsite location with BorgBackup.