FreeBSD: Full-Disk Encryption + UEFI

How to install FreeBSD using a GELI-encrypted UFS root partition on UEFI.

After the almost comical stream of OS X security bugs recently, I dug up my old ThinkPad T530 and installed FreeBSD as my
primary OS. Since a laptop is portable and easily stolen, full-disk encryption is a must. There are plenty of resources
online for setting up an encrypted ZFS root partition on FreeBSD, but I still prefer UFS on desktop setups. Don't get
me wrong—ZFS is my top choice for any kind of RAID situation—but I've always found it a bit overkill (and RAM intensive)
for a single-disk OS partition. And I definitely wanted UEFI for that native resolution console at boot time. :-)

There were hardly any guides online for installing FreeBSD to a GELI-encrypted UFS partition, and there was even
less information about how to get such a setup working with UEFI. However, I eventually figured it out,
so here's a quick how-to in case another discerning daemon finds his way here.

Configuring Your BIOS

I'm not sure if "BIOS" is the right word anymore, but you know what I mean. Reboot your computer and spam the
F2 or Delete key or whatever magic incantation you need in order to get to your BIOS settings. You'll definitely
need to disable Secure Boot, since it doesn't work yet (and why
would you want it, anyway?). On my ThinkPad, I also had to disable all the compatibility boot options. Most
of these options were labeled "CSM".

Partitioning the Disk

At this point, I'm assuming that you've successfully booted the FreeBSD installation media via UEFI. If the installer
won't boot in pure UEFI mode, then you're probably out of luck—but the GELI encryption section of this guide might still
be helpful to you.

Once you get to the partitioning step in the FreeBSD installer, choose the Shell option
to manually partition the disks. The first thing you'll need to do is figure out which block device corresponds to your hard
drive. To show the current disk layout, just run:

The first partition you'll need is an EFI System Partition. This is a small FAT-formatted partition from which
your computer's firmware will boot the operating system. It just needs to be large enough to hold the FreeBSD UEFI
bootloader—800 KB is plenty.

Your computer's UEFI firmware should look for a boot executable in a specific location on this partition. You'll need
to mount the partition, create the folder hierarchy, and copy over the FreeBSD UEFI bootloader from the install media:

Next, you'll need a boot partition. Confusing, I know. The EFI partition you just created contains
a small UEFI bootloader. However, this bootloader's only purpose is to look for a UFS (or ZFS) partition which contains the real
FreeBSD bootloader, and then run it. The boot partition will also contain the kernel, boot configuration, and kernel modules.

This partition will have to remain unencrypted, since the bootloader needs to be able to find a kernel to execute. There
are some guides online for storing your boot partition and kernel on an external USB stick to achieve a fully encrypted system,
but I'm not that paranoid.

Anyway, create the boot partition. 1 GB is probably overkill for the FreeBSD kernel, but I've got plenty of disk space. If
you have an SSD, be sure to pass the -t flag to newfs to enable
TRIM support.

Finally, create a partition for your root filesystem. I don't bother with swap for a desktop machine, so I'll just use
the entire remainder of the disk.

gpart add -t freebsd-ufs -l freebsd-root -a 4k ada0

Notice we didn't create a filesystem this time. That comes in the next section.

GELI Encryption

Now it's time to create your encrypted partition! FreeBSD's framework for disk encryption is called GELI.
Basically, it's a layer in between the filesystem and the physical disk that manages encryption/decryption of the data blocks. Creating your
GELI root partition is a one-liner:

geli init -b -e AES-XTS -l 256 -s 4096 /dev/gpt/freebsd-root

The -b flag is critical, as it allows the encrypted partition to be used as a root filesystem.

This will prompt you for an encryption passphrase. Use a good one! You will have to enter this passphrase every time you boot
your computer (and if you forget it, you're SOL). Once that's done, issue the following command to unlock the drive (it will
prompt you for the passphrase you just created):

geli attach /dev/gpt/freebsd-root

Now you can create the root UFS filesystem. Note the .eli extension on the block device
this time:

newfs -t -U -L rootfs /dev/gpt/freebsd-root.eli

Mounting the Filesystems

To complete the partitioning step, the FreeBSD installer expects you to mount your root filesystem at /mnt:

mount /dev/gpt/freebsd-root.eli /mnt

However, there is one very important caveat regarding the boot partition. The bootloader expects everything to be
under a folder called /booton the boot partition itself. Therefore, for the FreeBSD installer
to work, we'll need to mount the boot partition under a separate directory and create a symlink:

Finally, you'll need to create an fstab and loader.conf file for
your system to be bootable. At this stage in the installation, you can place these under /tmp/bsdinstall_*
and the installer will copy them to the target filesystem appropriately.

At this point, you're finished! Exit the shell to continue the FreeBSD installation.

Conclusion

Once the installer has finished, you may want to open a shell before you reboot, just to make sure your fstab
and loader.conf files look correct. With any luck, your computer's UEFI firmware will be able to find your
bootloader and launch the FreeBSD kernel.

When your system reboots, it will prompt you for your encryption passphrase during the boot process. The prompt is easy to miss
during the text-scrolling frenzy, so if it seems hung, just type your passphrase and press enter.

As always, contact me via email or ping me on Twitter
with any questions or issues you have.