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 chaining to other AuthorizedKeysCommands #10

Open
bgilbert opened this issue Jun 17, 2020 · 8 comments
Open

Support chaining to other AuthorizedKeysCommands #10

bgilbert opened this issue Jun 17, 2020 · 8 comments
Labels
enhancement New feature or request

Comments

@bgilbert
Copy link
Contributor

Feature Request

Desired Feature

GCP OS Login also uses an AuthorizedKeysCommand, but sshd only allows configuring one of those. Add a set of config directories in /usr, /etc, and /run that accept drop-ins giving additional commands to run. Run each command in sequence and let their stdout/stderr flow back to sshd.

@bgilbert bgilbert added the enhancement New feature or request label Jun 17, 2020
@stuartpb
Copy link

stuartpb commented Jun 21, 2020

I was also thinking that you could even have support for executables under ~/.ssh/authorized_keys.d, maybe with another layer (like by-fingerprint) for specifying options the script wants passed in to it.

@bgilbert
Copy link
Contributor Author

@stuartpb Could you elaborate on the another layer part?

@stuartpb
Copy link

stuartpb commented Jun 22, 2020

Okay, so, if a script wants to intercept AuthorizedKeysCommand, there are a variety of parameters it can take:

  • The fingerprint of the key or certificate
  • The base64-encoded key or certificate for authentication
  • The key or certificate type
  • The username, numeric user ID, and/or home directory of the target user

I was thinking you'd have another level of subdirectory for the drop-ins differentiating between scripts that use:

  • just username (ie. by-username)
    • this would be the equivalent of AuthorizedKeysCommand=/bin/foo (supplying the username is the default behavior)
    • as this is the default behavior, you could also just have this be the behavior of scripts in the base directory
  • username and key fingerprint (ie. by-fingerprint)
    • this would be the equivalent of AuthorizedKeysCommand=/bin/foo %u %f
  • username and full key (with type) (ie. by-key)
    • this would be the equivalent of AuthorizedKeysCommand=/bin/foo %u %t %k

If you had some kind of config file layer, you could specify your own arbitrary combinations of the operators OpenSSH lets you pass to an AuthorizedKeysCommand, but with the current set of data OpenSSH provides, any value for this would effectively be redundant to one of these three (ie. you can create a wrapper for any other calling convention from the data available to by-key, and a wrapper for the only parameters most scripts need via the lower-overhead by-fingerprint).

Use case

Let us call whatever name of the directory where we place scripts under /usr, /etc, or /run here "akd". (It might make sense to put it somewhere closer to ssh's configuration like /etc/authorized_keys.d, but that's out of scope for this post.)

So, for example, say you have a script in your configuration that adds any key that tries to log in as a certain user to that user's authorized keys (so a public user, in other words). As a way to specify that that's the data used by this script (without wanting to introduce a config-file layer), you'd put it in a location like /etc/akd/by-key/20-add-for-public-user.sh.

Related: crossing this with authorized_keys.d

Also, it should be possible for the user to have something like ~/.config/akd for a user to specify scripts (I was originally specifying ~/.ssh/authorized_keys.d itself, where a tool might differentiate between a file and a command by checking if the file is executable).

To combine these two ideas, an executable in ~/.ssh/authorized_keys.d would only receive the user's own name by default, and scripts could be placed in ~/.ssh/authorized_keys.d/by-fingerprint/ or ~/.ssh/authorized_keys.d/by-key/ if they require more information to operate.

@bgilbert
Copy link
Contributor Author

without wanting to introduce a config-file layer

I think a config-file layer is the right approach. In the original use case for this feature, there's an existing binary somewhere in /usr, and we need to point to it and specify arguments with the same flexibility as AuthorizedKeysCommand. So I was imagining something like /etc/ssh-key-dir.d/google-oslogin.conf with something like:

Command=/usr/libexec/google_authorized_keys %u
User=google

This allows interfacing with existing commands that don't fit the by-username/by-fingerprint/by-key paradigm, but of course it requires ssh-key-dir to take (or synthesize) all the possible arguments.

If we extended this to per-user commands, we could do it via files in ~/.ssh/ssh-key-dir.d with the same syntax. I think it'd be good to use a different directory than authorized_keys.d; it seems too confusing to have one directory with multiple kinds of files in it. I'm cautious about the per-user idea, though, since AuthorizedKeysCommands are security-sensitive and run before authentication. It might make more sense to require the administrator to install a system-wide script that only returns results for a particular user.

@Conan-Kudo
Copy link

This is something that I'd want as well for being able to use Fedora CoreOS in environments where a standard Authorized Keys Command already is set up and needs to be layered into the system (for things like retrieving keys from arbitrary databases or services).

@bgilbert
Copy link
Contributor Author

bgilbert commented Nov 8, 2022

Synthesizing percent-substitutions is a bit riskier than just forwarding them from sshd, since there's a risk that we won't produce the same values that sshd would. Proposal: take short arguments matching the substitution tokens, so our 40-ssh-key-dir.conf would have e.g.:

AuthorizedKeysCommand /usr/libexec/ssh-key-dir -u %u -U %U -h %h [...]

And we could still take a bare %u argument for compatibility. If a config file in /etc/ssh-key-dir.d specifies a token that we didn't receive on our own command line, we'd decline to run that command.

We might use TOML for the config files. Its Rust parser should be robust and the format is simple.

@lucab
Copy link
Contributor

lucab commented Nov 8, 2022

Out of curiosity, did anybody already check how hard would it be to patch sshd into honoring multiple AuthorizedKeysCommand lines? I guess sharing AuthorizedKeysCommandRunAs between them would be fine. Not sure if the semantic change for the keyword (from overriding to appending) would be acceptable.

@bgilbert
Copy link
Contributor Author

bgilbert commented Nov 8, 2022

I'm not sure sharing AuthorizedKeysCommandRunAs would work. ssh-key-dir needs access to user home directories, while tools that query a network service (like the GCP one) will want to run without privilege.

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

No branches or pull requests

4 participants