Linux Unified Key Setup (LUKS)
All the examples below assume wanting to setup a btrfs pool on two disks `/dev/
sdX` and sdX`/dev/
sdY` that will be used just for additional storage.sdY
Prepare Disks
Before encrypting a drive, it is recommended to perform a secure erase of the disk by overwriting the entire drive with random data. To prevent cryptographic attacks or unwanted file recovery, this data is ideally indistinguishable from data later written by dm-crypt.
Source
There are multiple ways to prepare a disk and some other potentially better ones listed on the page linked to above. Because I wantedwant to wipe my disks as quickly as possible and they were both the same size I usedam using a slightly more complicated method. This method creates the equivalent of filling the disks with the output from /dev/urandom
but does so faster by using the output of encrypting /dev/zero
and writing that to the disks.disks instead. I save even more time by using tee
and process substitution
to redirect the output to both drives at once. Just for good measure I usedam using pv
to measure the speed at which I am writing and to track my progress.
PASS=$(tr -cd '[:alnum:]' < /dev/urandom | head -c128)
openssl enc -aes-256-ctr -pass pass:"$PASS" -nosalt < /dev/zero | dd ibs=4K | pv | tee >(dd obs=64K oflag=direct of=/dev/sdX) | dd obs=64K oflag=direct of=/dev/sdY
Partition
Although LUKS can be layered on top of redundant storage (btrfs/mdadm+btrfs -or- mdadm + dm-integrity) for my usages it almost always makes sense to layer those things on top of LUKS.LUKS Alsoinstead. IMy don'tgoal useis LUKSjust to have an encrypted filesystem for mystorage bootof drivesdata so I justonly needed the drivesneed to havecreate one partition.partition on each disk.
sgdisk --clear --new=0:0:0 /dev/sdX
sgdisk --clear --new=0:0:0 /dev/sdY
Encrypt
Setup LUKS with passphrase encrypted drives.
cryptsetup open /dev/sdX1 cryptbtrpool_1
cryptsetup open /dev/sdY1 cryptbtrpool_2
AddCreate keyfile as optional decryptionencryption key.
dd if=/dev/urandom bs=512 count=4 of=/etc/keyfile
Add keyfile as optional decryption key.
cryptsetup luksAddKey /dev/sdX1 /etc/keyfile
cryptsetup luksAddKey /dev/sdY1 /etc/keyfile
Unlock Devices
cryptsetup open /dev/sdX1 cryptbtrpool_1 --key-file=/etc/keyfile
cryptsetup open /dev/sdY1 cryptbtrpool_2 --key-file=/etc/keyfile
Create btrfs Pool
You can use LUKS devices like any other block device and format them any way you want. However below I am combining them into a RAID1 btrfs filesystem that spans both disks and utilizes the underlying LUKS devices for encryption since btrfs doesn't support this natively.
mkfs.btrfs --data raid1 --metadata raid1 --label btrpool /dev/mapper/cryptbtrpool_1 /dev/mapper/cryptbtrpool_2
Add to crypttab
needIt is best practice to doreference thisdrives stillin /etc/fstab
or /etc/crypttab
using something more constant than just the dev name like /dev/sdX1
. I reference the drives by the UUID of the LUKS partition but another good option is to reference the drives by their "disk-id" found under /dev/disk/by-id/...
.
I can find the UUID for the LUKS partitions by using blkid
and grep
to filter the output.
blkid | grep LUKS
/dev/sdX1: UUID="99fc46af-1048-4c50-bc38-2085aee78579" TYPE="crypto_LUKS" PARTLABEL="Linux filesystem" PARTUUID="8cbdf3b0-7ba0-4b7b-8639-15ea3029c72e"
/dev/sdY1: UUID="507033de-5eb5-4baf-8875-6595fbb260af" TYPE="crypto_LUKS" PARTLABEL="Linux filesystem" PARTUUID="14d8331c-9a82-4e5d-8ea8-4d1a6d8025fe"
Now with those UUIDs I can use them in /etc/crypttab
to automatically open my LUKS partition during boot.
# <target name> <source device> <key file> <options>
+ cryptbtrpool_1 UUID=507033de-5eb5-4baf-8875-6595fbb260af /etc/keyfile
+ cryptbtrpool_2 UUID=99fc46af-1048-4c50-bc38-2085aee78579 /etc/keyfile
Add to fstab
needEntries in /etc/crypttab
will all have completed by the time entries in /etc/fstab
are attempted. So knowing that the LUKS devices will have been automatically opened I can then mount that filesystem as I would any other block device. Since the btrfs filesystem above was labeled btrpool
it is possible to domount thissubvolumes stillusing a combination of that label and the names of any subvolumes that were created.
# /etc/fstab
# <file system> <mount point> <type> <options> <dump> <pass>
+ LABEL=btrpool /storage/btrpool btrfs x-mount.mkdir=0755,defaults,subvol=@,compress=zstd 0 0
+ LABEL=btrpool /storage/btrpool/services btrfs defaults,subvol=@services,compress=zstd,X-mount.mkdir=0755 0 0
+ LABEL=btrpool /storage/btrpool/media btrfs defaults,subvol=@media,compress=zstd,X-mount.mkdir=0755 0 0