Working on a Geli-Encrypted ZFS Pool from a Live-CD or Memstick

Imagine you are experimenting with ZFS. You might render your system unbootable, e.g. because you misconfigured a mountpoint property. Let’s fix this.

Note: In this post, I’ll refer to the following setup which is the one bsdinstall generates if you tick the encryption checkbox during installation.

For the sake of simplicity, we’ll assume that you have set-up a stripe on just one disk /dev/ada0. If you have set-up a mirror, you’ll have to decrypt the mirrored partitions of the ZFS pool as well to operate on it.

Who’s who

You can show the partitions on your drive using gpart:

gpart show ada0
### output ###
=>       34  419430333  ada0  GPT  (200G)
         34       1024     1  freebsd-boot  (512K)
       1058    4194304     2  freebsd-zfs  (2.0G)
    4195362    8388608     3  freebsd-swap  (4.0G)
   12583970  406846397     4  freebsd-zfs  (194G)

The number in the ada0 column is the partition you can find ad /dev/ada0p<number>.

  • ada0p1: bootstrapping code to boot off bootpool.
  • ada0p2: the ZFS pool bootpool. This one is not encrypted because Geli needs the kernel’s crypto framework. Hence, bootpool contains
    • The kernel with modules to mount ZFS, support geli, etc.
    • The geli decryption key for the partition containing zroot. Don’t worry, it’s protected by your passphrase through symetric encryption.
  • ada0p3: swap space – probably also encrypted if you checked that checkbox, too.
  • ada0p4: the geli-encrypted ZFS pool zroot.
    zroot contains at least one dataset with / as mountpoint (usually zroot/ROOT/default).

More detailed and accurate information can be found on the man-page section about BOOTSTRAPPING.

Decrypting the pool

Assuming you want to fix things on zroot, you’ll need to decrypt ada0p4 first. For decryption, you need the key-file. So let’s mount bootpool to /tmp/bootpool.

mkdir /tmp/bootpool
zfs import # lists the available pools to import. bootpool should be listed there
zfs import -N -f bootpool # forcefully import bootpool, but don't mount it.
zfs set mountpoint=/tmp/bootpool bootpool
zfs mount bootpool

The keyfile should be located at /tmp/bootpool/boot/encryption.key Now you are able to decrypt ada0p4:

geli attach -k /tmp/bootpool/boot/encryption.key /dev/ada0p4

Note: If you have a ZFS mirror or raidz set-up, you’ll have to decrypt the other partitions before importing the pool.

Importing the pool

zfs import -N -f zroot # import zroot without mounting it

Note: Be careful when mounting datasets of zroot. They have their mountpoints set to locations that aleady contain files on the live-system, e.g. zroot/ROOT/default‘s mountpoint is / but the livesystem is mounted at /, too. If you screw it up, reboot and start over.

Congratulations, you can now operate on your pool from the live-system!