Extended Brain Storage

FreeBSD: Full Disk Encryption with UEFI

Posted on February 1, 2017

In order to get rid of systemd on a server, one way may seem to be within the realm of FreeBSD

Note: The system installation process would be the same for either server or a desktop. Obviously, the 3rd party software will make the difference.


This manual deals with the FreeBSD installation with full disk encryption (FDE) and UEFI very briefly. A more detailed and commented approach on “plain” FDE can be found in FreeBSD: Full Disk Encryption.


The process is pretty straightforward as for any other installation including the partitioning step with escaping to shell.

Disk Format and Partitioning

The disk format process WILL DELETE DATA. The first SATA disk (/dev/ada0) will be partitioned using the GPT, as it is recommended to use the GPT for UEFI boot, because some UEFI firmwares do not allow UEFI-MBR boot, more info on uefi.org.

$ gpart create -s gpt ada0

Due to the UEFI firmware, an EFI System Partition (ESP) of 800kiB needs to be created and formatted to FAT (either FAT16 or FAT32).

$ gpart add -t efi -a 4k -s 800k ada0
$ newfs_msdos /dev/ada0p1

Two freebsd slices (aka partitions) the first of 768MB for /boot (large enough to hold two kernels) and the rest for an encrypted /root and swap) can be created on the disk (ada0) as follows:

$ gpart add -t freebsd-boot -a 4k -s 768m ada0
$ gpart add -t freebsd-ufs -a 4k ada0

Partition labelling can be utilised for better reference (survives computer restarts, addition of new disk etc.) as follows:

$ glabel label -v bootld /dev/ada0p1
$ glabel label -v bootfs /dev/ada0p2
$ glabel label -v sysfs /dev/ada0p3

Now, a simple FreeBSD UEFI boot loader needs to be installed as follows:

$ mount -t msdosfs /dev/label/bootld /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

Disk Encryption

Full disk encryption is activated using geli (AES-256, 4096bit key) as follows (if available, the aesni driver can be loaded):

$ kldload aesni
$ geli init -b -s 4096 -l 256 /dev/label/sysfs

Metadata backup can be found in /var/backups/label_sysfs.eli. This file can be copied on a backup medium in order to help restore a corrupted encrypted partition should it occur in the future. Reader discretion advised!

The encrypted partition now needs to be attached using:

$ geli attach /dev/label/sysfs
GEOM_ELI: Device label/sysfs.eli created.

Being attached as /dev/label/sysfs.eli, the decrypted partition can now be modified in order to contain the swap and root partitions as follows (using the BSD partition scheme again):

$ gpart create -s bsd /dev/label/sysfs.eli
$ gpart add -t freebsd-swap -s 2048m /dev/label/sysfs.eli
$ gpart add -t freebsd-ufs /dev/label/sysfs.eli

And again, it is useful to label the partitions accordingly:

$ glabel label -v swapfs label/sysfs.elia
$ glabel label -v rootfs label/sysfs.elib

Now, it is time to format the partitions as follows (the -t flag can be used with newfs to enable TRIM support):

$ newfs -j /dev/label/bootfs
$ newfs -j /dev/label/rootfs

Having each partition formatted, the swap and root partitions be mounted as follows:

$ swapon /dev/label/swapfs
$ mount /dev/label/rootfs /mnt/

Since the FreeBSD boot loader expects its data to reside in the /boot directory of the boot partition, it needs to be mounted under a different directory (e.g. /bootfs) and the /boot directory needs to be “symlinked” to its boot sub-directory as follows:

$ mkdir /mnt/bootfs
$ cd /mnt
$ ln -s bootfs/boot boot
$ mount /dev/label/bootfs /mnt/bootfs
$ mkdir bootfs/boot

The exit command returns back to the installer.

Installation Finalisation

The trickiest part is luckily over. Since the installer expects the root of the filesystem to be mounted in /mnt, which has been just done, it installs the necessary files (base, kernel, libs, ports etc.) there. Consequently, it prompts for further details necessary to finish the installation process (such as root password, network interface setup, DNS setup, services setup, user setup, time zones).

Unfortunately, the installer does not make sure the proper setup is in the /etc/fstab and /boot/loader.conf files. Therefore, before system restart, a manual configuration needs to be performed.

If the /dev directory is suddenly empty (null) and so is the /mnt directory like the following examples:

$ ls -lA /dev
total 8
-rw-r--r--  1 root  wheel  8 Jan  1 00:00 null
$ ls -lA /mnt
total 0

the installer needs to be completed by the exit command. And on the very last screen instead of “Reboot”, the “Live CD” option needs to be selected.

User root can now log in (with empty password) in order to manually configure the mount points in /etc/fstab as follows:

$ echo "# Device           Mountpoint  FStype  Options     Dump  Pass#" > /mnt/etc/fstab
$ echo "/dev/label/bootfs  /bootfs     ufs     rw,noatime  1     1" >> /mnt/etc/fstab
$ echo "/dev/label/swapfs  none        swap    sw          0     0" >> /mnt/etc/fstab
$ echo "/dev/label/rootfs  /           ufs     rw,noatime  1     1" >> /mnt/etc/fstab

and boot loader parameters as follows:

$ echo 'aesni_load="YES"' > /mnt/boot/loader.conf
$ echo 'geom_eli_load="YES"' >> /mnt/boot/loader.conf
$ echo 'geom_eli_passphrase_prompt="YES"' >> /mnt/boot/loader.conf
$ echo 'vfs.root.mountfrom="ufs:/dev/label/rootfs"' >> /mnt/boot/loader.conf

Finally, the system can be restarted now.

It may be useful to visit the FreeBSD: Post Installation Steps.

Some notes on FreeBSD UEFI Secure Boot can be found on: freebsdfoundation.org

Tags: #FreeBSD #security #encryption #FDE #systemd #UEFI #MBR #GPT #UFS #ZFS

⏴ Previous Post Next Post ⏵