TritonDataCenter / sdc-vmtools-lx-brand

The guest tools for lx-brand images
https://docs.joyent.com/images/container-native-linux
Mozilla Public License 2.0
7 stars 10 forks source link

Use 'AuthorizedKeysCommand' sshd_config option for Smart Login functionality #27

Closed chorrell closed 5 years ago

chorrell commented 7 years ago

SmartOS instances use SmartLogin which is a plugin to ssh that allows a dynamic lookup of ssh keys. This allows for dynamic ssh key updating when ssh keys are added or removed via CloudAPI.

Newer versions of sshd have an AuthorizedKeysCommand option (man sshd_config) that "specifies a program to be used to look up the user's public keys." It looks like this could duplicate the SmartLogin functionality on lx-brand where there is a new enough version of sshd available.

Reference: http://manpages.ubuntu.com/manpages/zesty/man5/sshd_config.5.html

We would also need to set AuthorizedKeysCommandUser, preferably to the nobody user or a user with limited access (nologin) for running the script.

Interestingly, various tokens are available that can be passed to the AuthorizedKeysCommand command, such as %u for the username being authenticated. Currently the user would only ever be root (with the keys stored as the root_authorized_keys meta data value.

http://manpages.ubuntu.com/manpages/zesty/man5/sshd_config.5.html#contenttoc4 (see TOKENS)

In the future this could be used to authenticate different users instead of just root.

chorrell commented 7 years ago

I did a bit of testing and the nobody user doesn't seem to have the right privileges for running /native/usr/sbin/mdata-get. Looks like we'd need a dedicated user for this (e.g. triton-ssh or something similarly names.

There also seems to be some slight differences in implementation between Ubuntu 16.04 and CentOS 7. In Ubuntu 16.04, you can explicitly pass the %u argument to the AuthorizedKeysCommand script (e.g., AuthorizedKeysCommand /lib/smartdc/fetch-ssh-keys %u) but on CentOS 7 this fails but the %u argument is already implicitly passed.

chorrell commented 7 years ago

Oh, no, it turns out I was wrong and %u is automatically passed to the script in Ubuntu 16.04 as well.

chorrell commented 7 years ago

From the man page for sshd_config in Ubuntu-16.04 for AuthorizedKeysCommand (the last sentence):

Arguments to AuthorizedKeysCommand may be provided using the following tokens, which will be expanded at runtime: %% is replaced by a literal '%', %u is replaced by the username being authenticated, %h is replaced by the home directory of the user being authenticated, %t is replaced with the key type offered for authentication, %f is replaced with the fingerprint of the key, and %k is replaced with the key being offered for authentication. If no arguments are specified then the username of the target user will be supplied.

So it looks like we can always assume the %u token is passed.

From the man page for sshd_config in CentOS 7 for AuthorizedKeysCommand:

Specifies a program to be used to look up the user's public keys. The program must be owned by root and not writable by group or others. It will be invoked with a single argument of the username being authenticated, and should produce on standard output zero or more lines of authorized_keys output (see AUTHORIZED_KEYS in sshd(8)). If a key supplied by AuthorizedKeysCommand does not successfully authenticate and authorize the user then public key authentication continues using the usual AuthorizedKeysFile files. By default, no AuthorizedKeysCommand is run.

chorrell commented 7 years ago

For reference, this is the script I'm using to test in lx-brand (/lib/smartdc/fetch-ssh-keys):

#!/native/usr/bin/bash

USER=$1

/native/usr/sbin/mdata-get ${USER}_authorized_keys
bahamat commented 7 years ago

For joyent brand zones either root or admin can use root_authorized_keys. And this should work with anything that has AuthorizedKeysCommand, so kvm,bsd, etc should all work.

chorrell commented 7 years ago

It turns out this won't really do what I think it will do. The meta data root_authorized_keys value will not be automatically updated for a given lx-brand instance when a key is added or removed.

fengxiaochuang commented 7 years ago

Hi, @chorrell

I would like to use AuthorizedKeysCommand Option to do a server management system, but I do not know how to obtain the visitor's ip address, when the visitor has not yet landed. Do you have this attempt? In the public key string to add the source IP address should also be done, but that practice is a bit stupid. Do you have a better solution?