Encrypted BTRFS storage setup with LUKS

Unfortunately, BTRFS doesn’t have an integrated, on filesystem level, encryption solution. The best solution for now (until hopefully BTRFS will get an integrated encryption solution) is to make use of LUKS. This adds a layer, but comes with the advantage of having full disk encryption that is transparent for the upper layer, in our case the BTRFS filesystem.

This exemplary setup uses two devices /dev/sdb and /dev/sdc but can be applied to any amount of devices by following the steps with additional devices.

Create a (random generated) keyfile:

dd bs=64 count=1 if=/dev/urandom of=/etc/cryptkey iflag=fullblock
chmod 600 /etc/cryptkey

Encrypt the devices:

cryptsetup -v -c aes-xts-plain64 -h sha512 -s 512 luksFormat /dev/sdb /etc/cryptkey
cryptsetup -v -c aes-xts-plain64 -h sha512 -s 512 luksFormat /dev/sdc /etc/cryptkey

For safety make a backup of the LUKS headers:

cryptsetup luksHeaderBackup --header-backup-file ~/sdb.header.bak /dev/sdb
cryptsetup luksHeaderBackup --header-backup-file ~/sdc.header.bak /dev/sdc

Automatically unlock LUKS devices on boot by adding them to /etc/crypttab:

# Use 'blkid /dev/sdb' and 'blkid/dev/sdc' to get the UUID
data1 UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /etc/cryptkey luks,noearly #,discard (for SSDs)
data2 UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /etc/cryptkey luks,noearly #,discard (for SSDs)

Unlock encrypted devices now to create the filesystem in the next step:

cryptsetup open --key-file=/etc/cryptkey --type luks /dev/sdb data1
cryptsetup open --key-file=/etc/cryptkey --type luks /dev/sdc data2

Or regenerate and reload the crypttab:

/usr/lib/systemd/system-generators/systemd-cryptsetup-generator /run/systemd/generator
systemctl daemon-reload
systemctl restart cryptsetup.target

Create the BTRFS filesystem:

mkfs.btrfs -L btrfs_data_volume -m raid1 -d raid1 /dev/mapper/data1 /dev/mapper/data2

Mount the BTRFS filesystem:

mount -t btrfs -o defaults,noatime -L btrfs_data_volume /mnt/data

And add the mount to the /etc/fstab:

LABEL=btrfs_data_volume /mnt/data btrfs defaults,noatime 0 2

Leave a Reply

Your email address will not be published. Required fields are marked *