Thanks for this detailed and thoughtful bug report, we really appreciate it. We've had some preliminary internal discussions, and we have a sync with our security team scheduled for tomorrow afternoon to discuss whether or not we think this issue warrants a coordinated release. Below is my initial analysis.
In order to allow people to access systems using these randomly generated passwords (without needing another access vector in order to know the passwords), cloud-init emits them to the serial console. In order to have log messages emitted to the console readily available within the system also, it writes that same content to /var/log/cloud-init-output.log. As a result, those passwords are written to that file, which is world-readable.
In the first instance, we should consider whether or not emitting these random passwords to the console is acceptable default behaviour. For users who are using this functionality as the only way they access the instance, it is: there's no other way for them to know what password to use. The question then becomes, I think, what proportion of users of this functionality use it in this way? If it's the majority, then perhaps emitting them by default is justifiable. If not (or if we think this behaviour is simply too dangerous to be the default), then we could consider toggling it with a new configuration option, defaulting to false: users are already passing in cloud-config to get into this situation, so working around this change in behaviour should be reasonably straightforward. (I don't think we can remove support for the emission altogether: that will break existing workflows, and in a way that is likely to move such folks to simply using hard-coded passwords: not exactly a security fix.)
Given my (parenthetical) conclusion, we clearly do also need to address how we are going to remove access to these passwords from unprivileged users within the system. Two obvious options present themselves: (a) we could make cloud-init-output.log only root-readable, or (b) we could modify the code which emits these messages to either redact them when going to cloud-init-output.log or omit them from there entirely. cloud-init-output.log and the serial console are tied together very tightly[0], so (b) could prove to be difficult: we'll perform some further analysis. (It's possible that the default config in [0] could be extended to omit the lines using grep, for example?)
(For (a), I also just noticed that the content in cloud-init-output.log is also present in the journal for the various cloud-init units. Whatever resolution we reach regarding cloud-init-output.log, we should confirm that the permissions that journalctl enforces for such access are acceptable to us.)
Thanks again for the report! Any comments, questions, or suggestions (either from you, Carl, or the other cloud-init folks with access to this report) are more than welcome!
Dan
[0] The default configuration should give you a sense of how thorough that link is: "output: {all: '| tee -a /var/log/cloud-init-output.log'}"
Hi Carl,
Thanks for this detailed and thoughtful bug report, we really appreciate it. We've had some preliminary internal discussions, and we have a sync with our security team scheduled for tomorrow afternoon to discuss whether or not we think this issue warrants a coordinated release. Below is my initial analysis.
In order to allow people to access systems using these randomly generated passwords (without needing another access vector in order to know the passwords), cloud-init emits them to the serial console. In order to have log messages emitted to the console readily available within the system also, it writes that same content to /var/log/ cloud-init- output. log. As a result, those passwords are written to that file, which is world-readable.
In the first instance, we should consider whether or not emitting these random passwords to the console is acceptable default behaviour. For users who are using this functionality as the only way they access the instance, it is: there's no other way for them to know what password to use. The question then becomes, I think, what proportion of users of this functionality use it in this way? If it's the majority, then perhaps emitting them by default is justifiable. If not (or if we think this behaviour is simply too dangerous to be the default), then we could consider toggling it with a new configuration option, defaulting to false: users are already passing in cloud-config to get into this situation, so working around this change in behaviour should be reasonably straightforward. (I don't think we can remove support for the emission altogether: that will break existing workflows, and in a way that is likely to move such folks to simply using hard-coded passwords: not exactly a security fix.)
Given my (parenthetical) conclusion, we clearly do also need to address how we are going to remove access to these passwords from unprivileged users within the system. Two obvious options present themselves: (a) we could make cloud-init- output. log only root-readable, or (b) we could modify the code which emits these messages to either redact them when going to cloud-init- output. log or omit them from there entirely. cloud-init- output. log and the serial console are tied together very tightly[0], so (b) could prove to be difficult: we'll perform some further analysis. (It's possible that the default config in [0] could be extended to omit the lines using grep, for example?)
(For (a), I also just noticed that the content in cloud-init- output. log is also present in the journal for the various cloud-init units. Whatever resolution we reach regarding cloud-init- output. log, we should confirm that the permissions that journalctl enforces for such access are acceptable to us.)
Thanks again for the report! Any comments, questions, or suggestions (either from you, Carl, or the other cloud-init folks with access to this report) are more than welcome!
Dan
[0] The default configuration should give you a sense of how thorough that link is: "output: {all: '| tee -a /var/log/ cloud-init- output. log'}"