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

Support for a keyscript pin, which would call an executable to retrieve key material #191

Open
turtlemonvh opened this issue May 8, 2020 · 5 comments

Comments

@turtlemonvh
Copy link

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.

@cbiedl
Copy link

cbiedl commented May 25, 2020

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,

@turtlemonvh
Copy link
Author

turtlemonvh commented May 31, 2020

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).

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.

@turtlemonvh
Copy link
Author

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.

@cbiedl
Copy link

cbiedl commented Jun 1, 2020

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: 22cb93d

@turtlemonvh
Copy link
Author

turtlemonvh commented Jun 1, 2020

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants