kms: support CephFS fscrypt encryption with a KMIP KMS - #6521
Greenpepper15 wants to merge 8 commits into
Conversation
d34803a to
1be881a
Compare
| // GetSecret gets the raw secret via KMIP. | ||
| func (kms *kmipKMS) GetSecret(_ context.Context, _ string) (string, error) { | ||
| if kms.useCryptoRPC { | ||
| return "", fmt.Errorf("%w: fscrypt requires the key material, set %q to false", | ||
| ErrGetSecretUnsupported, kmipUseCryptoRPC) | ||
| } | ||
|
|
||
| key, err := kms.getKey(kms.uniqueIdentifier) | ||
| if err != nil { | ||
| return "", fmt.Errorf("failed to get key %q: %w", kms.uniqueIdentifier, err) | ||
| } | ||
|
|
||
| return base64.StdEncoding.EncodeToString(key), nil | ||
| } |
There was a problem hiding this comment.
Dear ceph-csi maintainers,
This PR changes pretty big but the core change "just" involves this one function.
The rest are changes revolve around testing this change.
1acd73d to
b078ed6
Compare
|
/test ci/centos/mini-e2e/k8s-1.35 |
|
@Greenpepper15 could you please add e2e tests around fscrypt PVCs? |
| if testCephFSFscrypt { | ||
| kmsToTest := map[string]kmsConfig{ | ||
| "secrets-metadata-test": secretsMetadataKMS, | ||
| "vault-test": vaultKMS, | ||
| "vault-tokens-test": vaultTokensKMS, | ||
| "vault-tenant-sa-test": vaultTenantSAKMS, | ||
| "kmip-fscrypt-test": kmipKMS, | ||
| } | ||
|
|
||
| for kmsID, kmsConf := range kmsToTest { |
There was a problem hiding this comment.
@Greenpepper15 could you please add e2e tests around fscrypt PVCs?
@black-dragon74 I integrated this new KMIP fscrypt integration into the existing fscrypt KMS e2e testing suite.
I can add the kmip fscrypt testing to more KMS testing scenarios though like "encrypted PVC-PVC cloning" and "encrypted snapshot" testing. Is that fine?
There was a problem hiding this comment.
I see you have enabled the said kms for fscrypt with the latest commit.
|
Also it seems like the test run failed due to flake in the NVMe e2e testing suite. |
|
Also when looking at the logs I can see these messages I think the fscrypt tests are skipped for RBD: And I do not any other logs related to testing fscrypt in Cephfs. So I assume they are skipped too. Can you pass the ceph-csi e2e test option "--test-cephfs-fscrypt" and "--test-rbd-fscrypt" to this command "/test ci/centos/mini-e2e/k8s-1.35" somehow. I think otherwise the fscrypt tests are not executed. Or what do you think? |
Run the encrypted PVC-PVC clone and the encrypted snapshot-backed volume specs against kmip-fscrypt-test. Both mount a volume that inherits the fscrypt metadata of its parent, a case the plain encrypted PVC spec does not cover. Requested: ceph#6521 (comment) Assisted-by: Claude Code <noreply@anthropic.com> Signed-off-by: David Mohren <david.mohren@clyso.com>
|
Can you @black-dragon74 re-run the e2e-acceptance test? It failed at the build ceph-csi image stage. The multi-arch-build / multi-arch-build also runs "build ceph-csi image" and succeeded on the same commit. So I am unsure what the problem can be except flake. |
|
/test ci/centos/mini-e2e/k8s-1.35 |
|
This pull request now has conflicts with the target branch. Could you please resolve conflicts and force push the corrected changes? 🙏 |
Run the encrypted PVC-PVC clone and the encrypted snapshot-backed volume specs against kmip-fscrypt-test. Both mount a volume that inherits the fscrypt metadata of its parent, a case the plain encrypted PVC spec does not cover. Requested: ceph#6521 (comment) Assisted-by: Claude Code <noreply@anthropic.com> Signed-off-by: David Mohren <david.mohren@clyso.com>
cad2b08 to
7fef5c3
Compare
|
/test ci/centos/mini-e2e/k8s-1.35 |
|
Again like here #6521 (comment) when I go through the e2e tests run logs I do not find evidence that the any fscrypt e2e tests (including the new kmip e2e tests) were run. I looked through the e2e log start and now it makes sense: This command is run to start the e2e tests Should I open a PR on for the ci/centos branch to add these e2e test flags? |
|
Ah, good catch! The tests run on CentOS Stream 9 (minikube with Podman driver). That means the kernel needs CephFS+fscrypt support. I do not know if that CentOS version is recent enough. Ideally the |
|
yup that sounds like a good idea. Let's see which tests crash. |
|
/test ci/centos/mini-e2e/k8s-1.35 |
|
@nixpanic I think this test may reflect a fscrypt test regression. The current test failure is: So the KMS test As far as I see it this is the reason This looks suspiciously like the new error type I introduced in #6539 specifically this commit 3d9af0e :( I think the test dies at the exclusive lock function here: ceph-csi/internal/cephfs/nodeserver.go Line 190 in e056908 (introduced 2 years ago. Lucky not me :D) For this operation BUT the e2e CephX user does not have Line 84 in e056908 (this line is 5 years old) (in normal deployment the CephFS user has I will add the x cap to this branch and see if this fixes this potential 2 year old regression. If my hypothesis is true we can figure out how to fix this. |
fscrypt needs one deterministic secret from the KMS and builds its own key hierarchy on the volume, so the stub that always answered ErrGetSecretUnsupported was the only thing keeping a KMIP KMS from backing CephFS file encryption and RBD encryptionType file. Return the key material of the managed symmetric key, base64 encoded so a volume stays openable with the fscrypt tool, and keep rejecting the request when USE_CRYPTO_RPC keeps cryptographic operations on the server. Assisted-by: Claude Code <noreply@anthropic.com> Signed-off-by: David Mohren <david.mohren@clyso.com>
Implementing GetSecret on the kmip provider makes it pass the fscrypt capability probe for RBD encryptionType file as well, but only the CephFS combination has been tested. Keep RBD failing at CreateVolume, as it does today, with an actionable error instead of the accidental probe rejection. The lock is removed once the combination is validated. Assisted-by: Claude Code <noreply@anthropic.com> Signed-off-by: David Mohren <david.mohren@clyso.com>
Document that a KMIP KMS backs CephFS fscrypt encryption when USE_CRYPTO_RPC is disabled, and warn that rotating or replacing the managed key makes existing volumes permanently unopenable. Assisted-by: Claude Code <noreply@anthropic.com> Signed-off-by: David Mohren <david.mohren@clyso.com>
No KMS speaking KMIP exists in the e2e environment, so the KMIP provider has never been covered there. Deploy PyKMIP, pinned together with the last dependency versions it works with, and provisions what the kmip KMS provider needs. PyKMIP identifies clients by the certificate CN and only lets the owner fetch a key, so the key-creating script uses the same client certificate as ceph-csi. PyKMIP 0.10.0 is the last release and predates current versions of its dependencies, so Python, SQLAlchemy and cryptography are pinned to the last versions it works with. Newer cryptography removed the legacy ciphers PyKMIP imports and the server crashes on startup. Assisted-by: Claude Code <noreply@anthropic.com> Signed-off-by: David Mohren <david.mohren@clyso.com>
Add a kmip-fscrypt-test KMS configuration pointing at the PyKMIP Service, with USE_CRYPTO_RPC disabled so GetSecret may fetch the key material, and run the encrypted PVC and app binding spec against it. The KMIP server is only deployed for fscrypt test runs, keeping the PyPI dependency out of every other CI job. Assisted-by: Claude Code <noreply@anthropic.com> Signed-off-by: David Mohren <david.mohren@clyso.com>
Run the encrypted PVC-PVC clone and the encrypted snapshot-backed volume specs against kmip-fscrypt-test. Both mount a volume that inherits the fscrypt metadata of its parent, a case the plain encrypted PVC spec does not cover. Requested: ceph#6521 (comment) Assisted-by: Claude Code <noreply@anthropic.com> Signed-off-by: David Mohren <david.mohren@clyso.com>
Signed-off-by: David Mohren <david.mohren@clyso.com>
6f1a9ea to
2029426
Compare
exclusive lock needs `x` caps which were not given to the e2e CephX user Signed-off-by: David Mohren <david.mohren@clyso.com>
|
/test ci/centos/mini-e2e/k8s-1.35 |
|
Okay after adding the Now its a different fscrypt on RBD test failure. Well I could look more into these fscrypt test failures in this PR or open a new PR that has the goal of making the fscrypt test suite work on CI. @nixpanic which option do you prefer? |
Describe what this PR does
This PR makes a KMIP KMS usable for CephFS fscrypt encryption in the most
minimal way possible by implementing
GetSecreton the existingkmipprovider.
ConfigureEncryptionprobes the KMS withGetSecretand rejects theconfiguration when the KMS answers
ErrGetSecretUnsupported, which thekmipprovider always did. The new implementation returns the key materialof the managed symmetric key, base64 encoded, and fscrypt uses it as a
custom_passphrase.Fetching the key material requires the KMIP
Getoperation, so the changeis gated on
USE_CRYPTO_RPCbeing"false".The base64 encoding keeps the passphrase printable so that a volume remains
recoverable with the upstream
fscrypttool by runningbase64on the keyexported from the KMS. I chose base64.StdEncoding but another ceph-csi
secret encoding uses base64.URLEncoding (see question section for the
motivation).
RBD with
encryptionType: filewould pass the same capability probe and usethe same
fscrypt.Unlock, but that combination is untested, so this PRexplicitly rejects it in
configureFileEncryptionwith an error. RBDbehavior is therefore unchanged.
Is there anything that requires special attention
Do you have any questions?
E2e placement: should the two e2e commits move to a separate PR, or is
keeping them here okay? Please check the KMIP e2e I added.
Passphrase encoding: should the passphrase use
StdEncodingor theURL-safe alphabet that
generateNewEncryptionPassphraseuses? fscryptderives the protector key from the exact passphrase bytes, so the encoding
can never change afterwards. Either would work within the driver. What
breaks with
URLEncodingis only the manual recovery path with thebase64(1)tool:base64(1)emits the standard alphabet, so aby-the-book recovery would derive a different passphrase for any key whose
bytes encode to
+or/, and the unlock will fail for some keys.StdEncodingis therefore a recovery-contract choice, not a within-drivercorrectness constraint.
Provider naming: should
GetSecretown the barekmipprovider name,or use a different name to keep the bare name free for other KMIP
integrations? This PR makes the bare
kmipprovider hand out key materialthrough
GetSecret.KMIP test server: should the KMIP e2e use PyKMIP? Almost nothing else
fits: the test server must speak exactly what the kmip provider speaks,
run in a plain Pod without a license, and let a script create a key.
PyKMIP is what Ceph itself tests the RGW KMIP encryption against
(
qa/tasks/pykmip.pyin the teuthology suite), and what OpenStackBarbican's functional gate uses for its KMIP plugin. The one maintained
open-source alternative is Cosmian KMS (BUSL 1.1, KMIP 1.0-2.1, binary
socket server with TLS client authentication). If you prefer a maintained
implementation, I can switch the e2e to it.
PyKMIP 0.10.0 is the last release, so the pod pins the last dependency
versions it works with (Python 3.11, SQLAlchemy 1.x, cryptography
41.0.7). Newer cryptography removed the legacy ciphers PyKMIP imports
and the server crashes on startup.
Testing caveat: I could not run the new e2e spec on my setup, because it
needs a Ceph cluster together with a CephFS fscrypt capable kernel. The
spec itself has therefore not been executed and I am piggybacking the
ceph-csi CI to exercise it. Note that no CI job currently sets
--test-cephfs-fscrypt, so a run needs that flag. What I did verifyagainst a live PyKMIP server on a scratch cluster is the deployment and
provisioning flow.
Is the change backward compatible?
kmipusers are unaffected:RequiresDEKStore,EncryptDEKandDecryptDEKare untouched, there is no configuration schema change, andthe only behavioral change is that a configuration that used to fail now
succeeds.
by an older release, which still answers the capability probe with
ErrGetSecretUnsupported.UNIQUE_IDENTIFIERat adifferent key, makes every existing volume permanently unopenable. There
is no re-wrap path.
Related issues
Fixes: #6324
Future/now concerns
There are different ways to add KMIP support to CephFS fscrypt. I chose the
most minimal one, but the other directions remain possible and might make
more sense for different use cases.
Planned follow-ups:
encryptionType: filewith KMIP (an RBD e2e spec) and removethe lock in
configureFileEncryption.Checklist:
guidelines in the developer
guide.
Request
notes
updated with breaking and/or notable changes for the next major release.
Show available bot commands
These commands are normally not required, but in case of issues, leave any of
the following bot commands in an otherwise empty comment in this PR:
/retest ci/centos/<job-name>: retest the<job-name>after unrelatedfailure (please report the failure too!)