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

cryptsetup: add support for the keyscript= option #3007

Closed
wants to merge 1 commit into from
Closed

cryptsetup: add support for the keyscript= option #3007

wants to merge 1 commit into from

Conversation

tchernobog
Copy link

One of the last and most important missing options to fully support
the old crypttab, is support for "keyscript=". This is especially
important for people with custom setups, such as those retrieving the
key from a smartcard.

This patch adds such option, and updates the documentation accordingly.
It also offers a compatibility layer with Debian by setting some useful
environment variables, and rendering them available to the keyscript
when run.

One of the last and most important missing options to fully support
the old crypttab, is support for "keyscript=". This is especially
important for people with custom setups, such as those retrieving the
key from a smartcard.

This patch adds such option, and updates the documentation accordingly.
It also offers a compatibility layer with Debian by setting some useful
environment variables, and rendering them available to the keyscript
when run.
@falconindy
Copy link
Contributor

Ignoring the numerous missing error checks and style violations, support for this has been discussed before and ultimately shot down:

https://lists.freedesktop.org/archives/systemd-devel/2012-July/005835.html

@tchernobog
Copy link
Author

Ignoring the numerous missing error checks and style violations,

That I would be willing to fix, certainly. This is my first attempt, sorry if I got style or checks wrong. I am open to suggestions; I already noticed problems with the indentation, for instance, now that I see it as a patch. Sorry about that.

support for this has been discussed before and ultimately shot down:
https://lists.freedesktop.org/archives/systemd-devel/2012-July/005835.html

Thanks for pointing out the thread. One of the issues however, is that scripts allow the user to really adapt them to their own situation. I.e. I have an OpenGPG-compatible card with some extra data which I want to be used as a key. It is fairly easy to write a script for it, but if you have 10 different users, you probably end up with 10 different scenarios. I don't know if attempting to handle them all would render the logic of cryptsetup too complex.

By looking at the thread, it looks more like the discussion dwindled down. Would then the outline sketched by Mike Kazantsev (https://lists.freedesktop.org/archives/systemd-devel/2012-July/006057.html) be satisfactory to start writing a patch for systemd?

@poettering
Copy link
Member

I am still not convinced that keyscript= is such a good idea. There's ask-password already in place which is kind of a proper API for this already.

I think if Debian wants keyscript=, they should add this downstream.

Smartcard stuff sounds like something to support directly in cryptsetup I figure, if that can be reasonably done, see #2776 for example.

What other usecases are there for keyscript=, that neither proper smartcard support nor ask-password can cover?

(BTW, I consider the smartcard stuff a really bad usecase for keyscript=, since it's hw bound, and that means a single script invoked at the time the pw is needed tends to be wrong, since it cannot deal with the fact that hw is hotplugged dynamically and might appear at any time.)

@poettering poettering added the needs-reporter-feedback ❓ There's an unanswered question, the reporter needs to answer label Apr 25, 2016
@tchernobog
Copy link
Author

Thanks @poettering for the commentary. You're probably right, it might make sense to define a common infrastructure for acquiring smartcard authorization keys. It might entail making some assumptions though (what to do when there are more smartcard readers connected, more keys on the smartcard - and how to use the (signing|auth) key to decrypt the storage, etc.).

I would say then not to merge this back in systemd - maybe Debian would like to grab it to support old behaviour, until an alternative is in place. But downstream as a temporary fix would be also okay.

Could you please outline in very rough steps what would be an acceptable solution to add another password provider for smartcards? It probably needs to be configurable. Thanks!

@johanna-a
Copy link

Having read up on this, I would suggest the following outline for pkcs11 support:
crypttab specifies a pkcs11 URI (https://tools.ietf.org/html/rfc7512)
cryptsetup-generator.c makes sure that a pkcs11 provider is required if a pkcs11 URI is specified
(systemd) cryptsetup.c passes the pkcs11 URI to the "real" cryptsetup in a similar way to how keyfiles are handled.
pkcs11 support is implemented in cryptsetup + cryptsetuplib (probably in something like lib/utils_pkcs11.c)

Everyone is happy until someone requires cryptsetup to timeout. Which they shouldn't.

Unsolved:
cryptsetup may need to ask for a PIN to unlock a slot on a pkcs11 token. In this case (systemd) cryptsetup-generator must recognize this from the pkcs11 URI and use the normal passphrase logic to ask for a PIN to supply to cryptsetuplib. But it will (probably) get messy.

@tukss
Copy link

tukss commented Jun 30, 2016

One Debian keyscript that is not covered by systemd-ask-password nor related to smartcards is /lib/cryptsetup/scripts/decrypt_derived. It is used to extract a derived passphrase from an already opened LUKS device, which is useful to open multiple encrypted devices by entering a single password. A possible use case is multiple LVM PVs, each of which are on encrypted devices. I am not saying the keyscript option is the only way to go here. Probably something simpler would be better. Or am I missing that this is already possible with the current handling of crypttab in systemd?

Copy link

@Elbandi Elbandi left a comment

Choose a reason for hiding this comment

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

and need to change one line more:

if (!path_is_absolute(argv[4]) && !arg_key_script)

and move parse_options call before that

r = WEXITSTATUS(status);
if (r == EXIT_SUCCESS)
{
char line[LINE_MAX];
Copy link

Choose a reason for hiding this comment

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

char line[LINE_MAX] = { 0 };

@wildy
Copy link

wildy commented Sep 6, 2017

Another case that (I presume) is not covered by password agents is, when you require some external program to pull the key over a (secured) network connection so that volumes to be decrypted require actually being on a certian network.
That, or can it be done with password agents?

@bam80
Copy link

bam80 commented Sep 6, 2017

Any chances to merge soon?

@iam-TJ
Copy link

iam-TJ commented Sep 17, 2017

This has broken many FDE PCs I manage and provide support for, where they use a variety of (usually USB device [ yubikey, mass-storage, inverse path Armory, etc.], network supplied) methods of obtaining the key material.

As a practical matter, when you replace an existing tool at least implement all it's core functionality to avoid these kinds of severe regressions.

The keyscript= functionality puts control of how and where the system obtains the key material in the hands of the system administrators where it belongs, rather than subject to developers who seem to have no real interest in this important functionality (this has been going on since 2012!).

So how about implementing keyscript= support so admins can get on with maintaining FDE devices for another 5 years whilst the 'correct' solution is developed and delivered?

Alternatively, why not provide a simple way to disable the systemd-cryptsetup generators and fall-back to the original cryptsetup handling if the admin so chooses?

Either way, we get back the original functionality that has been lost for so long.

@Zythyr
Copy link

Zythyr commented Jan 28, 2018

I am trying to use keyscript in crypttab to unlock an encrypted partition. Haven't no success. It seems this bug is the one causing the issue.

Any idea when this issue will be fixed?

@Fmajor
Copy link

Fmajor commented Jul 28, 2018

Is there any progress? I really miss the keyscript= option.、
=======update===========
i found a workaround here

# vim /etc/default/grub
## add 
cryptopts=target=sda4_crypt,source=/dev/disk/by-uuid/a0a9abbb-8321-3213-a7c8-0f04aa2f11b9,keyscript=/lib/cryptsetup/scripts/get_key
## to GRUB_CMDLINE_LINUX_DEFAULT=
## change the 'sda4_crypt' and uuid with the name in your /etc/crypttab
# update-grub

now keyscript is coming back

@mintsoft
Copy link

As far as I can tell, there's no way to do TPM integration and keep all the configuration in one place without the keyscript support :(

@aleksandarstojkovski
Copy link

Is there any progress? I really miss the keyscript= option.、
=======update===========
i found a workaround here

# vim /etc/default/grub
## add 
cryptopts=target=sda4_crypt,source=/dev/disk/by-uuid/a0a9abbb-8321-3213-a7c8-0f04aa2f11b9,keyscript=/lib/cryptsetup/scripts/get_key
## to GRUB_CMDLINE_LINUX_DEFAULT=
## change the 'sda4_crypt' and uuid with the name in your /etc/crypttab
# update-grub

now keyscript is coming back

and what is the content of /etc/crypttab ?

@poettering
Copy link
Member

If anyone is still interested in this, I think it would be OK to to merge something like this:

Teach systemd-cryptsetup that when the specified key file in /etc/crypttab is actually an AF_UNIX/SOCK_STREAM socket, it connects to it, and reads the key data from it. We actually implemented something like this at many places now, for example in .netdev's PrivateKeyFile= and PrivateKey=. Supporting this in systemd-cryptsetup would make a ton of sense, the only reason this is currently not supported yet is that the key file is read with libcryptsetup's code, not with ours, and libcryptsetup doesn't known the AF_UNIX handling logic.

Doing things this way I think is much prettier, since it isolates the keyscript code from cryptsetup itself, the hook-up is very losely coupled only. it's more flexible (and could be performant too) given that packages can handle the socket requests any way they want.

I really dislike generic callouts as the keyscript= Debian implements, since it turns services into application servers, whose surface is not controllable anymore, which means sandboxing and similar cannot be done reasonably anymore. However, this AF_UNIX/SOCK_STREAM logic provides very similar behaviour, witout forking any external code off systemd-cryptsetup: the code is strictly isolated in its own service unit.

Anyway, I think we should close this PR, I am not convinced we should add this as it stands now, and the idea with simply making AF_UNIX/SOCK_STREAM sockets as keyfiles a supported feature is so much nicer I think, and delivers the same funcitonality.

@poettering poettering closed this Oct 16, 2020
@mintsoft
Copy link

@poettering sounds good, is there a good example of a similar thing being implement elsewhere in systemd that could serve as a template for this?

@poettering
Copy link
Member

I already mentioned a place we already support similar behaviour.

@mintsoft
Copy link

So you did, I really should have read that better!

@Maryse47
Copy link

Wasn't the point of keyscript= running an arbitrary code/script that does any magic it needs to retrieve a password? I don't see how new proposal answers that especially if it needs all existing software using keyscript be rewritten.

@poettering
Copy link
Member

hmm? the idea is that you use an AF_UNIX/SOCK_STREAM socket in the fs that is backed by a scoket-activated systemd service. That service can be anything you like, including your existing keyscripts actually, which you can probably even make work without modification. After all if you use StandardOutput=socket in your socket-activated service behaviour is very close to the debian keyscript= which are also supposed to write its acquired key data to stdout.

poettering added a commit to poettering/systemd that referenced this pull request Nov 4, 2020
…ile_full()

Previously, we'd load the file with libcryptsetup's calls. Let's do that
in our own, so that we can make use of READ_FULL_FILE_CONNECT_SOCKET,
i.e. read in keys via AF_UNIX sockets, so that people can plug key
providers into our logic.

This provides functionality similar to Debian's keyscript= logic (see
 systemd#3007), as it allows key scripts to be run as socket activated services,
that have stdout connected to the activated socket. In contrast to
traditional keyscript= support this logic runs stuff out of process
however, which is beneficial, since it allows sandboxing and similar.
@poettering
Copy link
Member

@mintsoft I decided to just hack that up myself, see #17524

poettering added a commit to poettering/systemd that referenced this pull request Nov 5, 2020
…ile_full()

Previously, we'd load the file with libcryptsetup's calls. Let's do that
in our own, so that we can make use of READ_FULL_FILE_CONNECT_SOCKET,
i.e. read in keys via AF_UNIX sockets, so that people can plug key
providers into our logic.

This provides functionality similar to Debian's keyscript= crypttab
option (see → systemd#3007), as it allows key scripts to be run as socket
activated services, that have stdout connected to the activated socket.
In contrast to traditional keyscript= support this logic runs stuff out
of process however, which is beneficial, since it allows sandboxing and
similar.
@mintsoft
Copy link

mintsoft commented Nov 7, 2020

Awesome @poettering 👍

poettering added a commit to poettering/systemd that referenced this pull request Nov 25, 2020
…ile_full()

Previously, we'd load the file with libcryptsetup's calls. Let's do that
in our own, so that we can make use of READ_FULL_FILE_CONNECT_SOCKET,
i.e. read in keys via AF_UNIX sockets, so that people can plug key
providers into our logic.

This provides functionality similar to Debian's keyscript= crypttab
option (see → systemd#3007), as it allows key scripts to be run as socket
activated services, that have stdout connected to the activated socket.
In contrast to traditional keyscript= support this logic runs stuff out
of process however, which is beneficial, since it allows sandboxing and
similar.
poettering added a commit to poettering/systemd that referenced this pull request Nov 26, 2020
…ile_full()

Previously, we'd load the file with libcryptsetup's calls. Let's do that
in our own, so that we can make use of READ_FULL_FILE_CONNECT_SOCKET,
i.e. read in keys via AF_UNIX sockets, so that people can plug key
providers into our logic.

This provides functionality similar to Debian's keyscript= crypttab
option (see → systemd#3007), as it allows key scripts to be run as socket
activated services, that have stdout connected to the activated socket.
In contrast to traditional keyscript= support this logic runs stuff out
of process however, which is beneficial, since it allows sandboxing and
similar.
poettering added a commit to poettering/systemd that referenced this pull request Nov 28, 2020
…ile_full()

Previously, we'd load the file with libcryptsetup's calls. Let's do that
in our own, so that we can make use of READ_FULL_FILE_CONNECT_SOCKET,
i.e. read in keys via AF_UNIX sockets, so that people can plug key
providers into our logic.

This provides functionality similar to Debian's keyscript= crypttab
option (see → systemd#3007), as it allows key scripts to be run as socket
activated services, that have stdout connected to the activated socket.
In contrast to traditional keyscript= support this logic runs stuff out
of process however, which is beneficial, since it allows sandboxing and
similar.
poettering added a commit to poettering/systemd that referenced this pull request Dec 1, 2020
…ile_full()

Previously, we'd load the file with libcryptsetup's calls. Let's do that
in our own, so that we can make use of READ_FULL_FILE_CONNECT_SOCKET,
i.e. read in keys via AF_UNIX sockets, so that people can plug key
providers into our logic.

This provides functionality similar to Debian's keyscript= crypttab
option (see → systemd#3007), as it allows key scripts to be run as socket
activated services, that have stdout connected to the activated socket.
In contrast to traditional keyscript= support this logic runs stuff out
of process however, which is beneficial, since it allows sandboxing and
similar.
poettering added a commit to poettering/systemd that referenced this pull request Dec 1, 2020
…ile_full()

Previously, we'd load the file with libcryptsetup's calls. Let's do that
in our own, so that we can make use of READ_FULL_FILE_CONNECT_SOCKET,
i.e. read in keys via AF_UNIX sockets, so that people can plug key
providers into our logic.

This provides functionality similar to Debian's keyscript= crypttab
option (see → systemd#3007), as it allows key scripts to be run as socket
activated services, that have stdout connected to the activated socket.
In contrast to traditional keyscript= support this logic runs stuff out
of process however, which is beneficial, since it allows sandboxing and
similar.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cryptsetup needs-reporter-feedback ❓ There's an unanswered question, the reporter needs to answer
Development

Successfully merging this pull request may close these issues.