Encrypting and formatting a disk with LUKS + Btrfs
Hey there, a wild tutorial appeared! This is just a quick one for self-reference, but I hope it helps others too.
The problem at hand is that of formatting a data disk (if you want to format your root /
disk please look elsewhere - it usually has to be done before or during installation unless you like fiddling around in a live environment) with Btrfs.... but also encrypting the disk, which isn't something that Btrfs natively supports.
I'm copying over some data to my new lab PC, and I've decided to up the security on the data disk I store my research data on.
Unfortunately, both GParted and KDE Partition Manager were unable to help me (the former not supporting LUKS, and the latter crashing with a strange error), so I ended up looking through more posts that should be reasonable to find a solution that didn't involve encrypting either /
or /boot
.
It's actually quite simple. First, find your disk's name via lsblk
, and ensure you have created the partition in question. You can format it with anything (e.g. using the above) since we'll be overwriting it anyway.
Note: You may need to reboot after creating the partition (or after some of the below) if you encounter errors, as Linux sometimes doesn't like new partitions appearing out of the blue with names that were used previously on that boot very much.
Then, format it with LUKS, the most common encryption scheme on Linux:
sudo cryptsetup luksFormat /dev/nvmeXnYpZ
...then, formatting with Btrfs is a 2-step process. First we hafta unlock the LUKS encrypted partition:
sudo cryptsetup luksOpen /dev/nvme0n1p1 SOME_MAPPER_NAME
...this creates a virtual 'mapper' block device we can hit like any other normal (physical) partition. Change SOME_MAPPER_NAME
to anything you like so long as it doesn't match anything else in lsblk
/df -h
and also doesn't contain spaces. Avoid unicode/special characters too, just to be safe.
Then, format it with Btrfs:
sudo mkfs.btrfs --metadata single --data single --label "SOME_LABEL" /dev/mapper/SOME_MAPPER_NAME
...replacing SOME_MAPPER_NAME
(same value you chose earlier) and SOME_LABEL
as appropriate. If you have multiple disks, rinse and repeat the above steps for them, and then bung them on the end:
sudo mkfs.btrfs --metadata raid1 --data raid1 --label "SOME_LABEL" /dev/mapper/MAPPER_NAME_A /dev/mapper/MAPPER_NAME_B ... /dev/mapper/MAPPER_NAME_N
Note the change from single
to raid1
. raid1
stores at least 2 copies on different disks - it's a bit of a misnomer as I've talked about before.
Now that you have a kewl Btrfs-formatted partition, mount it as normal:
sudo mount /dev/mapper/SOME_MAPPER_NAME /absolute/path/to/mount/point
For Btrfs filesystems with multiple disks, it shouldn't matter which source partition you pick here as Btrfs should pick up on the other disks.
Automation
Now that we have it formatted, we don't want to hafta keep typing all those commands again. The simple solution to this is to create a shell script and put it somewhere in our $PATH
.
To do this, we should ensure we have a robust name for the disk instead of /dev/nvme
, which could point to a different disk in future if your motherboard or kernel decides to present them in a different order for a giggle. That's easy by looking over the output of blkid
and cross-referencing it with lsblk
and/or df -h
:
sudo lsblk
sudo df -h
sudo blkid # → UUID
The number you're after should be in the UUID=""
field. The shell script I came up with is short and sweet:
#!/usr/bin/env bash
disk_id="ID_FROM_BLKID";
mapper_name="SOME_NAME";
mount_path="/absolute/path/to/mount/dir";
sudo cryptsetup luksOpen "/dev/disk/by-uuid/${disk_id}" "${mapper_name}";
sudo mount "/dev/mapper/${mapper_name}" "${mount_path}"
Fill in the values as appropriate:
disk_id
: The UUID of the disk in question fromblkid
.mapper_name
: A name of your choosing that doesn't clash with anything else in/dev/mapper
on your systemmount_path
: The absolute path to the directory that you want to mount into - usually in/mnt
or/media
.
Put this script in e.g. $HOME/.local/bin
or somewhere else in $PATH
that suits you and your setup. Don't forget to run chmod +x path/to/script
!
Conclusion
We've formatted an existing partition with LUKS and Btrfs, and written a quick-and-dirty shell script to semi-automate the process of mounting it here.
If this has been useful or if you have any suggestions, please do leave a comment below!
Sources and further reading
- Another guide that I have somehow lost that reminded me about
cryptsetup luksFormat
andcryptsetup luksOpen
- if you find it again please leave a comment below! I think it was a GitHub Gist or repo somewhere - cryptsetup - device-mapper: reload ioctl on failed: No such file or / Newbie Corner / Arch Linux Forums
- linux: How can I view all UUIDs for all available disks on my system? - Unix & Linux Stack Exchange