Support for a keyscript pin, which would call an executable to retrieve key material
As a lower barrier to entry for integrations with custom sources of secret material, would the maintainers be open to a keyscript-like pin in clevis, mirroring the functionality of the same argument in crypttab?
https://manpages.debian.org/testing/cryptsetup/crypttab.5.en.html
This may allow integrations like #39 to be developed with less bloat to clevis core.
Disclaimer: I'm not the clevis developer. If I read the documentation and old mailing list articles correctly, the keyscript feature is not supported by systemd and there hasn't quite been huge enthusiasm to rectify that situation. For the past five years. So is it readlly worth to support a feature that is dead as a doodoo and will forseable go away at some time in the near future?
Anyway, implementing this isn't really difficult since clevis-luks-unlock already has all the logic. Only difference: Print the plaintext instead of calling cryptsetup. Beware, it's completely untested.
How to use (in case it's not obvious):
- Patch
clevis-luks-unlock - Copy, or better: Symlink as
clevis-luks-keyscript. That name is important. - Configure that as keyscript in your
/etc/crypttab.
--- /usr/bin/clevis-luks-unlock.orig
+++ /usr/bin/clevis-luks-unlock
@@ -55,8 +55,13 @@
done
if [ -z "$DEV" ]; then
- echo "Did not specify a device!" >&2
- usage
+ if [ "$(basename "$0")" = 'clevis-luks-keyscript' ] && [ "$CRYPTTAB_SOURCE" ] && [ -b "$CRYPTTAB_SOURCE" ] ; then
+ mode='keyscript'
+ DEV="$CRYPTTAB_SOURCE"
+ else
+ echo "Did not specify a device!" >&2
+ usage
+ fi
fi
if ! cryptsetup isLuks "$DEV"; then
@@ -111,6 +116,10 @@
pt="$(luks1_decrypt -d $DEV -s $slot -u $UUID)" \
|| continue
+ if [ "$mode" = 'keyscript' ] ; then
+ printf '%s' "$pt"
+ exit 0
+ fi
exec cryptsetup open -d- "$DEV" "$NAME" < <(
echo -n "$pt"
)
@@ -120,6 +129,10 @@
while read -r id; do
pt="$(luks2_decrypt --token-id "$id" "$DEV")" \
|| continue
+ if [ "$mode" = 'keyscript' ] ; then
+ printf '%s' "$pt"
+ exit 0
+ fi
exec cryptsetup open -d- "$DEV" "$NAME" < <(
echo -n "$pt"
)
Cheers,
Thanks for the details @cbiedl .
the keyscript feature is not supported by systemd and there hasn't quite been huge enthusiasm to rectify that situation
Yeah we've been running into this a bit at work recently while working to develop a simple integration with LUKS.
So is it readlly worth to support a feature that is dead as a doodoo and will forseable go away at some time in the near future?
If I'm reading you correctly here, I'm not proposing that clevis supports the LUKS keyscript functionality. Instead, I'm checking to see if clevis could have its own keyscript functionality via a pin, so something like this:
# Now: With tang, from the README
clevis luks bind -d /dev/sda tang '{"url": "http://server.local/key"}'
# What I want: With a `keyscript` option, where the script at the path simply returns a key
clevis luks bind -d /dev/sda keyscript '{"path": "/usr/local/bin/"}'
Reading through the code a bit more, it looks like this may be simpler than I originally expected.
The README mentions that the pins are plugins, but the nature of those plugins was unclear to me until I dug through the code. Now I see that a pin named keyscript would just require executables clevis-encrypt-keyscript and clevis-decrypt-keyscript on the path. From what I can tell those do need to return a valid formatted jwe (rather than some arbitrary ciphertext).
- https://github.com/latchset/clevis/blob/v13/src/luks/clevis-luks-bind.in#L135-L136
- just calls
clevis encrypt
- just calls
- https://github.com/latchset/clevis/blob/v13/src/luks/clevis-luks-unlock.in#L81-L105
- just calls
clevis decrypt
- just calls
- https://github.com/latchset/clevis/blob/v13/src/clevis-decrypt#L44-L47
- just calls
clevis-decrypt-$pin
- just calls
- https://github.com/latchset/clevis/tree/master/src/pins/sss
- see "test" configuration
- just uses "clevis-decrypt-test" and "clevis-encrypt-test" bash functions
- the "test" pin for clevis just returns jwe on encrypt and consumes on decrypt
I'll mess around with this a bit more and see I can build off the test pin to get a simple keyscript pin to behave.
I have a prototype working here: https://github.com/turtlemonvh/clevis/tree/191/keyscript-pin0prototype/src/pins/keyscript
I used the example of the test example for the sss keyscript to build an example. I'm sure there are some silly things in there, but the scripts do seem to work.
The command works like this
# Encrypt
$ echo "hi there" | ./src/pins/keyscript/clevis-encrypt-keyscript '{"keyscript": "/tmp/keyscript"}' > keyscript.jwe
$ cat keyscript.jwe ; echo
eyJhbGciOiJkaXIiLCJjbGV2aXMiOnsiY2ZnIjp7ImtleXNjcmlwdCI6Ii90bXAva2V5c2NyaXB0In0sInBpbiI6ImtleXNjcmlwdCJ9LCJlbmMiOiJBMjU2R0NNIn0..9ZmxtknGj5qtka_P.DBq9JLBWRkMQ.ETuFwW5MG00lQuGT46uABg
$ cat keyscript.jwe | cut -d"." -f1 | jose b64 dec -i- ; echo
{"alg":"dir","clevis":{"cfg":{"keyscript":"/tmp/keyscript"},"pin":"keyscript"},"enc":"A256GCM"}
# Decrypt
$ cat keyscript.jwe | ./src/pins/keyscript/clevis-decrypt-keyscript
hi there
If there is interest in having this capability in clevis I can clean this up and even add on some options like passing arguments to the keyscript.
Possibly I completely understood your initial request indeed. About authoring pins, I had created pull request earlier. Although you've already created something, it still might be of some value for you: https://github.com/latchset/clevis/pull/203/commits/22cb93d61f7c4cf60eb3ab0899c16d8a49905550
That guide is awesome @cbiedl - thanks!
I hadn't gotten to the initramfs and dracut configuration yet, so that is especially helpful. Your "key in a file" pin looks very similar to my "keyscript" pin - that would have been good to find a few hours ago. :D
I'll read through your work on #203 in more detail (as well as your PR on #204) when I come back around to this.