-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
RFC: Filter cubbyhole responses based on cidr_block #1340
Conversation
I have to think more about whether this is functionality that we want to support here. I think the answer is "not yet": One comment on the code itself: the CIDR should be validated at write time, so that if it's invalid the writer knows about it before passing the token to the reader. |
@hashbrowncipher We had a discussion about this internally. We've already been looking into expanding the policy system to allow more controls, including CIDR access -- but we deferred CIDR access until we have a better story around trusting forwarding headers. So my initial thinking here was to defer this as well. However... ...If there's anywhere in Vault where the policy system is likely not the right way to go, it's probably So, I think we'll accept this, but with some extra work on top of what's here. I'm guessing that's not really an issue since you marked this RFC, so I'm assuming you were looking for initial feedback:
I say "authenticity of the IP address" because part of what makes it more complicated than it would at first seem to simply parse |
That's great! I'll make the changes suggested by your initial feedback. |
Ok. Time for a discussion of IP addresses. I've looked over #291, and it sounds like the matter of what to do isn't well settled yet. In my experience, correctly processing X-Forwarded-For headers is about as fun as unboxing a freshly Fedexed bobcat. I've seen it screwed up enough times at $EMPLOYER (using Apache's mod_rpaf and nginx's remoteip) that the idea of using it for security critical code scares me. In most of the cases I've seen, configuration errors arise when humans are tasked with keeping the IP whitelists up to date. When I have a choice, I have my load balancers decide which clients to trust by their TLS certificates, and skip IP whitelisting entirely. I initially thought PROXY protocol might not be quite so bad. Typically PROXY protocol is used by a Layer 4 load balancer, which can totally provide value for an application like Vault. I think the best case scenario would be to not give Vault's private keys to the L4LBs, and have my load balancer TLS encapsulate the (already encrypted) TCP stream. The proxy protocol header would be inside the LB's TLS encapsulation, but outside the client->Vault TLS encapsulation. I tested to see if this would be possible with HAProxy, but unfortunately HAProxy's implementation of PROXY protocol puts the PROXY header outside the TLS encapsulation. This leaves us with no method other than IP whitelists to determine whose PROXY or X-Forwarded-For headers to trust. You can tell I'm a fan of the end-to-end principle here. I think there's real value in having an uninterrupted TLS stream between the client and Vault. I'm not a fan of putting a load-balancer in front of Vault, but I can see why others might be. So the second-best case scenario, IMO, would be a load-balancer operating in TCP mode and sending PROXY protocol headers up to Vault. Operators would have to specify a whitelist of IP addresses that are allowed to send PROXY headers to Vault, but (fortunately) requests would outright fail when the configuration is wrong, providing fast-feedback. In AWS, this could be implemented by putting the ELB instances in their own /28 subnets. And now to add the warnings and documentation you requested. |
@jefferai I believe I've now addressed all of your initial feedback, thanks! This is my first open source Go code, so your critique is heartily appreciated. |
@hashbrowncipher Gosh, it's like you've been sitting in on our own conversations around headers, PROXY, and why I'm always encouraging people on mailing lists to not use load balancers, or if they must, do it in TCP mode so at least the TLS connection is end-to-end. But this is why I'm so lukewarm on cidr support. I have no problem in theory, but it's very easy for people to not understand why it doesn't work, and why it's not just a simple matter of parsing X-Forwarded-For. I'll take a look at this soon and may do some massaging of the exact message that goes back. |
I hate to do this but I have thought of another request: Can you make |
Sure. |
Hi @hashbrowncipher , Any update on this? Thanks! |
@jefferai last week was just awful for me, but I'll try to work on it this week. Sorry for the wait! Is there a deadline I'm trying to hit? |
Ish... We're gearing up for release (not this week) but could certainly
address this in the release after if it doesn't make it in time!
|
@hashbrowncipher For the moment I'm going to shift this to 0.6.1 but if it lands soon then I can shift it back. No rush! |
t.Fatalf("err: %v", err) | ||
} | ||
|
||
expected_warnings := []string{"cidr_block is specified, but may be unreliable. See warning in cubbyhole docs"} |
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 you move this string to a const in the package?
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.
Also a period at the end of the second sentence :-D
@hashbrowncipher Are you still interested in getting this in? |
Not as much as I once was. Would you like to close it? |
The other way around -- I was going to suggest that we could get it merged in, but if your interest is dropping off, I'd be interested in knowing why. I don't want to end up with a feature without a use-case :-) |
The use-case I imagined it for was wholly superseded by the EC2 auth backend, once I figured out how feature-full the EC2 auth backend was. I've also now changed jobs, which doubly obviates the use-case. |
Oh hah. OK. I'll close this for now then. |
The cubbyhole is designed (in part) for entities to securely exchange secrets, by sharing a token that they use to PUT data in and GET data from the cubbyhole. This change enhances cubbyhole security by allowing the entity which writes into the cubbyhole to specify cidr blocks of clients that are allowed to read a given path. The idea is that the writer, knowing the IP address to which it will send its cubbyhole token, will choose cidr blocks such that only is intended recipient can then read the value out of the cubbyhole.
By doing this, we supplement the cubbyhole security model. Currently, an eavesdropper must use the cubbyhole before its intended recipient, within the lease duration, and prevent any monitoring from noticing that the cubbyhole has been used by an attacker. This change makes it so that an eavesdropper must also be able to spoof packets coming from the intended recipient in order to use the Cubbyhole.
The code in this diff is taken nearly verbatim from the app-id backend.
cc @EvanKrall