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).
Plugin your USB flash drive
(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.
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
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
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
Put FreeBSD partition into fstab for mounting correctly:
# echo "/dev/da0p2 / ufs rw 1 1" >> /mnt/etc/fstab
Copy the system to the USB drive for later installation on the new laptop:
# cp kernel.txz /mnt/root/
# cp base.txz /mnt/root/
Unmount flash drive:
# umount /mnt
Laptop
Now, we are ready to install FreeBSD on our Laptop from the newly created USB flash drive.
Plugin your USB flash drive and boot the laptop.
Use `root` to log in (without any password).
Delete the harddisk:
# dd if=/dev/random of=/dev/ada0 bs=1m
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
Encrypt swap partition:
# echo "/dev/ada0p1.eli none swap sw 0 0" >> /mnt/etc/fstab
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
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
Install FreeBSD on the newly created ZFS pool:
# cd /tank
# unxz -c /root/base.txz | tar xvpf -
# unxz -c /root/kernel.txz | tar xvpf -
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
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
Create fstab to mount encrypted harddisk and load swap drive
# echo "/dev/ada0p1.eli none swap sw 0 0" >> /etc/fstab
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
Create rc.conf
# echo zfs_enable=\"YES\" >> /etc/rc.conf
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
Reboot
# reboot