Skip to content

Azure IMDS publicKeys contain \r\n which prevents ssh access to vms using cloud-generated ssh keys. #3825

@ubuntu-server-builder

Description

@ubuntu-server-builder

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

Launchpad details
affected_projects = ['cloud-init (Ubuntu)', 'cloud-init (Ubuntu Xenial)', 'cloud-init (Ubuntu Bionic)', 'cloud-init (Ubuntu Focal)', 'cloud-init (Ubuntu Groovy)', 'cloud-init (Ubuntu Hirsute)']
assignee = None
assignee_name = None
date_closed = 2021-01-12T20:54:27.491085+00:00
date_created = 2021-01-09T03:29:43.495573+00:00
date_fix_committed = 2021-01-12T20:54:27.491085+00:00
date_fix_released = 2021-01-12T20:54:27.491085+00:00
id = 1910835
importance = critical
is_complete = True
lp_url = https://bugs.launchpad.net/cloud-init/+bug/1910835
milestone = None
owner = chad.smith
owner_name = Chad Smith
private = False
status = fix_released
submitter = chad.smith
submitter_name = Chad Smith
tags = ['verification-done', 'verification-done-bionic', 'verification-done-focal', 'verification-done-groovy', 'verification-done-xenial']
duplicates = []

Launchpad user Chad Smith(chad.smith) wrote on 2021-01-09T03:29:43.495573+00:00

== Begin SRU Template ==
[Impact]
The previous version of cloud-init used OpenSSL to process the SSH keys provided by the Azure platform. cloud-init 20.4 replaced that code with a more efficient implementation, but one which did not use OpenSSL: this meant that users passing certificates to instances, or users generating SSH keys in Azure's web UI (which inserts \r\n sequences into the public key content), were regressed: their certificates and malformed SSH keys were no longer handled, so they could fail to gain access to newly-launched instances.

This release is only a single functional cherry-pick which solely affects Azure platform. It is a critical bug we wish to release as soon as possible

  * Azure: cherry-pick 4f62ae8: Fix regression with handling of IMDS ssh keys
    (#760) (LP: #1910835)

The functional changeset here introduces a raise KeyError exception which forces cloud-init to revert to previous released logic of the previous cloud-init public release 20.3.

[Test Case]

As this is a single commit backport, the cloud-init SRU exception need not apply. An upstream integration test has been written for this issue (https://github.com/canonical/cloud-init/blob/master/tests/integration_tests/bugs/test_lp1910835.py).

A full run of the upstream test suite on Azure will therefore regression test the update generally and test this issue specifically: a log of a test run for each suite will be attached.

[Regression Potential]

The proposed change only modifies code paths used on Azure, specifically to revert to a previous behaviour: users unaffected by the bug should see no change (their keys will get to their instance via a different route), and users affected by the bug would have been unable to access their instances before (so cannot be relying on this behaviour in a way which we could break by fixing it).

[Discussion]
This should only affect public Azure VM launched which use Azure to --generate-ssh-keys either from the dashboard or from the az cli

Any other cloud-platform is not affected by this change.

== End SRU Template ==

  * cherry-pick 4f62ae8: Fix regression with handling of IMDS ssh keys
    (#760) (LP: #1910835)

== Original Description ==

cloud-init 20.4 or later will incorrectly add Azure publicKeys to .ssh/authorized_keys preventing ssh access for cloud-generated keys.

To reproduce: launch an ubuntu VM from the portal.azure.com choosing to generate new ssh key.

When the instance is launched you can see that the ssh-rsa content provided in the metadata publicKeys value contains CRLF characters (\r\n) thus splitting the content of the pubkey onto multiple lines when it is rendered into .ssh/authorized_keys.

the solution is either for IMDS to stop adding the CRLF characters or cloud-init to strip them out.

Here is the IMDS value provided to cloud-init

cloud-init query --format '{{ds.meta_data.imds.compute.publicKeys}}'

[{'keyData': 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCllNnyHXFWlMb9EKD9LZrOxt1d\r\nk/QxYwQ0HYEP8n6TUWoUsN3mv/Qk/qWH76Pa6f33hefzTFRiom7Ls/tJMcr/ki8R\r\n9FqyYOu0xxHmpXTUWFoZQCZtGRMtvDl/s76Wr1sCsE/ez+EcAPeGGm/B7jHtDAUW\r\nlkINfuPVBDfRtSfmnlCKS+sIf1XOqvRASGWi05zAW921T4OkiattyXyhaOimJOwq\r\n4jAXmydwtNCN2iGGKWS8YeXbtgveReqZVVKtcDKevgWdNyqZa69uq9tRujobjCh7\r\n6xxCkQcdCLospgqX79GBbdRys6mVxVgc349RIWjQwglRQpJwNzkeOG5Q+La2MEhu\r\niKqKJMvYVhil3khzMuZwzmTrGbRx0E8AS+Cm064RBgbcdjCW8dDYGLuk2eQ2v9Ht\r\n6eERfxMBNg3udv1jmiKpjjHIg99HDU4VqhL3aHmg+TSrxByd0cAgFBV+H0CiUVC9\r\nS2mLJ6Peu/HDwd88E8Wqiv3eAsjcaCRH3QiQVaU= generated-by-azure\r\n', 'path': '/home/ubuntu/.ssh/authorized_keys'}]

cloud-init renders this directly to .ssh/authorized_keys without processing the string, resulting in an invalid keyline:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCllNnyHXFWlMb9EKD9LZrOxt1d k/QxYwQ0HYEP8n6TUWoUsN3mv/Qk/qWH76Pa6f33hefzTFRiom7Ls/tJMcr/ki8R^M
9FqyYOu0xxHmpXTUWFoZQCZtGRMtvDl/s76Wr1sCsE/ez+EcAPeGGm/B7jHtDAUW^M
lkINfuPVBDfRtSfmnlCKS+sIf1XOqvRASGWi05zAW921T4OkiattyXyhaOimJOwq^M
4jAXmydwtNCN2iGGKWS8YeXbtgveReqZVVKtcDKevgWdNyqZa69uq9tRujobjCh7^M
6xxCkQcdCLospgqX79GBbdRys6mVxVgc349RIWjQwglRQpJwNzkeOG5Q+La2MEhu^M
iKqKJMvYVhil3khzMuZwzmTrGbRx0E8AS+Cm064RBgbcdjCW8dDYGLuk2eQ2v9Ht^M
6eERfxMBNg3udv1jmiKpjjHIg99HDU4VqhL3aHmg+TSrxByd0cAgFBV+H0CiUVC9^M
S2mLJ6Peu/HDwd88E8Wqiv3eAsjcaCRH3QiQVaU= generated-by-azure

this prevents ssh from actually reading the right key from azure:

$ ssh-keygen -lf /home/ubuntu/.ssh/authorized_keys

If we strip the CRLF (^M) characters and reparse with ssh-keygenm we see the proper key registered:

$ ssh-keygen -lf /home/ubuntu/.ssh/authorized_keys
3072 SHA256:PQ9EKxTKONJKFC2N56UpL6+Oc/cujfA9HpsF5VW2QDI generated-by-azure (RSA)

If cloud-init (or IMDS) were to strip those \r\n characters from each line ssh

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions