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.
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".
While you're in the BIOS, you might want to go ahead and disable the TPM if you have one—I've seen many reports
that it breaks resuming from suspend in FreeBSD.
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:
I'm going to assume your hard drive is called ada0. Let's blow away the current partition
table and write a fresh GPT partitioning scheme.
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.
Notice we didn't create a filesystem this time. That comes in the next section.
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:
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):
Now you can create the root UFS filesystem. Note the .eli extension on the block device
this time:
To complete the partitioning step, the FreeBSD installer expects you to mount your root filesystem at /mnt:
However, there is one very important caveat regarding the boot partition. The bootloader expects everything to be
under a folder called /boot on 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:
(Special thanks to ross at daemon-notes.com for that tidbit.)
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.
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.
Configuring Your BIOS
Partitioning the Disk
gpart show
gpart destroy -F ada0
gpart create -s gpt ada0
gpart add -t efi -l freebsd-efi -a 4k -s 800k ada0
newfs_msdos /dev/gpt/freebsd-efi
mount -t msdosfs /dev/gpt/freebsd-efi /mnt
mkdir -p /mnt/EFI/BOOT
cp /boot/boot1.efi /mnt/EFI/BOOT/BOOTX64.efi
echo BOOTx64.efi > /mnt/EFI/BOOT/STARTUP.NSH
umount /mnt
gpart add -t freebsd-ufs -l freebsd-boot -a 4k -s 1g ada0
newfs -t -U -L bootfs /dev/gpt/freebsd-boot
gpart add -t freebsd-ufs -l freebsd-root -a 4k ada0
GELI Encryption
geli init -b -e AES-XTS -l 256 -s 4096 /dev/gpt/freebsd-root
geli attach /dev/gpt/freebsd-root
newfs -t -U -L rootfs /dev/gpt/freebsd-root.eli
Mounting the Filesystems
mount /dev/gpt/freebsd-root.eli /mnt
mkdir /mnt/bootfs
mount /dev/gpt/freebsd-boot /mnt/bootfs
cd /mnt
mkdir bootfs/boot
ln -s bootfs/boot
Conclusion