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.
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.
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.
I’ve generated two random keyfiles with
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.
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.
For a regular disk, partition as you will.
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:
nodiratimeto disable access time logging
data=writebackto reduce writes
discardif you have enabled
Install your system
You’re now able to install the base system. Don’t forget to put the mount options in your
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.
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,
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
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:
init.bb on github
initramfs file lists the needed files:
initramfs on github
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
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
Now compile your Kernel.
CRAMFS is set. It made we waste a few days.
If you’ve done something wrong, you’ll hit a Kernel Panic.
Mount the boot partition in
/boot and run:
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:
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.