Setting up ZFS with native encryption

From Alpine Linux

This is a guide for creating and auto-mounting an encrypted ZFS drive or partition on an existing encrypted alpine linux system, using ZFS's own encryption capabilities. If you want to make a fresh install with the root partition on ZFS, see Root on ZFS with native encryption.

The system will be encrypted when powered off but will not require you to type an extra password at boot, since it uses a key stored on the encrypted root partition. Alternative options are also given, such as prompting for a password at boot rather than storing the key on the root drive. The example in this guide is modeled around creating a ZFS filesystem to be used as a user's home directory, but it can be trivially modified to create a filesystem for other purposes.

Preparation

Every command in this guide should be run as root.

   apk update
   apk add zfs zfs-lts  # install the utilities
   modprobe zfs         # load the kernel modules
   mdev -s              # make sure the device nodes are present

Create an encryption key

This section can be skipped if you intend to unlock the drive by typing a password rather than unlocking automatically. You should use a password instead if your root partition is not encrypted. The location "/etc/home.key" can be anything.

   dd if=/dev/random of=/etc/home.key bs=32 count=1
   chmod 600 /etc/home.key

IMPORTANT: Make sure you don't lose this key by overwriting your root filesystem or anything like that. You might want to store a copy of it on an encrypted USB drive, for instance.

ZFS setup

Create the zpool

Replace `/dev/sd...` with the name of the disk or partition where you would like to make the zfs filesystem, such as `/dev/nvme0n1` or `/dev/sda1`. If you would like to be prompted for a password at boot rather than using the key as generated above, then replace `-O keylocation=file:///etc/home.key -O keyformat=raw` with `-O keylocation=prompt -O keyformat=passphrase`. The name "homepool" can be anything.

   zpool create -o ashift=12 -O acltype=posixacl -O compression=lz4 \
    -O dnodesize=auto -O normalization=formD -O relatime=on -O xattr=sa \
    -O encryption=aes-256-gcm -O keylocation=file:///etc/home.key -O keyformat=raw \
    -O mountpoint=none homepool /dev/sd...

After completing this, confirm that the pool has been created:

   zpool status

Should return something like:

     pool: homepool
    state: ONLINE
   config:
   
           NAME        STATE     READ WRITE CKSUM
           homepool    ONLINE       0     0     0
             sd...     ONLINE       0     0     0
   
   errors: No known data errors

Create and mount the filesystem

   zfs create -o mountpoint=/home/username homepool/username
   chown username:username /home/username  # likely unnecessary if not creating a homedir

Set up the services to auto-mount the new filesystem

   rc-update add zfs-import    # import existing zpools
   rc-update add zfs-load-key  # load the encryption keys
   rc-update add zfs-mount     # mount the filesystems

Finally,

   reboot