Geli

This is a tutorial to guide you through the setup of a fully encrypted laptop with FreeBSD, Geli, and a separate boot/key flash drive.


Requirements

You need the following items:

  • one laptop

  • one robust USB flash drive -- with robust I mean really a weather proof, shock proof USB flash drive. You will have to carry this around with your keys all the time.


Preparations

We start with a running installation of FreeBSD. If you do not know how to do that, please follow the Handbook and install the current version of FreeBSD onto your laptop.

If you prefer not to install FreeBSD first, just boot the laptop with a second USB flash drive that contains `memstick.iso` and select `Shell` in the start menu to get to a working shell for later use.


USB Key

The USB flash drive acts as a boot loader for the encrypted laptop and at the same time as the holder of one of the keys required in Geli (the other one will be your personal passphrase).


  1. Plugin your USB flash drive

  2. (Optional) Erase everything on the drive by typing

# dd if=/dev/zero of=/dev/da0 bs=512 count=60088320

You have to adjust the count line by the number of blocks available on the USB drive. Check that by looking at the end of the messages log:

# tail /var/log/messages

The first line above overwrites everything with zeros. Finally using the latter command, you overwrite everything again with random numbers to make it hard for an attacker to distinguish which part is random and which part is actually encrypted.

  1. Create partitions:

# gpart create -s gpt da0

# gpart add -t efi -s 40M da0

# gpart add -t freebsd-ufs da0


# newfs_msdos -F 32 -c 1 /dev/da0p1

# newfs -U -L Key /dev/da0p2

  1. Mount the USB drive and install FreeBSD on it:

# mount /dev/da0p2 /mnt

# cd /usr/src

# make DESTDIR=/mnt installworld

# make DESTDIR=/mnt distribution

# make DESTDIR=/mnt installkernel

  1. Install the EFI boot loader code:

# mount -t msdosfs /dev/da0p1 /mnt1

# mkdir -p /mnt1/EFI/BOOT

# cp /mnt/boot/loader.efi /mnt1/EFI/BOOT/BOOTX64.efi

# umount /mnt1

  1. Put FreeBSD partition into fstab for mounting correctly:

# echo "/dev/da0p2 / ufs rw 1 1" >> /mnt/etc/fstab

  1. Copy the system to the USB drive for later installation on the new laptop:

# cp kernel.txz /mnt/root/

# cp base.txz /mnt/root/

  1. Unmount flash drive:

# umount /mnt


Laptop

Now, we are ready to install FreeBSD on our Laptop from the newly created USB flash drive.


  1. Plugin your USB flash drive and boot the laptop.

  2. Use `root` to log in (without any password).

  3. Delete the harddisk:

# dd if=/dev/random of=/dev/ada0 bs=1m

  1. Partition harddisk:

# gpart create -s gpt ada0

# gpart add -t freebsd-swap -b 1m -s 8g nvd0

# gpart add -t freebsd-zfs -a 1m nvd0

  1. Encrypt swap partition:

# echo "/dev/ada0p1.eli none swap sw 0 0" >> /mnt/etc/fstab

  1. Encrypt ZFS partition:

# kldload geom_eli

# dd if=/dev/random of=/root/nvd0.key bs=256 count=1

# chmod 400 /root/nvd0.key


# geli init -b -B /root/backup.eli -K /root/ada0.key -s 4096 /dev/ada0p2

# geli attach -k /root/ada0.key /dev/ada0p2

  1. Add ZFS pool:

# zpool create tank /dev/nvd0p2.eli

# zfs create tank/tmp

# zfs create tank/usr

# zfs create tank/usr/home

# zfs create tank/usr/ports

# zfs create tank/usr/ports/distfiles

# zfs create tank/usr/src

# zfs create tank/var

# zfs create tank/var/cache

# zfs create tank/var/cache/pkg

# zfs create tank/var/crash

# zfs create tank/var/db

# zfs create tank/var/db/pkg

# zfs create tank/var/empty

# zfs create tank/var/log

# zfs create tank/var/mail

# zfs create tank/var/run

# zfs create tank/var/tmp

  1. Install FreeBSD on the newly created ZFS pool:

# cd /tank

# unxz -c /root/base.txz | tar xvpf -

# unxz -c /root/kernel.txz | tar xvpf -

  1. Load the keyfile at boot time:

# echo geom_eli_load=\"YES\" >> /boot/loader.conf

# echo geli_ada0_keyfile0_load=\"YES\" >> /boot/loader.conf

# echo geli_ada0_keyfile0_type=\"ada0:geli_keyfile0\" >> /boot/loader.conf

# echo geli_ada0_keyfile0_name=\"/root/ada0.key\" >> /boot/loader.conf

# echo vfs.root.mountfrom=\"zfs:tank\" >> /boot/loader.conf

  1. Additional (optional) settings at boot time for Laptops. The last one requires the respective firmware file in the right location:

# echo autoboot_delay=\"2\" >> /boot/loader.conf


# echo kern.maxproc=\"100000\" >> /boot/loader.conf

# echo kern.ipc.shmseg=\"1024\" >> /boot/loader.conf

# echo kern.ipc.shmmni=\"1024\" >> /boot/loader.conf


# echo hw.psm.trackpoint_support=\"1\" >> /boot/loader.conf

# echo hw.psm.synaptics_support=\"1\" >> /boot/loader.conf


# echo net.inet.tcp.soreceive_stream=\"1\" >> /boot/loader.conf


# echo net.link.ifqmaxlen=\"2048\" >> /boot/loader.conf


# echo cc_htcp_load=\"YES\" >> /boot/loader.conf


# echo cpuctl_load=\"YES\" >> /boot/loader.conf


# echo coretemp_load=\"YES\" >> /boot/loader.conf


# echo acpi_ibm_load=\"YES\" >> /boot/loader.conf


# echo cpu_microcode_load=\"YES\" >> /boot/loader.conf

# echo cpu_microcode_name=\"/boot/firmware/intel-ucode.bin\" >> /boot/loader.conf

  1. Create fstab to mount encrypted harddisk and load swap drive

# echo "/dev/ada0p1.eli none swap sw 0 0" >> /etc/fstab

  1. Set ZFS mountpoints:

# zpool set bootfs=tank tank

# zfs set mountpoint=/ tank

# zfs set mountpoint=/tank/tmp tank/tmp

# zfs set mountpoint=/tank/usr tank/usr

# zfs set mountpoint=/tank/var tank/var

  1. Create rc.conf

# echo zfs_enable=\"YES\" >> /etc/rc.conf

  1. Copy files to ZFS file system

# cp /etc/rc.conf /tank/etc/rc.conf

# cp /etc/fstab /tank/etc/fstab

# cp /boot/loader.conf /tank/boot/loader.conf

  1. Reboot

# reboot