Linux – How to automatically import a non-root encrypted ZFS pool on boot-up

bootencryptionlinuxsystemdzfs

I’m running an updated version of Arch Linux with the stock kernel, version 4.9.6, and ZoL version 0.7.0, and I want to import an encrypted non-root pool on boot. The pool is a raid 1 mirror.

The encrypted containers were made via:

cryptsetup -y -v luksFormat /dev/nvme0n1p3

and

cryptsetup -y -v luksFormat /dev/nvme1n1p3

I used the same passphrase for each.

I can manually open the containers and import the pool via:

cryptsetup open /dev/nvme0n1p3 enc0  
cryptsetup open /dev/nvme1n1p3 enc1   
zpool import -d /dev/mapper zeb

The cryptosetup commands prompt me for, and accept, my password.

My mkinitcpio file contains the systemd, zfs, and sd-encrypt hooks. It also contains the modules dm_mod, dm_crypt, aes_x86_64 and raid1. These are somewhat of a shot in the dark based on bit’s and pieces I’ve found online.

I’m using systemd-boot, but it seems like the key lies in getting the mkinitcpio configuration set up correctly. My boot partition is not encrypted.

Again, my only goal here is to automatically (with prompt for passphrase) import my encrypted ZFS pool on boot. I have no problem doing this with non-encrypted pools.

Best Answer

I don't have 50 reputation to comment, so I'll post my questions here. Your rootfs is not encrypted? So when you boot, you don't receive any cryptsetup prompts? If you don't receive any passwords promts, I'd suggest you unpacking your initramfs and modify init file, and add the following lines, somewhere after mounting rootfs. cryptsetup open /dev/nvme0n1p3 enc0 && cryptsetup open /dev/nvme1n1p3 enc1 && zpool import -d /dev/mapper zeb

Sometime ago I needed to add remote ssh unlock of LUKS-encrypted ROOTFS with ZFS on a remote server. I have no way but modify init file and add dropbear to it, launch it, and modify cryptsetup command to accept password from fifo. I made a bash script for that, so when I update initramfs, this bash script unpacks initramfs, put my changes, and packs it back. But I am using gentoo and it's beautiful genkernel. Genkernel includes hooks for ZFS and cryptsetup, if you specify it. I don't know how it is in arch linux, maybe you have also an option to build kernel with genkernel/dracut, that way you can easily include cryptsetup and zfs hooks in initramfs, if it is not already included. Anyway it is easily doable by modifying init file, try it and post your results here. your initramfs maybe compressed using different methods, so find how to uncompress it in archlinux. On my side, I modified genkernel to generate it as cpio, and use cpio commands to unpack/pack back.

UPDATE: You need to edit your mkinitcpio.conf and add 2 hooks "encrypt zfs" before "filesystems" in HOOKS next you need to define your luks devices, needed for unlocking in /etc/crypttab.initramfs # (google crypttab) This file will be included in next generation of initramfs, so now we are unlocking them at least. Maybe ZFS will do autoimport on next reboot, but if not, do the following:

create file /usr/lib/initcpio/install/zfsmount

#!/bin/bash

build() {
    add_runscript
}

create file /usr/lib/initcpio/hooks/zfsmount

#!/usr/bin/ash

run_hook() {
zpool import mypool
}

and in mkinitcpio.conf add "zfsmount" in HOOKS somewhere in the end, before or after "filesystems"

And, of course, regenerate your initramfs with mkinitcpio

Refs: https://wiki.archlinux.org/index.php/Installing_Arch_Linux_on_ZFS

https://wiki.archlinux.org/index.php/mkinitcpio

Related Question