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
ca: fix storing the leaf signing cert with Vault provider #11671
Conversation
3e2c10a
to
d155347
Compare
agent/consul/leader_connect_test.go
Outdated
store := s1.caManager.delegate.State() | ||
_, activeRoot, err := store.CARootActive(nil) | ||
require.NoError(err) | ||
require.Equal(intermediatePEM, activeRoot.LeafSigningCert()) |
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 is the line that fails before the bug fix. The other test changes are to be sure it did not exist in other places.
if needsSigningKeyUpdate { | ||
rootCA.SigningKeyID = expectedSigningKeyID | ||
} |
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 line was moved up to the place where we set needsSigningKeyUpdate
, to keep the logic together.
@@ -550,13 +563,10 @@ func (c *CAManager) primaryInitialize(provider ca.Provider, conf *structs.CAConf | |||
rootCA.IntermediateCerts = activeRoot.IntermediateCerts | |||
c.setCAProvider(provider, rootCA) | |||
|
|||
c.logger.Info("initialized primary datacenter CA from existing CARoot with provider", "provider", conf.Provider) |
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 is unrelated, but something I noticed while working on this.
I'm pretty sure that previously we would not log anything when a server initializes itself using an existing stored CARoot
. I guess this would happen if the raft leader election on any cluster that already had a root setup.
I made the log message slightly different, so that it's clear this initialization was from an existing CARoot
.
agent/consul/leader_connect_ca.go
Outdated
c.logger.Info("Correcting stored SigningKeyID value", "previous", rootCA.SigningKeyID, "updated", expectedSigningKeyID) | ||
if activeRoot != nil && rootUpdateRequired { | ||
c.logger.Info("Correcting stored CARoot values", | ||
"previous-signing-key", rootCA.SigningKeyID, "updated-signing-key", expectedSigningKeyID) |
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.
might've gotten confused by the control flows here but wouldn't rootCA.SigningKeyID
& expectedSigningKeyID
be the same by the time we reach lines 553-54?
Since on line 531 we set:
rootCA.SigningKeyID = expectedSigningKeyID
did I miss something obvious 🤔 ?
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.
Ya, I found this if / else if
to be not super obvious.
All of this logic (from about line 523) is about fixing existing data stored in raft and the state store. So line 531 is where we fix the local reference, but we still need to persist that fix back into raft with ApplyCARequest
.
So here on line 553 it is correct in the local variable, but we are logging that we are about to (later on below the if / else if
) persist it.
I would like to refactor this some more. #11687 makes some more changes in this area (for a different reason), and it moves the activeRoot
call earlier in the function. I think once that is done we can probably refactor this to make it a bit more obvious that the logic is:
if nothingToFix {
return
}
applyFixesToRaft
return
Does that make sense, or am I missing something?
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 think that makes sense and that I'm almost there!
So won't the logging actually log two identical values?
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.
Ah, I see what you are saying now. Yes! I did mess up the logging. I've moved the log up to the if block where we check if it needs update, so it should log the correct thing now.
That allowed me to remove the else if
and make it just an if
, which is also nice.
Thanks for working on this 🎉 -- left a couple of comments but otherwise LGTM! |
This will be used in a follow up commit.
d155347
to
b631479
Compare
We were not adding the local signing cert to the CARoot. This commit fixes that bug, and also adds support for fixing existing CARoot on upgrade. Also update the tests for both primary and secondary to be more strict. Check the SigningKeyID is correct after initialization and rotation.
As a method on the struct type this would not be safe to call without first checking c.isIntermediateUsedToSignLeaf. So for now, move this logic to the CAMananger, so that it is always correct.
b631479
to
28a8a64
Compare
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 🚀 !
// This state shouldn't be possible to get into because we update the root and | ||
// CA config in the same FSM operation. | ||
if activeRoot.ID != rootCA.ID { | ||
return fmt.Errorf("stored CA root %q is not the active root (%s)", rootCA.ID, activeRoot.ID) | ||
} | ||
|
||
// TODO: why doesn't this c.setCAProvider(provider, activeRoot) ? |
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.
+1
🍒 If backport labels were added before merging, cherry-picking will start automatically. To retroactively trigger a backport after merging, add backport labels and re-run https://circleci.com/gh/hashicorp/consul/513905. |
…-intermediate ca: fix storing the leaf signing cert with Vault provider
…-intermediate ca: fix storing the leaf signing cert with Vault provider
Fixes #10826
Fixes #10532
We were not saving the leaf signing cert on the
CARoot
when the Vault provider was initialized. This was only a problem for API users (not envoy and xDS) because this extra code was masking the bug.In #11661 I'd like to remove that masking code (because it is unnecessary, and because we need to change the Provider interface, so fewer callers makes that easier).
This PR updates an existing test to catch the bug, then fixes the bug. I added a few more assertions to both the primary and secondary test cases to make sure we did not have a similar bug in other places.