Btrbk is a backup tool for btrfs subvolumes, taking advantage of btrfs specific capabilities to create atomic snapshots and transfer them incrementally to your backup locations.
The source and target locations are specified in a config file, which allows to easily configure simple scenarios like "laptop with locally attached backup disks", as well as more complex ones, e.g. "server receiving backups from several hosts via ssh, with different retention policies".
Key Features:
Btrbk is designed to run as a cron job for triggering periodic snapshots and backups, as well as from the command line (e.g. for instantly creating additional snapshots).
Btrbk is a single perl script, and does not require any special installation procedures or libraries. Download the latest [btrbk source tarball], or try latest master:
wget https://raw.githubusercontent.com/digint/btrbk/master/btrbk
chmod +x btrbk
sudo ./btrbk ls /
For more information, read the installation documentation.
Please consult the btrbk(1) man-page provided with this package for a full description of the command line options.
Before running btrbk
, you will need to create a configuration
file. You might want to take a look at btrbk.conf.example
provided
with this package. For a detailed description, please consult the
btrbk.conf(5) man-page.
After a configuration change, it is highly recommended to check it by
running btrbk with the -n,--dry-run
option:
# btrbk -c /path/to/myconfig -v -n run
This will read all btrfs information on the source/target filesystems and show what actions would be performed (without writing anything to the disks).
The examples below assume that the btrfs subvolume containing home
and rootfs
is mounted at /mnt/btr_pool
. This is usually the btrfs
root subvolume, which always has subvolid=5
.
Mounting subvolid=5
is recommended (mandatory for btrbk < v0.32.0)
if you want to backup your root filesystem /
.
/etc/fstab:
/dev/sda1 /mnt/btr_pool btrfs subvolid=5,noatime 0 0
Note that some default btrfs installations (e.g. Ubuntu) use subvolume
names @
for rootfs (mounted at /
) and @home
for /home
, as a
naming convention. If this is the case on your file system, replace
the subvolume
declarations in the examples accordingly.
The simplest use case is to only create snapshots of your data. This will obviously not protect it against hardware failure, but can be useful for:
Let's assume you need regular snapshots of your home directory, which
is located in the subvolume home
of the volume /mnt/btr_pool
. The
snapshots are to be stored in btrbk_snapshots
(on the same volume).
/etc/btrbk/btrbk.conf:
timestamp_format long
snapshot_preserve_min 18h
snapshot_preserve 48h
volume /mnt/btr_pool
snapshot_dir btrbk_snapshots
subvolume home
Notice that the target
option is not provided, and btrbk will only
manage snapshots located on the same volume in snapshot_dir
. Btrbk
does not create subdirs by default, the snapshot directory must first
be created manually:
# mkdir /mnt/btr_pool/btrbk_snapshots
The "volume" section is merely used as a specifier for a base directory, and can be skipped if you prefer to configure everything using absolute paths. The above configuration can also be written as:
snapshot_dir /mnt/btr_pool/btrbk_snapshots
subvolume /mnt/btr_pool/home
If you don't want to mount the btrfs root filesystem to
/mnt/btr_pool
, you might as well configure it like this:
snapshot_dir /btrbk_snapshots
subvolume /home
Start a dry run (-n, --dry-run):
# btrbk run -n
Create the first snapshot:
# btrbk run
Print schedule (-S, --print-schedule):
# btrbk run -n -S
If it works as expected, configure a cron job to run btrbk hourly:
/etc/cron.hourly/btrbk:
#!/bin/sh
exec /usr/bin/btrbk -q run
Snapshots will now be created every hour. All snapshots are preserved for at
least 18 hours (snapshot_preserve_min
), whether they are created by the cron
job or manually by calling sudo btrbk run
on the command line. Additionally,
48 hourly snapshots are preserved (snapshot_preserve
).
In this example, we assume you have a laptop with:
/mnt/btr_pool
, containing a subvolume rootfs
for the root
filesystem (i.e. mounted on /
) and a subvolume home
for the
user data,/mnt/btr_pool/btrbk_snapshots
which
will hold the btrbk snapshots,/mnt/btr_backup
,
containing a subvolume or directory mylaptop
for the incremental
backups.Retention policy:
/etc/btrbk/btrbk-mylaptop.conf:
snapshot_preserve_min 2d
snapshot_preserve 14d
# Create snapshots only if the backup disk is attached
#snapshot_create ondemand
target_preserve_min no
target_preserve 20d 10w *m
snapshot_dir btrbk_snapshots
volume /mnt/btr_pool
target /mnt/btr_backup/mylaptop
subvolume rootfs
subvolume home
[...]
/etc/cron.daily/btrbk:
#!/bin/sh
exec /usr/bin/btrbk -q -c /etc/btrbk/btrbk-mylaptop.conf run
/mnt/btr_pool/btrbk_snapshots/rootfs.YYYYMMDD
/mnt/btr_pool/btrbk_snapshots/home.YYYYMMDD
/mnt/btr_backup/mylaptop/rootfs.YYYYMMDD
/mnt/btr_backup/mylaptop/home.YYYYMMDD
If you prefer triggering the backups manually, change the cron command
to run the snapshot
action instead of run
. Start the backups
manually by running:
# btrbk resume
For a quick additional snapshot of your home, run:
# btrbk snapshot home
Let's say you have a fileserver at "myserver.example.org" where you want to create backups of your laptop disk. The config could look like this:
ssh_identity /etc/btrbk/ssh/id_rsa
volume /mnt/btr_pool
subvolume rootfs
target /mnt/btr_backup/mylaptop
target ssh://myserver.example.org/mnt/btr_backup/mylaptop
In addition to the backups on your local usb-disk mounted at
/mnt/btr_backup/mylaptop
, incremental backups would also be pushed
to myserver.example.org
.
If you're a sysadmin and want to trigger backups directly from your fileserver, the config would be something like:
ssh_identity /etc/btrbk/ssh/id_rsa
volume ssh://alpha.example.org/mnt/btr_pool
target /mnt/btr_backup/alpha
subvolume rootfs
subvolume home
volume ssh://beta.example.org/mnt/btr_pool
target /mnt/btr_backup/beta
subvolume rootfs
subvolume dbdata
This will pull backups from alpha/beta.example.org and locally create:
/mnt/btr_backup/alpha/rootfs.YYYYMMDD
/mnt/btr_backup/alpha/home.YYYYMMDD
/mnt/btr_backup/beta/rootfs.YYYYMMDD
/mnt/btr_backup/beta/dbdata.YYYYMMDD
Let's say we have a host (at 192.168.0.42) running btrbk with the setup of the time-machine example above, and we need a backup server to only fetch the snapshots.
/etc/btrbk/btrbk.conf (on backup server):
target_preserve_min no
target_preserve 0d 10w *m
volume ssh://192.168.0.42/mnt/btr_pool
target /mnt/btr_backup/my-laptop
subvolume home
snapshot_dir btrbk_snapshots
snapshot_preserve_min all
snapshot_create no
If the server runs btrbk with this config, 10 weeklies and all
monthlies are received from 192.168.0.42. The source filesystem is
never altered because of snapshot_preserve_min all
.
Common virtual machine setups have multiple volume sections with same host, but distinct port numbers for each machine.
/etc/btrbk/btrbk.conf:
# This propagates to all subvolume sections:
target /mnt/btr_backup/
volume ssh://localhost:2201/mnt/btr_pool
group vm vm01
subvolume home
snapshot_name vm01-home
subvolume data
snapshot_name vm01-data
volume ssh://localhost:2202/mnt/btr_pool
group vm vm02
subvolume home
snapshot_name vm02-home
volume ssh://localhost:2203/mnt/btr_pool
[...]
This will create /mnt/btr_backup/vm[NN]-home
, vm[NN]-data
, ...
Note that btrbk holds a single reference to every btrfs filesystem
tree, regarding UUID's as "globally unique". If the configured
subvolumes point to the same filesystem on different machines (ports),
you will see log lines like this when running btrbk -v
:
Assuming same filesystem: "ssh://localhost:2201/dev/sda1", "ssh://localhost:2202/dev/sda1"
If you want to make backups from a filesystem other than btrfs (e.g. ext4 or reiserfs), you need to create a synchronization subvolume on the backup disk:
# btrfs subvolume create /mnt/btr_backup/myhost_sync
Configure btrbk to use myhost_sync
as source subvolume:
volume /mnt/btr_backup
subvolume myhost_sync
snapshot_name myhost
snapshot_preserve_min latest
snapshot_preserve 14d 20w *m
The btrbk package provides the "btrbk-mail" script, which automates the synchronization using rsync, and can be run as cron job or systemd timer unit. For configuration details, see the config section in "/contrib/cron/btrbk-mail".
Alternatively, you can run any synchronization software prior to running btrbk. Something like:
#!/bin/sh
rsync -az --delete \
--inplace --numeric-ids --acls --xattrs \
-e 'ssh -i /etc/btrbk/ssh/id_rsa' \
myhost.example.org:/data/ \
/mnt/btr_backup/myhost_sync/
exec /usr/bin/btrbk -q run
This will produce snapshots /mnt/btr_backup/myhost.20150101
, with
retention as defined with the snapshot_preserve option.
If your backup server does not support btrfs, you can send your subvolumes to a raw file.
This is an experimental feature: btrbk supports "raw" targets,
meaning that similar to the "send-receive" target the btrfs subvolume
is being sent using btrfs send
(mirroring filesystem level data),
but instead of instantly being received (btrfs receive
) by the
target filesystem, it is being redirected to a file, optionally
compressed and piped through GnuPG.
/etc/btrbk/btrbk.conf:
raw_target_compress xz
raw_target_encrypt gpg
gpg_keyring /etc/btrbk/gpg/pubring.gpg
gpg_recipient btrbk@example.org
volume /mnt/btr_pool
subvolume home
target raw ssh://cloud.example.com/backup
ssh_user btrbk
# incremental no
This will create a GnuPG encrypted, compressed files on the target host. For each backup, two files are created:
/backup/home.YYYYMMDD.btrfs.xz.gpg
: main data file containing
the btrfs send-stream,/backup/home.YYYYMMDD.btrfs.xz.gpg.info
: sidecar file containing
metadata used by btrbk.If you are using raw incremental backups, please make sure you understand the implications (see btrbk.conf(5), TARGET TYPES).
Since btrbk needs root access, it is very advisable to take all the
security precautions you can. In most cases backups are generated
periodically without user interaction, so it is not possible to
protect your ssh key with a password. The steps below will give you
hints on how to secure your ssh server for a backup scenario. Note
that the btrbk package is not required on the remote side, but you
will need the btrfs
executable from the btrfs-progs package.
On the client side, create a ssh key dedicated to btrbk, without password protection:
# ssh-keygen -t rsa -b 4096 -f /etc/btrbk/ssh/id_rsa -C btrbk@example.org -N ""
The content of the public key (/etc/btrbk/ssh/id_rsa.pub) is used for authentication in "authorized_keys" on the server side (see [sshd(8)] for details).
The most straight forward setup is to allow root login on the remote host. If this is not an option for you, refer to the more complex "Dedicated Btrbk User Login" section below.
/etc/ssh/sshd_config:
PermitRootLogin prohibit-password
Add your btrbk public key to "/root/.ssh/authorized_keys" on the server, and you are good to go.
Restrict ssh access to a static IP address within your network. On the remote host, either add a "Match" block in:
/etc/ssh/sshd_config:
Match Address 192.168.0.42
Or restrict in authorized_keys:
from="192.168.0.42" <pubkey>...
Consult the [sshd_config(5)] man-page for a detailed explanation and more options.
If allowing root login is not an option for you, there are several ways to restrict SSH access to a regular user.
On the client side, configure btrbk use the sudo backend. This changes
the ssh calls to btrfs commands to `sudo btrfs