Starting with FreeBSD 11 the loader and kernel can be stored on an encrypted partition, which offers new possibilities of using full disk encrypted ZFS.
This document describes the manual installation of FreeBSD 11.1 on ZFS, using full disk encryption, including encrypted swap space.
In the following example I used my trustworthy HP N40L microserver to install FreeBSD 11.1 on a SanDisk 240 GB SSD attached to the on-board SATA bus, so that the four internal SATA enclosures can be used to put large data drives in. This explains the use of ada4
as the name of the internal SSD, as the discs in the 4 bay SATA enclosure are numbered from ada0
to ada3
. It is important to set the drive order correctly in the BIOS and have the system boot from USB or the SSD accordingly. That way you can have the system boot from a USB flash drive while installing, whereas as soon as you remove the USB flash drive, the system will automatically boot from the internal SSD.
FreeBSD-11.1-RELEASE-amd64-memstick.img
from a FreeBSD mirror web site, e.g.sudo dd if=FreeBSD-11.1-RELEASE-amd64-memstick.img of=/dev/diskXXX bs=64k
/dev/diskXXX
to whatever device your USB flash drive actually isada4
with your actual device!gpart destroy -F ada4
gpart create -s gpt ada4
boot0
, which makes it easy to address that partition later on. 512 KB is large enough.-a 4K
or -a 1m
to the gpart
statements below. In my tests however for that particular kind of server and SSD it showed no difference in performance, probably because due to encryption I/O is rather CPU bound.gpart add -l boot0 -t freebsd-boot -s 512K ada4
swap0
. As the machine contains 16 GB of RAM, I use swap space twice the size of RAM.gpart add -l swap0 -t freebsd-swap -a 1m -s 32G ada4
root1
and just use the remaining space on your drive to create one single root partition root0
. We will however create both root partition, but only use the first one for this tutorial.gpart add -l root0 -t freebsd-zfs -s 200883180 ada4
gpart add -l root1 -t freebsd-zfs -s 200883180 ada4
ada4p4
of course:gpart show ada4
=> 40 468877232 ada4 GPT (224G) 40 1024 1 freebsd-boot (512K) 1064 984 - free - (492K) 2048 67108864 2 freebsd-swap (32G) 67110912 200883180 3 freebsd-zfs (96G) 267994092 200883180 4 freebsd-zfs (96G)
Now you have to install the bootcode onto the boot partition ada4p1
. In our case we have to use gptzfsboot
as we want to boot from a ZFS file system which resides on a disk using GPT:> gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada4
partcode written to ada4p1
bootcode written to add4
-g
tells the boot loader where to find the boot partition. As our boot partition is also encrypted, the boot loader has no means of deciding what partition is the actual boot
partition, as without the password it cannot look into the partitions’ content.geli init -l 256 -g -b /dev/gpt/root0
geli attach /dev/gpt/root0
zpool
named RPool
zpool create -m none RPool /dev/gpt/root0.eli
zfs set atime=off RPool
zfs set checksum=on RPool
zfs create RPool/ROOT
zfs create -o mountpoint=/tmp/mnt/RPool RPool/ROOT/default
zfs create -o mountpoint=/tmp/mnt/RPool/tmp -o setuid=off -o exec=on RPool/tmp
zfs create -o mountpoint=/tmp/mnt/RPool/usr RPool/usr
zfs create -o mountpoint=/tmp/mnt/RPool/usr/local RPool/usr/local
zfs create -o mountpoint=/tmp/mnt/RPool/usr/ports RPool/usr/ports
zfs create -o mountpoint=/tmp/mnt/RPool/usr/src RPool/usr/src
zfs create -o mountpoint=/tmp/mnt/RPool/var RPool/var
zfs create -o mountpoint=/tmp/mnt/RPool/var/log RPool/var/log
zfs create -o mountpoint=/tmp/mnt/RPool/var/mail RPool/mail
/tmp/mnt/RPool
:cd /tmp/mnt/RPool
kernel
and base
. I opted for an additional installation of src
, which contains the sources.unxz -c /usr/freebsd-dist/kernel.txz | tar xpvf -
unxz -c /usr/freebsd-dist/base.txz | tar xpvf -
unxz -c /usr/freebsd-dist/src.txz | tar xpvf -
chroot /tmp/mnt/RPool
loader.conf
echo 'aesni_load="YES"' > /boot/loader.conf
echo 'geom_eli_load="YES"' >> /boot/loader.conf
echo 'zfs_load="YES"' >> /boot/loader.conf
echo 'kern.geom.label.disk_ident.enable="1"' >> /boot/loader.conf
echo 'kern.geom.label.gptid.enable="1"' >> /boot/loader.conf
echo 'vfs.root.mountfrom="zfs:RPool/ROOT/default"' >> /boot/loader.conf
rc.conf
echo 'zfs_enable="YES"' > /etc/rc.conf
/etc/rc.conf
, /etc/resolv.conf
or other configuration files accordingly. You can also opt to do that later after you booted into your freshly installed system.exit
zfs umount -a
cd
zfs set -o mountpoint=legacy RPool/ROOT/default
zfs set -o mountpoint=/tmp RPool/ROOT/tmp
zfs set -o mountpoint=/usr RPool/ROOT/usr
zfs set -o mountpoint=/usr/local RPool/ROOT/usr/local
zfs set -o mountpoint=/usr/ports RPool/ROOT/usr/ports
zfs set -o mountpoint=/usr/src RPool/ROOT/usr/src
zfs set -o mountpoint=/var RPool/ROOT/var
zfs set -o mountpoint=/var/log RPool/ROOT/var/log
zfs set -o mountpoint=/var/mail RPool/ROOT/var/mail
Now we are ready to boot into our installed system:reboot
passwd
keymap="de"
to your /etc/rc.conf
As we didn’t setup our encrypted swap space during the system installation, now is a good time to do that:geli onetime -d -e AES-XTS -l 256 -s 4096 /dev/gpt/swap0
We also need to add an entry to /etc/fstab
so next time our swap space is activated automatically
# /etc/fstab # device mountpoint fstype mountoptions dump pass # /dev/gpt/swap.eli none swap sw 0 0
and have FreeBSD use the configured swap space for this incarnationswapon -a
Check whether the swap space is actually in use:swapinfo
should give you something like this:
Device 1K-blocks Used Avail Capacity /dev/gpt/swap0.eli 33554432 0 33554432 0%
After you have set up your network connection, you can install the Ports Collection withportsnap fetch
portsnap extract
and install all the other software packages you need. This works exactly as with any other FreeBSD installation you may have installed and configured already earlier.
When you add additional drives to your system, it is important you also do this in a similar fashion to the boot and root drives earlier.
For this example I use ada0
, which is the drive inserted into the first bay.
gpart destroy -F ada0
gpart create -s gpt ada0
gpart add -t freebsd-zfs -l data0 -a 4k ada0
geli init -b -s 4096 -l 256 /dev/gpt/data0
geli attach /dev/gpt/data0
zpool create -m none datapool0 /dev/gpt/data0.eli
zpool create -m none datapool0 mirror /dev/gpt/data0a.eli /dev/gpt/data0b.eli