canonical / cloud-init

Official upstream for the cloud-init: cloud instance initialization
https://cloud-init.io/
Other
2.97k stars 881 forks source link

Randomly-set credentials not available within the instance #3861

Open ubuntu-server-builder opened 1 year ago

ubuntu-server-builder commented 1 year ago

This bug was originally filed in Launchpad as LP: #1921124

Launchpad details
affected_projects = []
assignee = oddbloke
assignee_name = Dan Watkins
date_closed = None
date_created = 2021-03-24T14:11:48.686652+00:00
date_fix_committed = None
date_fix_released = None
id = 1921124
importance = undecided
is_complete = False
lp_url = https://bugs.launchpad.net/cloud-init/+bug/1921124
milestone = None
owner = oddbloke
owner_name = Dan Watkins
private = False
status = in_progress
submitter = oddbloke
submitter_name = Dan Watkins
tags = []
duplicates = []

Launchpad user Dan Watkins(oddbloke) wrote on 2021-03-24T14:11:48.686652+00:00

As part of the fix for bug 1918303 in [0], we stopped emitting randomly-generated passwords to /var/log/cloud-init-output.log. This functionality is used by some cloud-init consumers, most notably subiquity.

We should reintroduce saving these passwords somewhere in the instance, securely, so that these use cases are not regressed.

[0] https://github.com/canonical/cloud-init/commit/b794d426b9ab43ea9d6371477466070d86e10668

ubuntu-server-builder commented 1 year ago

Launchpad user Dan Watkins(oddbloke) wrote on 2021-03-24T14:37:46.411133+00:00

To ensure these are secure, they should be written to an only-readable-by-root file.

In terms of path, /run/cloud-init seems like a sensible place to put these. In security terms, it's good: the passwords will only be available until the instances is first rebooted, as /run is a tmpfs. However, if folks use cc_power_state to reboot a machine, for example, they'll never be able to read the file before it's wiped out.

Writing to /var/lib/cloud/data seems possible, but that directory isn't cleaned up by cloud-init if the filesystem performs another first boot (i.e. is captured as an image and launched). This means that such an image would contain users with passwords stored in the filesystem. I don't think this is a problem for the new instance per se: you would need root permissions to read the passwords anyway, so you can't gain further access using them. However, I think it presents a problem for other instances launched from such an image: anyone with root on one such instance therefore has passwords that could grant them access to other instances. (Such access could be privileged if root has a random password generated by cloud-init, or any of the other users have sudo permissions.)

/var/lib/cloud/instance/ has the same problem: the passwords would be available somewhere in /var/lib/cloud/instances// on all such subsequent launches.

Given all this, I'm leaning towards using a path in /run. Randomly-generated passwords will therefore be readable for the duration of an instance's first boot, and will disappear when that instance is next shut down. This means they will not leak into subsequent boots, or into images captured from such instances.

Any users for whom this causes a problem can work around it in their cloud-config (e.g. by doing a cp in a runcmd). This gives us secure default behaviour, and means that users have to explicitly opt for less secure behaviour.