Some personal notes on setting up an encrypted secondary drive with btrfs, luks2, fstab, crypttab, and grub.
Use fdisk
to partition the disk. For example, if the disk is /dev/sdb
:
fdisk /dev/sdb
Create a new partition table with g
(GPT). Create a new partition with n
(new partition), p
(primary), 1
(partition number), Enter
(default first
sector), Enter
(default last sector). Write changes with w
.
Encrypt the partition with cryptsetup
(Enter a passphrase when prompted):
cryptsetup luksFormat --type luks2 /dev/sdb1
cryptsetup open /dev/sdb1 my_encrypted_partition
Create a key file for the encrypted partition (it is needed for booting without entering a passphrase):
dd bs=512 count=4 if=/dev/urandom of=/etc/secrets/my_encrypted_partition.keyfile iflag=fullblock
chmod 400 /etc/secrets/my_encrypted_partition.keyfile
Obs: the key file is created with 4 KiB of random data and should be readable only by root.
Add the key file to the encrypted partition:
cryptsetup luksAddKey /dev/sdb1 /etc/secrets/my_encrypted_partition.keyfile
For the system to automatically unlock the encrypted partition at boot, add an
entry to /etc/crypttab
.
Find the UUID of the encrypted partition:
blkid /dev/sdb1
Add the following line to /etc/crypttab
:
my_encrypted_partition UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX /etc/secrets/my_encrypted_partition.keyfile luks
Create a btrfs file system on the encrypted partition:
mkfs.btrfs -L my_encrypted_partition /dev/mapper/my_encrypted_partition
obs: -L
is optional, it sets the label of the partition.
Mount the encrypted partition:
mount -t btrfs /dev/mapper/my_encrypted_partition /mnt/my_encrypted_partition
or use the label:
mount -t btrfs LABEL=my_encrypted_partition /mnt/my_encrypted_partition
Create subvolumes as needed:
btrfs subvolume create /mnt/my_encrypted_partition/@root
btrfs subvolume create /mnt/my_encrypted_partition/@snapshots
btrfs subvolume create /mnt/my_encrypted_partition/@data1
btrfs subvolume create /mnt/my_encrypted_partition/@data2
btrfs subvolume create /mnt/my_encrypted_partition/@data3
# ...
use btrfs subvolume list /mnt/my_encrypted_partition
to list subvolumes.
unmount the partition:
umount /mnt/my_encrypted_partition
Mount the subvolumes:
mount -t btrfs -o subvol=@root /dev/mapper/my_encrypted_partition /mnt/my_encrypted_partition
mount -t btrfs -o subvol=@snapshots /dev/mapper/my_encrypted_partition /mnt/my_encrypted_partition/.snapshots
mount -t btrfs -o subvol=@data1 /dev/mapper/my_encrypted_partition /mnt/my_encrypted_partition/data1
mount -t btrfs -o subvol=@data2 /dev/mapper/my_encrypted_partition /mnt/my_encrypted_partition/data2
mount -t btrfs -o subvol=@data3 /dev/mapper/my_encrypted_partition /mnt/my_encrypted_partition/data3
# ...
If you want the subvolumes to be mounted automatically at boot, add entries to
/etc/fstab
.
Find the UUID of the encrypted partition:
blkid /dev/mapper/my_encrypted_partition
Add the following lines to /etc/fstab
:
# Partitions for my_encrypted_partition
UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX /mnt/my_encrypted_partition btrfs your_desired_options,subvol=@root 0 0
UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX /mnt/my_encrypted_partition/.snapshots btrfs your_desired_options,subvol=@snapshots 0 0
UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX /mnt/my_encrypted_partition/data1 btrfs your_desired_options,subvol=@data1 0 0
UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX /mnt/my_encrypted_partition/data2 btrfs your_desired_options,subvol=@data2 0 0
UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX /mnt/my_encrypted_partition/data3 btrfs your_desired_options,subvol=@data3 0 0
# ...
Obs: replace your_desired_options
with your desired mount options. Use
man mount
to see the available options.
Add the following lines to /etc/fstab
:
# Partitions for my_encrypted_partition
LABEL=my_encrypted_partition /mnt/my_encrypted_partition btrfs your_desired_options,subvol=@root 0 0
LABEL=my_encrypted_partition /mnt/my_encrypted_partition/.snapshots btrfs your_desired_options,subvol=@snapshots 0 0
LABEL=my_encrypted_partition /mnt/my_encrypted_partition/data1 btrfs your_desired_options,subvol=@data1 0 0
LABEL=my_encrypted_partition /mnt/my_encrypted_partition/data2 btrfs your_desired_options,subvol=@data2 0 0
LABEL=my_encrypted_partition /mnt/my_encrypted_partition/data3 btrfs your_desired_options,subvol=@data3 0 0
# ...
Obs: replace your_desired_options
with your desired mount options. Use
man mount
to see the available options.
Currently I'm using the following options:
rw, noexec, user, noatime, nofail, async, compress=zstd:3, space_cache=v2, nodiscard, commit=60, x-systemd.idle-timeout=15s, x-systemd.mount-timeout=10s, x-systemd.device-timeout=10s, subvol=@<subvolume>, x-systemd.requires=<path_to_encrypted_partition_root>
# rw,noexec,user,noatime,nofail,async,compress=zstd:3,space_cache=v2,nodiscard,commit=60,x-systemd.idle-timeout=15s,x-systemd.mount-timeout=10s,x-systemd.device-timeout=10s,subvol=@root
UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX /mnt/my_encrypted_partition btrfs rw,noexec,user,noatime,nofail,async,compress=zstd:3,space_cache=v2,nodiscard,commit=60,x-systemd.idle-timeout=15s,x-systemd.mount-timeout=10s,x-systemd.device-timeout=10s,subvol=@root 0 3
# same as above, but with x-systemd.requires=/mnt/my_encrypted_partition
UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX /mnt/my_encrypted_partition/.snapshots btrfs rw,noexec,user,noatime,nofail,async,compress=zstd:3,space_cache=v2,nodiscard,commit=60,x-systemd.idle-timeout=15s,x-systemd.mount-timeout=10s,x-systemd.device-timeout=10s,subvol=@snapshots,x-systemd.requires=/mnt/my_encrypted_partition 0 3
To be fair, I don't remember why I'm using most of those options, I just kept changing when I had issues or when I read something that seemed to make sense. But nofail is important, it prevents the system from hanging if the partition is not available at boot.