openzfs / zfs

OpenZFS on Linux and FreeBSD
https://openzfs.github.io/openzfs-docs
Other
10.42k stars 1.72k forks source link

Support non-automatic loading of keys for encrypted datasets on boot #15840

Open thedeadliestcatch opened 7 months ago

thedeadliestcatch commented 7 months ago

Describe the feature would like to see added to OpenZFS

At the moment, all encrypted datasets are mounted/have their keys loaded automatically on boot time. This interrupts boot when the key is not available or a passphrase is required to "open" the dataset.

Ideally, some property should be added, ex. "noauto", so that the key is only manually loaded and the dataset is ignored during boot.

How will this feature improve OpenZFS?

It will prevent systems with encryption-at-rest from having the boot process interrupted when the keys are loaded via a manual or more complex system that depends on external tooling.

Additional context

This can be observed by creating a password-based encrypted dataset in a system coexisting with datasets encrypted using key files.

robn commented 7 months ago

Is it enough to set canmount=off or canmount=noauto on the datasets you don't want mounted?

thedeadliestcatch commented 7 months ago

It doesn't seem like that helps @robn , the loading of the keys is not done via mount triggers.

thedeadliestcatch commented 7 months ago

To document this further, for example on Ubuntu (development release):

There is a global setting in /etc/default/zfs:

# Run `zfs load-key` during system start?
ZFS_LOAD_KEY='yes'

From /etc/init.d/zfs-load-key:

# Load keys for all datasets/filesystems
do_load_keys()
{
    zfs_log_begin_msg "Load ZFS filesystem(s) keys"

    "$ZFS" list -Ho name,encryptionroot,keystatus,keylocation |
        while IFS=" " read -r name encryptionroot keystatus keylocation; do
        if [ "$encryptionroot" != "-" ] &&
            [ "$name" = "$encryptionroot" ] &&
            [ "$keystatus" = "unavailable" ] &&
            [ "$keylocation" != "prompt" ] &&
            [ "$keylocation" != "none" ]
        then
            zfs_action "Load key for $encryptionroot" \
                "$ZFS" load-key "$encryptionroot"
        fi
    done

    zfs_log_end_msg 0

    return 0
}

One would assume that the key loading is only automated for datasets with keylocation != prompt.

I will have to copy over the scripts from another Debian system to verify, since the above is not the stable release. I will then write another comment or update this one. I can confirm though that with a dataset that has keylocation=prompt, for a Debian based system (replicated also with Proxmox, latest stable release), init process is halted waiting for the user input.

I will report back.

robn commented 7 months ago

Right, I see. That's OpenZFS' etc/init.d/zfs-load-key.in, which of course distros are under no obligation to use but at least we could make some change if necessary.

It looks like that's doing load-key if keylocation is not prompt or none, that is, it asserts a real location. Is that right?

If that's the case, and you do have a manual/external process, I think probably you should set keylocation=none and then in your separate process, use zfs load-key -L <keylocation> to specify the location directly at the proper time. It seems like it doesn't make a lot of sense to add a special property to say "don't do this thing I asked you to do".

If that's not the case, well, tell me more!

thedeadliestcatch commented 7 months ago

Let me revisit the issue this week. I believe some Debian based systems are rolling out with an incomplete set of scripts. The OpenZFS zfs-load-key.in behavior is actually spot on to avoid prompt-based key loading.

f1d094 commented 6 months ago

We currently run encrypted zfs for the rpool (mirrorred) and data pools (RAIDZ2). The rpools are password based and will wait at boot time for the password, and these can be loaded remotely using dropbear-intramfs. The datapools are using binary keys and are started using a systemd service which waits for the binary key to be loaded. None of this required any special magic. Simply systemctl disable zfs-load-key.service and setup your own systemd services for what you want to load when...

f1d094 commented 6 months ago

Our systems are currently debian bookworm with a couple Ubuntu systems, but each is otherwise similarly configured.

voidzero commented 3 months ago

It's not possible to set keylocation=none on an encrypted filesystem:

# zfs set keylocation=none zroot/enc
cannot set property for 'zroot/enc': keylocation must not be 'none' for encrypted datasets

Setting it to canmount=noauto would be my preferred way to skip the automatic loading of the filesystem at boot, but on second thought this might make the zfs mount -a command ambiguous.

Currently, any linux distribution that loads all the filesystems with zfs load-key -a cannot be told to skip any individual filesystem. I'd be very happy if this can be overridden from zfs in some way - I want a prompt for some filesystems, but not load them at boot time.

voidzero commented 2 months ago

I just discovered that NixOS has the following setting: boot.zfs.requestEncryptionCredentials

That really made my day.