Full Disk Encryption on Exherbo
by Clement Delafargue on May 30, 2013
I’ve received my new laptop and I’ve decided to protect it with full-disk encryption (everything is encrypted, except the boot files). Since exherbo does not provide a customisable initramfs (the default one provided by the kernel is enough most of the time), I had to create one.
Additionnaly, this was the first time I’ve used a GPT (GUID Partition Table) and configured an EFI boot.
General setup
There are two partitions, /
and a data partition. These two partitions will
be encrypted with LUKS (Linux Unified Key Setup).
The keys will be stored in encrypted files on a different USB device, embedded in the Kernel’s initramfs.
At boot, the initramfs is loaded, prompts the key decryption passwords and
gives the deciphered keys to LUKS, which unlock the two partitions. Then the
init script mounts /
and calls switch_root
to start the boot process.
The initramfs archive is bundled in the kernel, so the USB device only contains bootloader config files and the kernel archive.
The bootloader I use is gummiboot, which is a lightweight EFI bootloader.
Disk setup
Partition tables
To build a GPT, you need to use gdisk
instead of fdisk
. Their UIs are
essentially the same. I think gparted
also handles GPT, but I’ve never
tried.
My laptop has a SSD, so it takes extra care when partitioning (it’s important to align partitions with disk sectors).
Luckily this is handled cleanly by gdisk
which aligns partitions by default.
One cool thing with GPT is that you can fit many partitions in a table (up to 128 IIRC). No more fiddling with primary / extended partitions and logical drives /.
The boot partition will be handled separately. This also means that your system can cleanly coexist with a windows install, without any fear of having the boot sectors wiped.
LUKS setup
Key generation
I’ve generated two random keyfiles with dd
dd if=/dev/random of=/path/to/key bs=1 count=256
If you’re not doing that from a live system, make sure to do it from a tmpfs
for extra security.
Next you need to encrypt the keyfiles with openssl:
openssl aes-256-cbc -in /path/to/key -out /path/to/key.enc
Make sure to backup the encrypted keyfiles, but don’t dump the plain keys yet.
LUKS setup
Now you need to setup the two LUKS partitions.
cryptsetup -c <cipher> -y -s <key-size> luksFormat <device> /path/to/key
When it’s done for the two partitions, you can delete the plain keys.
You can unlock the partitions now:
openssl aes-256-cbc -d -in /path/to/key.enc | \
cryptsetup [--allow-discards] --key-file=- luksOpen <device> <name>
If you have a SSD, you may want to use --allow-discards
. It creates an
information leak but it enhances your SSD’s lifetime.
Check this blog post for more information about trim and LUKS http://asalor.blogspot.de/2011/08/trim-dm-crypt-problems.html
The unlocked device is now available in /dev/mapper/<name>
and ready to be
formatted.
Formatting
For a regular disk, partition as you will.
mkfs.ext4 /dev/mapper/<name>
For a SSD, some tuning can be useful. For instance it’s important to disable journaling
sudo tune2fs -O ^has_journal /dev/mapper/<name>
Mounting the FS
For a regular disk, just mount it.
mount /dev/mapper/<name> /path/to/mountpoint
For a SSD, some extra options are useful:
noatime
,nodiratime
to disable access time loggingnobh
,data=writeback
to reduce writesdiscard
if you have enabled--allow-discards
in LUKS
Install your system
You’re now able to install the base system. Don’t forget to put the mount
options in your /etc/fstab
.
For an exherbo, I’d recommend the Exherbo Install Guide
Don’t forget to install an init system (I personally recommend systemd) but you can choose your favorite.
For the following, I’ll consider you’ve chrooted in your system.
Make it boot
The next step is to configure your boot device.
Partition Table
Create a GPT on your external device, make sure the boot partition has the correct type (EFI) and has the boot flag activated.
Format it in vfat.
Prepare your initramfs
The initramfs is the initial in-memory file system loaded by the boot manager.
It contains the encrypted keys, cryptsetup
and openssl
binaries (plus the
needed shared libraries) and an executable named init
which will be called.
Its work is to unlock the partitions and launch your system init.
Most distributions provide a generic initramfs
as well as a generic kernel,
with a tool to regenerate it. From what I’ve seen, those tools are based on
dracut which is a toolchain used to create initramfs. Since I knew exactly
the commands needed to unlock the partitions, using dracut was a bit overkill.
To ease things a bit, I’ve used busybox
which provides a small shell and
many core tools in a single staticly-built binary.
Since copying binaries and libraries in the archive is tedious, let the kernel
build process do it for you: in a file named initramfs
, you just have to
specify which files you need, where to get it and where to make it available.
Unlike busybox, I wasn’t able to compile static binaries for openssl
and
cryptsetup
. In this case you need to walk the dependency tree by yourself
with the ldd
command-line utility. Don’t forget that libraries (.so
files)
also have dependencies.
Have a look at my init script, it’s quite simple:
The initramfs
file lists the needed files:
If you use directly my code, don’t forget to make bb
to make sure the init
file is copied at the right place.
Keruspe helped me a lot on this part. For some
reason, the initramfs
file is almost never shown in the existing guides, and
everybody seem to copy all the files by hand. Tedious.
The busybox script drops you to a shell if something goes wrong. This is tremendously helpful to inspect the contents of the initramfs (are all the libraries available at the right path?) and to check if everything is mounted correctly.
The following documents have been of great help
One of the few articles which mention the initramfs_list
config file
http://landley.net/writing/rootfs-howto.html
The initramfs_list
file is also mentionned in the kernel documentation (in
Documentation/filesystems/ramfs-rootfs-initramfs.txt
, section Populating
initramfs
Configure your kernel
The next step is quite simple.
Make sure the following options are enabled:
EFI_STUB
(Processor type and features -> EFI runtime service support -> EFI stub support)CRAMFS
(File systems -> Misc. File systems -> Compressed ROM file system support)
Then go to General setup and configure Initial RAM filesystem and RAM disk (initramfs/initrd) support
Enter the path of your initramfs
.
Now compile your Kernel.
Make sure CRAMFS
is set. It made we waste a few days.
If you’ve done something wrong, you’ll hit a Kernel Panic.
Don’t Panic.
Configure gummiboot
Mount the boot partition in /boot
and run:
gummiboot install
It will copy the needed files to your external device.
Then copy the kernel image on the device:
kernel-install add <kernel-version> arch/x86/boot/bzImage
Now check the files in /boot/loader/
to make sure everything is OK. You
don’t have any option to pass to the kernel, the initramfs will be used. You
may want to pass the quiet
option once your system boots correctly for an
uncluttered boot.
For more information about Gummiboot:
Enjoy
As they say in the exherbo install guide
reboot && sacrifice a goat && pray
You should be prompted the key passwords. Once you see the prompt, you can safely remove the boot device, its contents are loaded in RAM.