Fixes T7034. Like HTTP, proxy requests to the correct host if a repository has an Almanac service host.
Details
- Reviewers
btrahan - Maniphest Tasks
- Restricted Maniphest Task
- Commits
- Restricted Diffusion Commit
rP8798083ad909: Proxy VCS SSH requests
Ran VCS requests through the proxy.
Diff Detail
- Repository
- rP Phabricator
- Lint
Lint Not Applicable - Unit
Tests Not Applicable
Event Timeline
This is kinda-maybe dangerous so I'm going to take a break and then self-review it with fresh eyes to see if I spot anything.
General thinking here:
I'm authenticating the user on the destination service by having the proxying service connect with a trusted device key and a special flag that says "I'm acting on behalf of @alincoln". A different approach I could have taken is to generate a "cluster SSH key" for each user and use that instead, which would be more similar to what we do with Conduit.
I didn't do that because it's more complex and significantly more work (to write, and to build the keys, and to use the keys), and I don't think it really increases security (if anything, it probably decreases security slightly, because the device key is harder for an attacker to get access to than user keys would need to be). The biggest drawback I see with this approach is that it's not the same as what we do with Conduit, which makes it harder to understand, but I think that's balanced by the smaller amount of code.
So the overall flow here is something like this:
Command | Runs On | Run By |
---|---|---|
git clone instance@host/repo | Your Laptop | User |
ssh -i alincoln.key -l instance host -- git-upload-pack repo | Your Laptop | git |
ssh -i device.key -l instance repo.service -- @alincoln git-upload-pack repo | Proxy Host | ssh-exec on proxy |
git-upload-pack repo | Service Host | ssh-exec on service host |
...if that makes any sense. The magic part there is in the third command, where we add @alincoln and the ssh-exec on the other end unpacks that to act as @alincoln.
The actual proxying is easy because in all cases we can just swap the VCS command out for one which has the exact same behavior but is nonlocal. We even get the whole SVN mess for free.
Caught a couple of things...
scripts/ssh/ssh-auth.php | ||
---|---|---|
31 | I'll add a "throw the key away" else here to future proof this. | |
33–34 | I just added this for logging, it doesn't do anything authentication-related. | |
scripts/ssh/ssh-exec.php | ||
150–159 | These variables are junk since we have another $user and a $user_name vs $username, I'll clean this up. | |
208 | This fixes a bug, stripping was incorrect here and we were logging without the "hg" / "git" / "svn" bit. |