Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZFS: Request credentials only for selected pools #93395

Merged
merged 1 commit into from Aug 15, 2020
Merged

Conversation

hmenke
Copy link
Member

@hmenke hmenke commented Jul 18, 2020

This change introduces more fine-grained requestEncryptionCredentials.
While previously when requestEncryptionCredentials = true, the
credentials for all imported pools and all datasets in these imported
pools were requested, it is now possible to select exactly the pools and
datasets for which credentials should be requested.

It is still possible to set requestEncryptionCredentials = true, which
continues to act as a wildcard for all pools and datasets, so the change
is backwards compatible.

Motivation for this change

Fixes #93389

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

@hmenke
Copy link
Member Author

hmenke commented Jul 18, 2020

Comment on lines 520 to 534
${optionalString cfgZfs.requestEncryptionCredentials ''
${optionalString (if isBool cfgZfs.requestEncryptionCredentials
then cfgZfs.requestEncryptionCredentials
else cfgZfs.requestEncryptionCredentials != []) ''
${packages.zfsUser}/sbin/zfs list -rHo name,keylocation ${pool} | while IFS=$'\t' read ds kl; do
(case "$kl" in
(${if isBool cfgZfs.requestEncryptionCredentials
then "" # requestEncryptionCredentials was true, so we loop over all (we insert no check)
else ''
if ! echo '${concatStringsSep cfgZfs.requestEncryptionCredentials "\n"}' | grep -qx "$ds"; then
continue
fi
''}
case "$kl" in
Copy link
Member Author

@hmenke hmenke Jul 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't tested this bit yet, because I only have a single pool and this only runs for non-root pools. I plan to do this in the next few days in a VM.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tested this in a VM with one extra pool and it works well. I've also had a look at nixos/tests/zfs.nix, whether there is an easy way to test this functionality but it doesn't look like it is possible to perform reboots of the test VMs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is actually possible

server.crash()

Do you want to implement that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is shutdown() as well as start().

@hmenke hmenke force-pushed the zfs branch 2 times, most recently from 6cd5d09 to 6b5134e Compare July 21, 2020 05:46
@hmenke
Copy link
Member Author

hmenke commented Jul 21, 2020

@Mic92 Thanks again for your input. This is now ready for the next round of review (or merge).

@Mic92
Copy link
Member

Mic92 commented Jul 21, 2020

All those should not exercise encryption though:

@GrahamcOfBorg test zfs.stable zfs.unstable zfs.installer

This change introduces more fine-grained requestEncryptionCredentials.
While previously when requestEncryptionCredentials = true, the
credentials for all imported pools and all datasets in these imported
pools were requested, it is now possible to select exactly the pools and
datasets for which credentials should be requested.

It is still possible to set requestEncryptionCredentials = true, which
continues to act as a wildcard for all pools and datasets, so the change
is backwards compatible.
${packages.zfsUser}/sbin/zfs list -rHo name,keylocation ${pool} | while IFS=$'\t' read ds kl; do
(case "$kl" in
(${optionalString (!isBool cfgZfs.requestEncryptionCredentials) ''
if ! echo '${concatStringsSep "\n" cfgZfs.requestEncryptionCredentials}' | grep -qFx "$ds"; then
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realized another corner case that I have fixed now. We need the -F flag for grep to not interpret the string as a regex because we only want exact matches. It is unlikely that users have . or other special characters in their dataset names, but they are allowed by ZFS and we should account for that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this shouldn't be done with grep like this. Instead, it seems like we ought to have two different code blocks: One for if it's a bool, and one for if it's a list. If it's a bool, then use the old code. If it's a list, then pluck all the elements of the list whose names begin with "${pool}/" and put load-key commands for each of them. This can be done at Nix eval time without annoying bash-isms, and doesn't require regex'ing every dataset against every list element on boot.

Copy link
Member

@Mic92 Mic92 Aug 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ElvishJerricco I don't think that would work. you still need to figure out at runtime if systemd-ask-password can be used.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After thinking a bit about it using grep here is the method that requires the least amount of code.

@Mic92 Mic92 merged commit 7acb961 into NixOS:master Aug 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ZFS: Request encryption credentials only for selected pools and datasets
3 participants