- Encrypt an existing unencrypted file system - dm-crypt/Device encryption from the Arch Linux Wiki
- Install and Configure GRUB Bootloader - How To Encrypt Root Filesystem on Linux by Schkn on devconnected
- Using A Live CD/USB To Fix Your Current System - GrubEFIReinstall from the Debian Wiki
- Tom Hale’s answer to “Resize btrfs filesystem to the minimum size in a single step” on the Unix & Linux Stack Exchange
- Robert Cutajar’s question “Initramfs in debootstrap chroot of fully encrypted system” on the Unix & Linux Stack Exchange
- “Full disk encryption (including boot) on Debian” by Daniel Wayne Armstrong
This guide presumes the following
- That your
/bootmount corresponds to a distinct partition with
/boot/efibeing on your ESP (which itself, is a distinct partition independent of
- That your root filesystem uses BTRFS (multiple guides exist on the internet if you use EXT4)
- That you do not use the Logical Volume Manager and are just dealing with plain BTRFS
- You are willing to deal with some system downtime and that you are booting and following this guide from a Debian live USB with an internet connection
/dev/sdX1is your ESP,
/dev/sdX2is your root partition,
/bootdrive (it’s very likely that it’s not, I’m just mentioning this so that you change it instead of possibly doing destructive actions to a completely unrelated disk)
- You have a backup… on a distinct physical disk if this blows up in your face or you have a power outage or thermonuclear warfare ensues
- That your computer is modern enough that it doesn’t have to deal with USB keyboard shenanigans as this guide does not account for it
Encrypting your root partition⌗
Mounting and resizing your BTRFS filesystem (not partition, filesystem)⌗
Did you know… You can resize a filesystem without resizing the partition it lies on! Turns out, they are two distinct things. For this guide, as we need to introduce a LUKS header, we need to shrink our drive’s filesystem (while maintaining the partition size) before we get going.
Let’s first create a folder that will contain our mounted root directory
# mkdir /mnt/btrfs
Then mount our BTRFS root partition and query its available size
# mount /dev/sdX1 /mnt/btrfs # btrfs filesystem usage -b /mnt/btrfs
btrfs filesystem usage -b /mnt/btrfs should return information to the tune of
[...] Used: 77960871936 Free (estimated): 136431190016 (min: 136431190016) Free (statfs, df): 136430141440 Data ratio: 1.00 Metadata ratio: 1.00 [...]
Let’s take the
Free (statfs, df) value of
136430141440 for my drive (naturally, yours will differ) and multiply it by
0.9 (use a calculator or better yet, a search engine so you can just Ctrl+C, Ctrl+V that) and then you’ll get
Make sure that the difference at least provides you with 128M of buffer space to play with. Now let’s resize our BTRFS filesystem by running.
# btrfs filesystem resize -122787127296 /mnt/btrfs # The minus sign indicates that this is a shrink operation
Now that we have resized our filesystem, it’s time to encrypt the partition.
Unmounting and encrypting your filesystem using LUKS2⌗
First, we must unmount our BTRFS filesystem.
# umount /mnt/btrfs
Then we can encrypt the filesystem using cryptsetup and ask it to allocate
128M for our LUKS header.
# cryptsetup reencrypt --encrypt --reduce-device-size 128M /dev/sdX1 # You need to set your password here
Once that succeeds, we will now mount our freshly encrypted LUKS partition.
Mounting your encrypted filesystem and resizing it again⌗
Our new LUKS parition will be mapped to the name
cryptroot (you can change this to anything you want but the rest of the guide operates on the presumption that you’re naming it
cryptroot). Let’s mount it.
# cryptsetup luksOpen /dev/sdX1 cryptroot # You will be prompted your password
Once we have done that, our unlocked container is now mapped to
/dev/mapper/cryptroot so now let’s mount the BTRFS filesystem it contains.
# mount /dev/mapper/cryptroot /mnt/btrfs
Once we have achieved that, let’s reclaim the space and undo the shrinking operation from last time.
# btrfs filesystem resize max /mnt/btrfs
Good news! You now have an encrypted root partition. Bad news, you cannot boot from it.. yet.
Setting up our chroot environment⌗
We will be setting up an environment such that we re-define
/ (root) to be the root directory of our filesystem instead of
the root directory of our live environment (hence, we’re changing our root directory… so
chroot). We will use the
chroot command to do that but before we do, we have to do some setup.
Have two terminal tabs, one for the
chroot'ed environment and one for your live installation. Let’s go to the live installation, first.
Let’s start by mounting our
/boot/efi partitions for our
chrooted environment to eventually access
P.S. All commands inside the
chroot will be prefixed with a
% to distinguish them while commands in the live environment are prefixed with
# mount /dev/sdX4 /mnt/btrfs/boot # mount /dev/sdX1 /mnt/btrfs/boot/efi
Now we need to give our chroot the ability to access block devices. To do so, we will need to bind mount
# mount -B /dev /mnt/btrfs/dev
Now go to the
chroot'ed tab (if you don’t have one, you can open a new tab and type in
chroot /mnt/btrfs to get into a chrooted environment) and have the chrooted environment mount
% mount --types=proc proc /proc % mount --types=sysfs sys /sys
Now return to the live environment tab and mount the directory that contains your NVRAM variables (important for when you update GRUB) so that your
chroot'ed environment can access them
# mount -B /sys/firmware/efi/efivars /mnt/btrfs/sys/firmware/efi/efivars
Modifying our operating system configuration files⌗
We need to install
cryptsetup-initramfs package into the
chroot so that the bootloader and bootstrapping process can read and understand encrypted filesystems. But running
apt won’t work because our
chroot doesn’t know how to resolve domain names, which our package managers rely on, so to fix that we must first go to our live environment and run…
# cp /etc/resolv.conf /mnt/btrfs/etc/resolv.conf
Once we’ve done that, now we can install the package within our
% apt update && apt install cryptsetup-initramfs -y
Telling our operating system that root is mounted from an encrypted partition⌗
Now that we’ve setup our chroot, we can use it to modify our existing installation, its boot partition and the EFI System Partition (as we mounted them in our earlier steps).
First, let’s tell our operating system that there is an encrypted filesystem in the first place by modifying
/etc/crypttab. Before we do that, we need to know the UUID of the LUKS partition (not the underlying BTRFS partition) and to do that, we will run
lsblk -f, which will give you an output similar to
[...] sdX ├─sdX1 vfat FAT32 AAAA-AAAA 1017.9M 0% /mnt/btrfs/boot/efi ├─sdX2 crypto_LUKS 2 ffffffff-ffff-ffff-ffff-ffffffffffff │ └─cryptroot btrfs f0f0f0f0-f0f0-f0f0-f0f0-f0f0f0f0f0f0 127G 36% /mnt/btrfs/ ├─sdX3 btrfs Home aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa 163.4G 38% /mnt/btrfs/home └─sdX4 vfat FAT32 FFFF-FFFF 682M 33% /mnt/btrfs/boot [...]
We’re interested in the UUID of
BTRFS and so we’ll take
ffffffff-ffff-ffff-ffff-ffffffffffff (yours will naturally, vary)
Then open up
/etc/crypttab with an editor of your choice and ensure that it looks something like this
# <name> <device> <password> <options> cryptroot UUID=ffffffff-ffff-ffff-ffff-ffffffffffff none luks
Done? Not quite. Now we need to modify
/etc/fstab and tell it that we’re no longer booting off an unencrypted BTRFS partition but to a map of an encrypted partition…
Once you open
/etc/fstab, you’ll probably have something akin to this…
[...] # <file system> <mount point> <type> <options> <dump> <pass> UUID=f0f0f0f0-f0f0-f0f0-f0f0-f0f0f0f0f0f0 / btrfs defaults,noatime 0 1 [..]
You should change it in a way such that it results in looking like this..
[...] # <file system> <mount point> <type> <options> <dump> <pass> /dev/mapper/cryptroot / btrfs defaults,noatime 0 1 [...]
Telling the bootloader (GRUB) that we’re booting off an encrypted partition⌗
Now that we’ve changed our
/etc/fstab (these files are read by the operating system in this order), now it’s time to tell GRUB all about it. Just remember your
crypto_LUKS UUID (
/etc/default/grub with your preferred text editor and ensure these lines are present in them
# Setting up GRUB (/etc/default/grub) GRUB_PRELOAD_MODULES="cryptodisk luks" GRUB_ENABLE_CRYPTODISK=y
Then find the
GRUB_CMDLINE_LINUX_DEFAULT variable and ensure that
cryptdevice=UUID=ffffffff-ffff-ffff-ffff-ffffffffffff root=/dev/mapper/cryptroot is appended to whatever may or may not be there.
Mine for example, ends up looking like…
[...] GRUB_CMDLINE_LINUX_DEFAULT="quiet splash cryptdevice=UUID=ffffffff-ffff-ffff-ffff-ffffffffffff root=/dev/mapper/cryptroot" [...]
cryptdevice detection by UUID and
root mapping by
crypttab name is in the variable, you’re good (hint: the delimiter between each instruction is a space)
Now we need these changes to be reflected.
% grub-install /dev/sdX # Presuming /dev/sdX is the destination drive, do not append numbers % update-initramfs -c -k all # Updates the ramdisk... % update-grub2 # Remember to add encrypted root to /etc/crypttab and /dev/mapper/cryptroot is in fstab
Hopefully, we’re now done with what we’ve needed to do, so now let’s do a cleanup because cleanup good (you can close the chroot, we’re done with it)
# sync # Ensure everything we've done is flushed to disk # umount /mnt/btrfs/sys/firmware/efi/efivars # umount /mnt/btrfs/sys # umount /mnt/btrfs/proc # umount /mnt/btrfs/boot/efi # umount /mnt/btrfs/boot # umount /mnt/btrfs/dev # umount /mnt/btrfs # sync # For good luck
Reboot, fingers crossed and hope things work. If they don’t, then Google is your friend and hope you have a backup!
Due to a bug in GRUB, when I followed other guides which recommended to additionally add
usb usb_keyboard ehci ohci uhci to my
GRUB_PRELOAD_MODULES, it bricked my bootloader by breaking hard drive detection.
I remember reading some forum post at 1AM where the same thing was talked about but I can’t find it. It is quite possible you’ll need to read additional guides that talk about enabling USB keyboard support in GRUB but I’ve omitted it from my guide as my computer didn’t need it and it bricked my bootloader (these guides come from stuff that I work on during off hours and figure that it’s neat to write about it by going through my command history and retracing my steps).