-
Notifications
You must be signed in to change notification settings - Fork 861
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
Support encrypted and signed user data #5599
base: main
Are you sure you want to change the base?
Conversation
@@ -0,0 +1,129 @@ | |||
"""These tests are for code in the cloudinit.user_data module. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that I moved non-PGP related tests here as they fit better here.
# that we attempt to decode said payload so that the transformed | ||
# data can be examined. | ||
parent_ctype = None | ||
if ctype in TRANSFORM_TYPES: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made a necessary refactor to this section involving setting the mime type of transformed messages. Please double check my logic 🙂 .
I did ensure that gzipped user data still works properly with this code.
@@ -0,0 +1,201 @@ | |||
.. _pgp: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If running this guide, don't be like me and forget to install this branch into the container and then be mad it doesn't work at the end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First pass review
doc/rtd/howto/pgp.rst
Outdated
|
||
Save this file to your working directory as `cloud-config.yaml`. | ||
|
||
Encrypt the user data using the public key of the encrypting user and the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Encrypt the user data using the public key of the encrypting user and the private key of the signing user:
The signing key doesn't do encryption. How about:
Encrypt the user data using the public key of the encrypting user and sign it using the private key of the signing user:
doc/rtd/howto/pgp.rst
Outdated
using the existing key ring in the snapshot, we do this for a few reasons: | ||
|
||
* Users may not want these keys in any key ring by default on a new instance | ||
* Keys may be exported from any system without needing to be concerned with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand what this is trying to say.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can export keys from a system I'm not making an instance from without trying to move gpg keyrings around that may not even be compatible with the target system.
I can wordsmith it.
def decrypt(self, data: str) -> str: | ||
"""Process data using gpg. | ||
|
||
This can be used to decrypt encrypted data, verify signed data, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This only verifies signed data if the data is signed, correct?
IOW, if a user wants their user data to be signed and encrypted, an attacker would need only to acquire the public key of the encryption key and then provide their own unsigned encrypted payload to cloud-init, and cloud-init will not verify it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. I pushed a new version that checks that gpg verified the signature if we require the signature.
884b803
to
344c3bc
Compare
Hello! Thank you for this proposed change to cloud-init. This pull request is now marked as stale as it has not seen any activity in 14 days. If no activity occurs within the next 7 days, this pull request will automatically close. If you are waiting for code review and you are seeing this message, apologies! Please reply, tagging TheRealFalcon, and he will ensure that someone takes a look soon. (If the pull request is closed and you would like to continue working on it, please do tag TheRealFalcon to reopen it.) |
344c3bc
to
36719d8
Compare
@holmanb , I have rebased the branch (only minor format.rst conflicts). It should be ready for review again. |
cloudinit/gpg.py
Outdated
data=data, | ||
update_env=self.env, | ||
) | ||
if require_signature and "gpg: Good signature" not in result.stderr: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't love depending on stderr for this behavior. Are there alternatives that might be better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated. I thought the same thing as I wrote it but also couldn't think of a better idea. Not sure why I didn't think of the verify command sooner.
Rather than an top-level `allow_userdata` key, instead use a `user_data` dict. This is to better align with the top-level `vendor_data` keys.
Cloud-init user data often contains user secrets including passwords and private keys. This data has always been submitted in plain text. To protect this data's confidentiality and guarantee its authenticity, this commit add the ability to have this data encrypted and signed. A new user data format is added allowing for an ASCII armored PGP MESSAGE. If detected, cloud-init will import into a temporary keyring any keys provided in /etc/cloud/keys and use these keys to decrypt and/or verify the provided data. After decryption, the resulting message will be treated as user data as before.
f3be313
to
a1186a8
Compare
Rebased away the conflict. @holmanb , can I get priority on this review? We're getting close to the end of the cycle and I'd like to get this one done so I can focus on my other items with less context switching. |
Proposed Commit Message
Additional Context
The
squash:
commits are just to make reviewing easier. I plan to squash them before merging.Test Steps
Merge type