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

Use the default username as provided by cloud-init #929

Open
Saviq opened this issue Jul 22, 2019 · 18 comments
Open

Use the default username as provided by cloud-init #929

Saviq opened this issue Jul 22, 2019 · 18 comments

Comments

@Saviq
Copy link
Collaborator

Saviq commented Jul 22, 2019

To keep as close as possible with cloud deployments, we were asked to use the default username when issuing multipass shell, as provided by cloud-init.

It depends on the image being launched (cloud init's template), so we might need to have our own "service" user and use that to find out what user we should shell into.

@Saviq Saviq added this to To do in 19.10 cycle via automation Jul 22, 2019
@Saviq Saviq added this to To do in v0.9.0 via automation Jul 25, 2019
@townsend2010
Copy link
Contributor

townsend2010 commented Aug 9, 2019

For now, we are going to replace the multipass user with an ubuntu user on all newly launched instances regardless of the distro being launched. Any existing instances will still have the multipass user. I opened #949 to track this.

In a future enhancement, we will use the cloud images default user and also add a multipass user during cloud-init which will mainly be used to figure out the default user.

@basak
Copy link

basak commented Nov 7, 2019

It depends on the image being launched (cloud init's template), so we might need to have our own "service" user and use that to find out what user we should shell into.

That sounds like a really horrible hack. Could the required information perhaps be added to image metadata - simplestreams in the case of Ubuntu? It seems to me that defining this against individual images and tracking cloud-init userdata overrides if necessary would be a more appropriate layer for this ti fit into.

@townsend2010
Copy link
Contributor

@basak,

Could the required information perhaps be added to image metadata - simplestreams in the case of Ubuntu?

We need a single source of truth for this if we are to get it from an external source. Other cloud images (such as Fedora) don't use simplestreams, so I don't think that is a place for it. We need a cloud image agnostic way of determining the default user.

Our proposed "hack" is to add a multipass user in addition to whatever the default user cloud-init sets up is. Then through issuing a command via ssh using the known multipass user into the instance, we can detect what the name of the default user is, so when someone does shell or exec, they get the default user regardless of the cloud image being used.

If you have any other ideas of how we can obtain the default user regardless of the cloud image being used, we are all ears 😁

@raharper
Copy link

raharper commented Nov 7, 2019

IIRC, multipass uses the NoCloud datasource. I think we can combine a few features to make this work better.

Cloud-init supports adding a user and having it generate emit a redirect to default user message over ssh. I propose that multipass use this configuration to create the multipass user with redirection enabled (or some other username if you want to retain multipass user for some other purpose) and the message from the instance will reply with whatever the default user for that image was; this handles not having multipass have to know how cloud-init is configured in the target image.

Here's the config to make this happen:

In meta-data you need to add the user's public ssh key like so:

% cat meta-data
instance-id: e0c77a90-2bf7-45c0-b3b8-09c196582e32
public-keys:
  - ssh-rsa AAAA...

And in user-data, enable the default and multipass user with ssh redirect like so

#cloud-config
users:
  - default
  - name: multipass
    ssh_redirect_user: true

After the instance has booted, you can ssh to the instance as the redirect user and cloud-init emits this messge:

% ssh multipass@localhost /bin/true 2>dev/null
Please login as the user "ubuntu" rather than the user "multipass".

@townsend2010
Copy link
Contributor

@raharper,

Cool stuff! A couple of questions.

  1. Is that string that cloud-init prints stable? Since it's a message we'll have to key on, any changes to that message will mess up how we parse the string to find the user we should use.
  2. Is this supported on older Ubuntu cloud image versions such as Trusty & Xenial?

@basak
Copy link

basak commented Nov 7, 2019 via email

@raharper
Copy link

raharper commented Nov 7, 2019

  1. Yes. The format is hard-coded:
    https://github.com/canonical/cloud-init/blob/master/cloudinit/ssh_util.py#L44

  2. This is supported back through Xenial. ssh_redirect_user was landed in Sept 2018, released in 18.4 and newer.

@basak
Copy link

basak commented Nov 7, 2019

Ideally multipass would run production images with no modification
whatsoever. This is the point of cloud-init and currently a key
differentiator against Vagrant. Hacking the image seems like the start
of slippery slope going against that.

To be clear, I realise that you're not actually "hacking the image" or modifying it. That was a poor choice of words, sorry.

What you are doing though is hacking the cloud-init userdata to be different from default in a way the developer won't do in production. I think that every instance of this should be avoided whenever possible for the reason I stated, and in this case it can be avoided so it should be avoided.

@raharper
Copy link

raharper commented Nov 7, 2019

I'm proposing that you move that single source of truth to the abstraction you're using for the image source. Make it the responsibility for the layer that supplies the image to also tell you the default username at the same time as providing you the image.

Unfortunately, the "default" user in images has diverged over time; specifically in Non-ubuntu images. Over time as cloud-images update to newer cloud-init releases, they've been able to set a consistent name as supplied by cloud-init in it's default configuration in packaging. Additionally, downstream provides, both in packaging and in image publishing may also override these defaults with whatever name/values they choose.

This leaves few solutions. The primary means to knowin the value is going to be either provide the default user name and groups (groups are harder) or accept the default user as defined in the image and query the value.

@raharper
Copy link

raharper commented Nov 7, 2019

What you are doing though is hacking the cloud-init userdata to be different from default in a way the developer won't do in production. I think that every instance of this should be avoided whenever possible for the reason I stated, and in this case it can be avoided so it should be avoided.

User-data is arbitrary; there are no "default" or "production" user-data values.

@townsend2010
Copy link
Contributor

What you are doing though is hacking the cloud-init userdata to be different from default in a way the developer won't do in production.

Right, which is what this bug is about is figuring out a way for Multipass to be able to ssh into an instance, regardless of what cloud image is being used, in a consistent manner and be able to preserve the "default" user that cloud-init sets up. Yes, we did change the default to be "multipass" and as has been pointed out over time, this is wrong. As a stop-gap measure, we changed that to "ubuntu", but again, that breaks other non-Ubuntu cloud-images.

Since we allow launching cloud images via URL or even file based, there is absolutely no way for Multipass to know what distro's cloud image is being launched. This is why we need some way to "probe" the instance to figure out what the default user name is. Also, there is absolutely nothing that precludes a user to set their own "default" user via the --cloud-init option to multipass launch, so even if an Ubuntu cloud image is launched via SimpleStreams, the user may very well have changed the default user to foo using their own custom cloud-init data they passed in.

@townsend2010
Copy link
Contributor

@raharper,

Thanks for the answers. So you are guaranteeing that the hard coded message will never change and will always be non-localized?

@raharper
Copy link

raharper commented Nov 7, 2019

@townsend2010

No, and no. Software changes as do requirements.

What we'll want is to allow user-data to include a template for the redirect response so you know what to expect.

There are no pending changes to that string. Cloud-init does not currently have any localization.

@townsend2010
Copy link
Contributor

@raharper,

Yeah, I kind of said that tongue-in-cheek, but I wanted to bring up that we need some sort of way to always be able to parse out the real default user name regardless of changes there. I appreciate your pointers and help on this!

@ricab
Copy link
Collaborator

ricab commented Nov 7, 2019

No, and no. Software changes as do requirements.

I guess we wouldn't need a hard guarantee that it won't change, just that it wouldn't change silently along a version track.

So, a related question is: is it (or could it become) part of the interface in any way? Otherwise, I share Chris's unease depending on an implementation detail.

@raharper
Copy link

raharper commented Nov 7, 2019

@ricab

Certainly. It's been untouched since it landed. Cloud-init team is aware. We can do two things.

  1. merge in comments around the ssh_redirect_user documentation and code, as well as where the message is currently defined, warning against changing that. Multipass is not the only user of ssh_redirect_user config.

  2. Accept a PR to allow user-data to provide a template for the redirection message.

@basak
Copy link

basak commented Nov 7, 2019 via email

@basak
Copy link

basak commented Nov 7, 2019 via email

@ricab ricab mentioned this issue Feb 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
19.10 cycle
  
To do
Development

No branches or pull requests

5 participants