-
Notifications
You must be signed in to change notification settings - Fork 138
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
fix ssec: missing base64 encoding and md5 hash #225
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Gilbert Scheiblhofer <[email protected]>
Signed-off-by: Gilbert Scheiblhofer <[email protected]>
I'm pretty new to velero, i tried this mr locally and noticed there are issues while accessing the logs and futher contents from the bucket, probably caused by not passing the sse-c headers. am i holding it wrong or is there still something missing. |
@@ -242,7 +247,7 @@ func readCustomerKey(customerKeyEncryptionFile string) (string, error) { | |||
fileHandle.Close() | |||
|
|||
if nBytes != 32 { | |||
return "", errors.Wrapf(err, "contents of %s (%s) are not exactly 32 bytes", customerKeyEncryptionFileKey, customerKeyEncryptionFile) | |||
return "", fmt.Errorf("contents of %s (%s) are not exactly 32 bytes", customerKeyEncryptionFileKey, customerKeyEncryptionFile) |
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.
Is this necessary? This will mean the log trace won't propagate to velero pod logs with stack trace
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.
The point of the fix is that err is always nil in this situation and errors.Wrapf here always returns nil, so to velero looks like key was read successfully (but is ""). I encountered this situation during testing, having a key < 32 bytes and no errors showed up in velero (but overall encryption did not work).
With this change, now the error is shown in the Backup-Resource correctly (but no stacktrace though).
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.
ahh.. got it. Make sense. Here's a revised suggestion.
return "", fmt.Errorf("contents of %s (%s) are not exactly 32 bytes", customerKeyEncryptionFileKey, customerKeyEncryptionFile) | |
return "", errors.Errorf("contents of %s (%s) are not exactly 32 bytes", customerKeyEncryptionFileKey, customerKeyEncryptionFile) |
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.
thanks..PR updated
@@ -186,7 +189,9 @@ func (o *ObjectStore) Init(config map[string]string) error { | |||
if err != nil { | |||
return err | |||
} | |||
o.sseCustomerKey = customerKey | |||
o.sseCustomerKey = base64.StdEncoding.EncodeToString([]byte(customerKey)) |
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.
Why are we encoding string to []byte then string again?
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.
So, your idea is to change the function readCustomerKey to return a []byte instead of a string? Would make sense, I can update the PR for 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.
I see now that the description says "<your_b64_encoded_32byte_string>" which is wrong, the key must be plain and is then encoded to base64 before sending it.
Does "the key must be plain" holds true prior to this PR? Are we creating breaking change from customerKey is base64 -> customerKey must be plain?
Is the reason you are adding encoding here is because you wanted plain key instead?
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.
Yes, the question is, should the key be stored plain or base64 encoded in the container? I assume plain because here
keyBytes := make([]byte, 32) |
we read exactly 32 bytes. If the key would be base64 encoded, then it would be longer then 32 bytes, and the mentioned line would be incorrect and needs to be fixed.
To test it successfully, you must mount the encryption key into the velero container (eg. from a secret) and then reference the file containing the key in the config of the BackupStorageLocation. See description here: https://github.com/vmware-tanzu/velero-plugin-for-aws/blob/main/backupstoragelocation.md. I see now that the description says "<your_b64_encoded_32byte_string>" which is wrong, the key must be plain and is then encoded to base64 before sending it. |
Signed-off-by: Gilbert Scheiblhofer <[email protected]>
@gschei you're right that's not my concern. I get it to work after checking the actual code not the problem, but once i enable the encryption part i'm unable to call |
EDIT: Nevermind, handled totally differnent besides that, the internal kopia data mover seems to have trouble as well.
Can you confirm csi data movement works with sse-c backup locations? P.S by dropping the sse-c key at all, it just works. |
Yes I see |
It looks like AWS
|
is currently required until vmware-tanzu/velero#6167 gets implemented. |
One additional remark regarding the encryption key: original implementation ac31cd9 (from feb/22) stated that the key should be a "32 byte string". Later (oct/23) a863977 a documentation update was done which apparently was wrong because it contradicts the original statement, saying that the key should now be a "base64 encoded 32 byte string" which is not correct, because within the code only the first 32 bytes are read anyway (and base64 endoding will make the string longer). From my point of view current implementation is not working at the moment - once due to missing base64 (or alternatively correct parsing of base64 encoded key) and also due to missing md5 hash - a problem which appeared later.
@kaovilai @reasonerjt Could you please have a look at this again and merge if OK? |
Please update readme and or backupstoragelocation.md to reflect this PR or the current state of using customerKey since you're probably most versed in how to use this PR as is. |
velero-plugin-for-aws/backupstoragelocation.md Lines 76 to 87 in 2dd6bcb
Is this accurate as is? |
Signed-off-by: Gilbert Scheiblhofer <[email protected]>
@kaovilai I clarified the description. The point is, when I base64 encode the key within the kubernetes secret, it will be automatically base64 decoded by kubernetes when mounted into the container. |
# The customerKeyEncryptionFile points to a mounted secret within the velero container. | ||
# Add the below values to the velero cloud-credentials secret: | ||
# Eg. add to the velero "cloud-credentials" secret this entry with the base64 encoded key | ||
# (will be decoded when the secret is mounted) | ||
# customer-key: <your_b64_encoded_32byte_string> |
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.
Should this line be uncommented? or is the encoded customer-key only supposed to be populated by the object_store.go?
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.
Can it be expected that someone put in encoded 32 byte string instead of specifying the file name in the key below this one?
If so
# customer-key: <your_b64_encoded_32byte_string> | |
customer-key: <your_b64_encoded_32byte_string> |
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.
The function readCustomerKey
currently only supports reading the secret from a file mounted inside the velero container. So the example here shows how to put the key into the secret, therefore it is just a comment and not part of the BSL configuration. I think it make sense, not to provide the senstive key as parameter, but only as secret.
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 lgtm. Just some clarifications. Thanks for the PR!
This PR is based on #224 and replaces PR #217 (which has some code duplication and is not complete).
It fixes these issues:
I tested this change successfully with an encrypted backup and restore with Velero and S3 Bucket.