-
Notifications
You must be signed in to change notification settings - Fork 781
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
consul-template "vault_agent_token_file" should support wrapped format from vault agent #1498
Comments
I'm working on reproducing this using vault agent but my vault skills need some work first. I haven't messed with Vault much directly and can't get the cert client auth to work.. so I'm going to pause this until I have a better understanding of Vault as there are other bugs that need my attention. If anyone knows a way to reproduce this with consul-template itself, I could probably make faster progress. Not saying I won't get back to it, but I'm planning on a release soon and don't want to spin my wheels to long. |
Hey @drawks, sorry for the long delay getting to this. I still haven't had time to get a test setup for this working but I'm going to take a stab at it anyways. Based on the issue filed I should be able to check to see if the token is embedded in a json object as described and pull the token value from it. I'll go strictly off documentation and see how it goes. |
No apology necessary! Thanks for your time/attention. I've been working on other things, but can shift focus back to this as soon as you have something testable. |
I'll see if I can rig up a test using docker or something today so that I can confirm/deny that the fix is good AND also provide a re-usable test case |
That would be incredibly awesome @drawks. Thanks! |
I'm running into a few issues while testing, but have run out of time for the week. Will return to this on Tuesday. The tldr so far is that your change does result in the wrapped token being read from disk and unwrapped. However subsequent template actions against vault are not being made with the unwrapped token as far as I can tell. Using the hmac hashes in vaults audit log I can see the unwrap happen successfully and inserting a longline into the code I can see that the unwrapped token is captured in |
Thanks for the feedback @drawks! I'll look over the code again with the issue you found in mind, see if I can find any reason for it. Thanks again for your help on this. Very much appreciated. |
As far as I can piece together the timeline from audit logs:
I'd just include the logs, but they are quite verbose and all the values are hmac hashes. |
Sorry to ask.. but where does |
That's exactly the problem, it seemingly comes from nowhere. I only have the hash of it, but it matches neither the wrapped (A) not unwrapped (B) token hashes |
I'm thinking it might have to do with the I'm going to re-work the PR to set the token before the unwrap call again. I'll push it up so you can test it when you get a chance. I'll dig a bit more to see if I can come up with any other possibilities. |
Was finally able to replicate the original issue using the |
Just wanted to note that I've done this. |
Ok, picked this back up today and Put together the following log which includes addional loglines where unwrap, set and reads occur in consul-template. https://gist.github.com/drawks/44dfb9437bd27f5b09d9064e1c7a95b3 You can see at lines 28-30 that the wrapped token file is read from disc correctly, the wrapping token is read and then the unwrap operation occurs followed by a setToken to the correct unwrapped token. I make an additional call to the client's So I think your code changes to read and unwrap the token are correct, but we've got some issue where we're updating the incorrect client object. p.s. I also changed my test setup to use approle authentication so that it matches your test setup; just in case we ended up in two different corners. p.p.s. just so I don't get dire warnings from others reading this, the attached log is the result of a completely ephemeral vault instance setup in a vm. There are "secrets" in the logs, but they are of zero value and not used in any production application nor are the token being used for securing anything. |
Thanks for digging in @drawks, this is a big help. Just to be sure... were those new tests with the updated version I pushed on Friday? Thanks. |
Yes, I added my loglines ontop of your latest commit in the branch |
Aha! disabling the watcher against the I /think/ the proper behavior would be. edit: to be clear, there should never be an attempt to unwrap the wrapping token more than once. I see both the case with the watcher could be a problem as well as the case where consul-template receives a HUP. I /think/ in both cases it makes sense to skip the unwrap logic IF the wrapping token has been seen before. |
Great find! I was on my way as I was in the process of tracking down every SetToken call but hadn't made it to that one yet. I'll rework things to have it use the wrap_ttl check as well and push that in a few. Thank you!! |
I think the easiest way to prevent attempts at re-unwrapping the token would be to save the |
I went simple with my change in CT and just added the unwrapTTL call to the VaultAgentTokenQuery. I'm going to give it more thought when I port it to hashicat as I wanted to rework the watcher using a dependency internally like that anyways as it has always been sort of confusing. I'll think about your suggestion when I handle this with the next round of Thanks again. Pushing the update version now.... |
Wait. That won't work as the token in the file is wrapped and the VaultAgentTokenQuery doesn't unwrap it either. I'm going to refactor a bit to add common SetToken wrapper that handles the wrap_ttl json as well as unwrapping the token if necessary before calling the SetToken. |
Another refactoring done. |
Your latest commit isn't /quite/ right, since it will still result in the watcher attempting to unwrap the wrapped token, but the unwrap will fail because we've already unwrapped it once.
As suggested earlier in this thread, we need either the wrapped token file to be deleted after read and/or consul-template to remember the edit: I wouldn't mind taking a whack at getting this sorted, but was trying to avoid stepping on you as it seems you're actively updating your branch. |
Right. It unwraps it once in the client_set code on startup, then it does it again when starting up that VaultAgentTokenQuery dependency (which then just waits for file updates). I'm going to see if I can differentiate between the api returns for unwrapping already unwrapped tokens (docs imply this is possible). Basically I want to see if there is a way to do this without keeping track of the wrapper's state. Please take a whack if you'd like. Communicating ideas about code in code works great. And if we like you're solution better we can use it. I appreciate the empathy but I enjoy the art of it and love to collaborate so no worries. Thanks. |
FYI... the docs were misleading and there is no differentiation. It always returns the same error whether provided with a already unwrapped token or garbage. Not surprising though. Deleting the file seems like it could work but also seems like it could break things. Plus you can unwrap tokens from other sources than files. At this point I'm down to 2 ideas.. keeping the state (as you suggested) or ignoring the unwraping errors in some cases (eg. having VaultAgentTokenQuery log instead of return unwrapping errors). |
Thinking about this I'm wondering why not just always try to unwrap a secret, use the returned secret if given otherwise just go on with the token as if it is good (doesn't need unwrapping). Eliminate the option and just always have it check. The only downside I see are a few extra unwrap calls. I'm asking about this internally in case it goes against some Vault recommended setup/use/etc. |
Always sending the token to the unwrap API and then ignoring the error has the potential for causing a lot of audit log noise on the vault server. |
In my experiences audit logs are pure noise that you need to sift/filter for anything interesting. But.. there is the option already and we could just keep that to eliminate the excess noise but change the unwrap logic to only log issues after that first unwrap which would still error (for early feedback). That should keep the audit noise to a minimum while eliminating the need to track the wrapping state of the token. |
It'd be pretty easy to eliminate the additional check at startup, so it doesn't always try twice. Only need to have the VaultAgentTokenQuery skip updating the token on first use (as client_set has already handled it). |
Skipping the first call makes testing a PITA and doesn't really buy much. Not skipping yet. |
The current PR keeps the unwrap option and only tries to unwrap if set. It will return an error (and exit) if the initial client_set token set call failes but will only logs the failures in the monitoring code (VaultAgentTokenQuery). This should hit a decent spot where it won't need to keep state and it won't add a lot of audit noise (1 extra log entry at startup and 1 per renew if the token isn't wrapped after the first which I don't think should happen). IMO the 1 extra at startup shouldn't be an issue and if it becomes one it can be addressed after the fact by skipping that first call and reworking the tests. @drawks .. will that work for your use case? |
Just tested your branch and I'm still seeing a failure
I've not re-added any instrumentation, nor really looked over the code changes (an expensive context switch at the moment) but I suspect that we're still somehow setting the token an extra time. edit: sure enough, commenting out the watcher on the token file results in this going back to a working state |
First let me say thanks again @drawks for all the help with this. Weird. I am able to replicate this error and will look into it. |
I see the problem. To scatter brained to notice the obvious, that it sets the token before trying to unwrap it so it is wrong the 2nd time through. Bounced around too much with my thoughts on this. Going to take a step back and rethink a bit. |
Hey @drawks. Just to keep you up to date I've switched from trying to slap a quick fix on this to thinking how I want this fixed in a more permanent way that makes sense for the hcat library as well (where I have an issue to rework this). I'm working though it now and will post a new PR when done. |
Rock and roll! Thanks for working on it. |
I pushed up the branch (as a backup) with my refactor if you are curious. It's not done yet as there are issues with the integration tests conflicting and the commit message is an obvious placeholder, but this is the basic idea. https://github.com/hashicorp/consul-template/tree/vault-token-file-refactor Only if you are curious... if not I'll finish it up next week and comment here when the PR is up. Thanks. |
Configuration
vault-agent.hcl
consul-template.hcl
Command
vault agent -exit-after-auth -config=vault-agent.hcl && sudo consul-template -config=consul-template.hcl
Debug output
The contents of the sink file from vault agent, showing that
wrap_ttl
results in a json blob and not just a bare wrapping token:Expected behavior
consul-template should recognize the json format of the vault agent's sink file when using wrap_ttl and extract the
token
field and then proceed as usual.Actual behavior
consul-template slurps the entire contents of the sink file and sends it to the unwrap endpoint as a wrapping token.
Steps to reproduce
wrap_ttl
setvault_agent_token_file
set to the same file along withrenew_toke = true
References
Are there any other GitHub issues (open or closed) that should
be linked here? For example:
The text was updated successfully, but these errors were encountered: