Introduction to Borg Backup

Borg is a very useful application we can use to create deduplicating backups on Linux. Free and open source software, it is, for the most part, written in Python and supports data compression and encryption. Thanks to the data de-duplication feature, only data which actually changes is archived, and this let us optimize both disk space and execution time. Borg is really easy to install, since it is packaged and included in the repositories of the most used Linux distributions.

In this tutorial we are going to see how to install Borg on some of the most used Linux distributions, and some examples of its usage.

Introduction to Borg Backup
Introduction to Borg Backup

In this tutorial you will learn:

  • How to install Borg
  • The basic Borg concepts
  • How to initialize a Borg repository
  • How to create an archive
  • How to list the archives in a repository
  • How to list the content of archives
  • How to mount a borg archive
  • How to restore a borg archive
  • How to delete a borg archive
Category Requirements, Conventions or Software Version Used
System Distribution-independent
Software Borg
Other Root permissions
Conventions # – requires given linux-commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux-commands to be executed as a regular non-privileged user

Installation

On Fedora Borg is packaged as “borgbackup”. To install it, we can use the dnf package manager:

$ sudo dnf install borgbackup

To perform the installation on Debian and its derivatives, instead, we can use the apt wrapper:

$ sudo apt install borgbackup

On Archlinux Borg is available in the “Community” repository. The package is simply called “borg”. We can install it using pacman:

$ sudo pacman -S borg

If your favorite distribution is not among the ones we mentioned above, take a look at the official Borg installation guide, which includes many other systems. Borg is also available as a single binary packaged with all its dependencies: it can be downloaded from the project github releases page.

How Borg works

Borg is what is called a “deduplicating backup program”. Similarly to what happens with incremental backups, only data which actually changes on the filesystem after a full backup is performed, is archived in the subsequent backups, but similarities are just conceptual. Borg works by splitting each file into chunks which are identified by their hashsum. Only chunks not recognized by the applications are added to the “repository”. This deduplicating technique is really efficient since, among the other things, makes us able to move a file or a directory, without that to be considered a change, and therefore requiring additional space. The same happens for files timestamps. What really matters are just the file chunks, which are stored only once. On Linux Borg supports preserving all standard and extended filesystem attributes such as ACLs and xattrs.



The two main entities Borg revolves around are “Archive” and aforementioned “Repository”. An archive is essentially a snapshot of a filesystem in a certain point in time. Due to how Borg works, while data is stored only once, each archive does contains the complete filesystem, and, unlike what happens with incremental backups, an archive does not depend on the ones created before it. A repository, on the other hand, is a directory we use to store archives, and must be initialized via a specific command we will see in a moment. Let’s see how we would proceed supposing we want to create incremental backups of our whole home directory, and store the archives under /mnt/borg.

Initializing a repository

The very first thing we need to do to use Borg, is to initialize the directory we want to store the archives in, as a Borg repository. We perform this task by using the init command:

$ borg init --encryption=repokey /mnt/borg

When we initialize a repository we must decide the type of encryption we want to use for our backups. The choice we make is really important, and can’t be changed later. The main encryption modes we can choose are the following:

  • repokey/keyfile
  • authenticated
  • none

The repokey and keyfile options use both the AES-CTR-256 cipher for encryption. The differences between the two is where the encryption key is stored. If we choose “repokey” the encryption key will be stored in the repository configuration file, therefore the security of the backups will be based only on the passphrase we will be prompted to provide at initialization time. If we choose the “keyfile” mode, instead, the encryption key will be stored inside our home directory, in ~/.config/borg/keys, so to decrypt or create an archive we will both need to have something (the key) and to know something (the passphrase). In both cases it’s always a good idea to create a backup of the encryption key.

If we choose the authenticated mode, no encryption will be used, but the content of the repository will be “authenticated” through the same HMAC-SHA256 hash used with the repokey a keyfile modes.

Finally, if we choose none neither authentication or encryption will be used: the use of this mode is discouraged for obvious reasons. Other modes exists, but are variants of the ones mentioned above. Take a look at the application manual if you want to know more about them.

Since in the example above we used “repokey” as encryption mode, when we initialize the repository, we are prompted to provide and confirm a passphrase for the keyfile:

Enter new passphrase: 
Enter same passphrase again:



If we, sooner or later decide that we want to change the passphrase, we can simply do it with the “key change-passphrase” command, providing the path of the repository as argument:

$ borg key change-passphrase /mnt/borg

Once we issue the command, we will be prompted for the current repository key password, and two times for the new one:

Enter passphrase for key /mnt/borg: 
Enter new passphrase: 
Enter same passphrase again:

Once the repository is initialized a bunch of files and directories will be created inside of it:

$ ls /mnt/borg
total 68
-rw-------. 1 egdoc egdoc 700 Apr 23 19:20 config
drwx------. 3 egdoc egdoc 4096 Apr 23 19:19 data
-rw-------. 1 egdoc egdoc 52 Apr 23 19:19 hints.1
-rw-------. 1 egdoc egdoc 41258 Apr 23 19:19 index.1
-rw-------. 1 egdoc egdoc 190 Apr 23 19:19 integrity.1
-rw-------. 1 egdoc egdoc 16 Apr 23 19:19 nonce
-rw-------. 1 egdoc egdoc 73 Apr 23 19:19 README

Again, since we used “repokey” mode the encryption key is stored in the repository “config” file:

[repository]
version = 1
segments_per_dir = 1000
max_segment_size = 524288000
append_only = 0
storage_quota = 0
additional_free_space = 0
id = a1dccd1d4613d4f582cb4617f3393656e0a0f05db1fb9c90e0aa5b3e675bf17f
key = hqlhbGdvcml0aG2mc2hhMjU2pGRhdGHaAN6CZjFu1nnPs3QMuYTQ4O1m1jC+pVQjpGR3pR
b+pq20AxAPXboKEQsUmBajJXm0m/7Box9WSzw6IrizBPDSxERhys1d3piFUUsVRJ7GzjNO
lfcgVRpy2BpI9w/QXPgOl6FjCmp2HU5R5YdQjtEH4aUND702hWFBfI486oZJ94v/LrUVRm
8MFmC8KSXXNHBbuRXOvBnH+cME0Owz/kRLQEGHFaxD18F+dZOVV+1wEn+UDL6XsIA7FKk4
jwHxWVzoekGeHsVcDKXlXg1FWN9ck6QRWipgojUMvFvt9/wTinGkaGFzaNoAILRxN39c/m
yH7mzsXEqdxx3vvi6rh3X9rqlab4BD2tDrqml0ZXJhdGlvbnPOAAGGoKRzYWx02gAg/Tam
mSE01YTDzTiPyYDPszuBt01L/Gfrt6dgN7v/veqndmVyc2lvbgE=

Creating archives

Borg archives are created using the “create” command. To create the first relative home directory backup, we would first move into our home dir, then run:

$ cd && borg create --list /mnt/borg::archive-{hostname}-{now} .

Let’s take a look at the command. We invoked borg with the “create” command, and used the --list option: this is not mandatory, but it will cause the processed files and directories to be printed on the standard output. We than provided the path of the repository in which the archive should be saved and the name of the archive, separated from the latter by a double colon ::. Conveniently, a series of variables can be used to compose the archive name:

  • {now} – This is replaced by the current, localized date and time
  • {utcnow} – Same as above, but the UTC time is used, instead
  • {fqdn} – This is replaced by the machine Fully Qualified Domain Name
  • {hostname} – This is replaced by the machine hostname
  • {user} – This is replaced by the name of the user which launched the command

Finally, we provided the path of the directory we want to backup. Once we run the command, we will be asked to provide the password we choose when we initialized the repository:

Enter passphrase for key /mnt/borg:

Once we do, the archive will be created. Since we used the --list option the list of the processed files and directories will be printed. Each file will be prefized by symbol. In the table below you can see all the symbols and their meaning:

SYMBOL MEANING
A Regular file (added)
M Regular file (modified)
U Regular file (unchanged)
d Directory
b Block device
c Char device
s Symlink
i Data read from standard input
Dry run
x File not included in the backup due to exclusion

By default, archives are compressed with the lz4 algorithm, but this can be changed via --compression option. We can decide to use other algorithms like zlib or lzma and also specify the compression level with the following notation:

<algorithm>,<compression-level>

Where <compression-level> must be expressed as an integer from 0 to 9. Just as an example, to use the lzma algorithm with the maximum available compression, we would run:

$ borg create --list --compression lzma,9 /mnt/borg::archive-{hostname}-{now} .

We can also decide to use no compression at all by passing ‘none’ as argument to the --compress option.

Obtaining the list of the archives in a repository

To obtain the list of the archives stored in a Borg repository, we can use the “list” command and pass the path of the repository as argument. In our case, we would run:

$ borg list /mnt/borg

We will again be prompted to provide the password associated to the repository. Once we do, the list of the archives contained in the repository will be displayed:

archive-fingolfin-2022-04-23T19:33:58 Sat, 2022-04-23 19:34:00 [4454c59a6d88b7e905612aa642f64c5341a63acd717c26061c3156f65bced397]



The “list” command can also be used to obtain the list of the files contained in the archives. For instance, to list the content of the archive we created in this tutorial, we would run:

$ borg list /mnt/borg::archive-fingolfin-2022-04-23T19:33:58

Mounting an archive

If we want to explore the content of an archive (say for example we want to check the content of some files), we can mount it on a directory on the filesystem. The command which allows us to perform said task is “mount”. To mount the “:archive-fingolfin-2022-04-23T19:33:58” backup in our repository on the /tmp/borg directory for example, we would run:

$ sudo borg mount /mnt/borg::archive-fingolfin-2022-04-23T19:33:58 /tmp/borg

The archive will be mounted just as a filesystem in the specified directory, and its content will be easily available. Very convenient. Beside a specific archive, we can mount the repository as a whole:

$ sudo borg mount /mnt/borg /tmp/borg

In such case, the mountpoint will contain one directory for each of the archives contained in the repository.

Restoring an archive

If something bad happens and we need to restore the backup we created with Borg, we have to use the “extract” command. When the command is run, the archive is extracted in the current working directory, therefore to restore the files in our home directory we should move inside it first:

$ cd



Once we are in the directory in which we want to extract the archive, we can issue the “extract” command. As usual, we pass the path of the repository together with the name of the archive which should be extracted as argument and we are prompted to provide the repository password. In the example below we included the --list option to the command to visualize the extracted files:

$ borg extract --list  /mnt/borg::archive-fingolfin-2022-04-23T19:33:58

If we want to restore just some specific files from the archive, we can append their paths inside the archive to the command. For example, to extract the .bashrc and .bash_profile files from the archive, we would run:

$ borg extract --list /mnt/borg::archive-fingolfin-2022-04-23T19:33:58 .bashrc .bash_profile

On the opposite, if we want to specify the files to be excluded from the extraction, we can use the --exclude option. So, say we want to exclude all the files contained in the .local directory. We would run:

$ borg extract --list /mnt/borg::archive-fingolfin-2022-04-23T19:33:58 --exclude .local

Deleting an archive

If we want to delete a specific archive contained in our Borg repository, we have to use the “delete” command, and provide the repository and archive name. To remove the archive we used in the previous examples, we would run:

$ borg delete /mnt/borg::archive-fingolfin-2022-04-23T19:33:58

Conclusions

In this tutorial we learned the basics of Borg, a really efficient deduplicating backups program. We learned how Borg works under the hood and the concepts it revolves around. We saw how to initialize a repository and what encryption methods we can use for it, how to create archives with or without compressions, how to mount, restore and delete them. This tutorial meant to be just an introduction to Borg: there is really a lot more it can do. To learn to use the program at its full capabilities, please take a look at its manual!



Comments and Discussions
Linux Forum