Page MenuHomeFreeBSD

Add zfskeys script to /etc/rc.d for auto-loading zfs keys
ClosedPublic

Authored by ltning-freebsd_anduin.net on Apr 27 2021, 6:55 PM.

Details

Summary

ZFS in 13 supports encryption, but for the use case where keys are
available in plaintext on disk there is no mechanism for automatically
loading keys on startup.

This script will, by default, look for any dataset with encryption and
keylocation prefixed with file://. It will attempt to unlock, timing
out after 10 seconds for each dataset found.
User can optionally specify explicitly which datasets to attempt to
unlock.

Also supports (optionally by force) unmounting filesystems and unloading
associated keys.

Sponsored-By: Modirum

Test Plan

Tested with a variety of dataset names, including ones with spaces.
Tested with zero, one, and many datasets both by autodetection and
explicitly specified.

Diff Detail

Repository
R10 FreeBSD src repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

dteske requested changes to this revision.May 10 2021, 7:47 PM
dteske added inline comments.
libexec/rc/rc.d/zfskeys
26–27

Current test will fail to pass a very-real (but NULL) positional argument to b64encode. Use number of arguments instead of content of arguments to determine whether to encode args or not.

Combine into single statement for code efficiency (no need to test number of args if initial shift fails -- i.e., in the case of no args given).

Also, the wrong /bin/sh variable is used. "$@" will expand to multiple positional arguments but the %s operator in printf will only take a single string. To make the two match, I suggest "$*" which will squish multiple positional arguments into a single string to fit into printf's %s operator.

27

Current test will fail to pass a very-real (but NULL) positional argument to b64encode. Use number of arguments instead of content of arguments to determine whether to encode args or not.

33

Split on pipe (reason: line >80 char)

34

Use "NOT" operator; ditch the space before semi-colon (apply globally please).

35

Split on flag (reason: line >80 char)

37

Split on flag (reason: line >80 char)

43–44

Positional arguments should be quoted.

45–46

Blank line after declarations (apply globally please).

This revision now requires changes to proceed.May 10 2021, 7:47 PM
ltning-freebsd_anduin.net added inline comments.
libexec/rc/rc.d/zfskeys
26–27

Also, the wrong /bin/sh variable is used. "$@" will expand to multiple positional arguments but the %s operator in printf will only take a single string. To make the two match, I suggest "$*" which will squish multiple positional arguments into a single string to fit into printf's %s operator.

I'm a bit uncertain here; the problem I'm trying to solve is the mangling of $@ in rc, so the real solution would be to handle an arbitrary number of arguments and concatenate those into a null-terminated string. However in this script we only ever expect to see one argument (a dataset), so perhaps saying $1 explicitly after the shift is more appropriate?

35

Split on flag (reason: line >80 char)

I land at 75 chars here..?

ltning-freebsd_anduin.net added inline comments.
libexec/rc/rc.d/zfskeys
26–27

I'll be keeping the "$@" here, unless I misunderstood something:

$ foofunc() { printf "%s\0" "$@" ; }
$ foofunc foo bar baz | xargs -0 -n 1 echo
foo
bar
baz
$ 
  • Changes requested by dteske, others
This revision was not accepted when it landed; it landed in state Needs Review.Jul 28 2021, 4:27 PM
This revision was automatically updated to reflect the committed changes.