I'm trying to collaborate with some individuals that are not in my institution and are not allowed to connect to the internal network through VPN, however, ssh through a login server is allowed.
I.e. the collaborates can login using two successive ssh commands:
$ ssh loginserver
$ ssh repositoryserver
After logging in they can begin developing on the repository server. However, they would like to make a clone, and make modifications remotely, and then push changes back.
I know one can run mercerial commands through ssh, and this works fine for me (because I am on the network). I.e.:
$ hg clone ssh://uid@repositoryserver//path/to/repo
However, is there a way to run commands through the login server?
Something like:
$ hg clone ssh://uid@loginserver ssh://uid@repositoryserver//path/to/repo
Thanks for the help.
This is in principle possible, but the underlying ssh chaining is by necessity a bit fragile; if your institution's policies allow hosting on an external server, I'd consider that option first.
That said, yes, it can be done. First of all, your users will need to login to your repository server from your login server at least once (if you have a restricted setup, just cloning an hg repository once – and then throwing it away – will also work). This will set up an entry for the repository server in ~/.ssh/known_hosts, which is necessary for ssh chaining to proceed without user prompts. If your repository's server ssh configuration ever changes, this entry will become invalid and they will have to repeat the process after removing the entry from ~/.ssh/known_hosts or removing ~/.ssh/known_hosts entirely.
Second, they need to enable authentication agent forwarding on their machine (because otherwise they'll get prompted for a password or pass phrase, but won't be able to enter that). For that, they can do one of the following:
Add an entry to their ~/.ssh/config such as:
Host lserve
User uid
HostName loginserver
ForwardAgent true
The alternative to this approach is to tell Mercurial to use agent forwarding by adding the following entry to your ~/.hgrc or .hg/hgrc:
[ui]
ssh = ssh -A
The downside to doing this in your global ~/.hgrc is that agent forwarding will be done for every repository, including ones where you may not want that. Setting up ~/.ssh/config is the cleaner option and also allows you to simplify repo URLs.
You can also use the --ssh "ssh -A" command line option, but that's a lot of typing.
Depending on how they write their repo URLs, other configurations may work better. The above will allow the use of ssh://lserver//path/to/repo URLs. But the critical part is the ForwardAgent true line, which means that the remote server will query their local machine for authentication, rather than demanding a password or pass phrase. Needless to say, this also means that they need to have ssh agent authentication set up locally.
Next, you will have to create a shell script on loginserver that forwards the actual hg request. You can put it wherever you like (let's assume it is in /path/to/forward-hg:
#!/bin/sh
ssh repositoryserver hg "$@"
Once this is done, your friends can now access the remote repository as follows:
hg clone --remotecmd /path/to/forward-hg ssh://lserve//path/to/repo
hg push --remotecmd /path/to/forward-hg
hg pull --remotecmd /path/to/forward-hg
hg incoming --remotecmd /path/to/forward-hg
hg outgoing --remotecmd /path/to/forward-hg
Because this is a lot of typing, you may want to create aliases or put an entry in your local .hg/hgrc (caution: this cannot be done for hg clone, where you will still have to type it out or create, say, an hg rclone alias). This entry will be:
[ui]
remotecmd = /path/to/forward-hg
and tell Mercurial to add the requisite --remotecmd option to all commands that support it and that operate on this repository (note: Do NOT put this entry in your user's ~/.hgrc, only in the repository-specific one).
Finally, here is why this works: When accessing a remote repository, Mercurial will basically try to start $REMOTEHG serve --stdio (where $REMOTEHG is the remote Mercurial executable) and communicate with this process over stdin and stdout. By hijacking $REMOTEHG, this becomes effectively ssh repositoryserver hg serve --stdio, which will do it on the repository server instead. Meanwhile – assuming agent forwarding is setup properly, so that password prompts and the like don't get in the way – the local Mercurial client will remain completely unaware of this and only see the normal communication with the repository server over stdin and stdout (which get passed through unaltered by the ssh daemon on the login server).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With