我正试图与一些不在我所在机构的个人合作,他们不允许通过VPN连接到内部网络,但允许通过登录服务器进行ssh。
也就是说,合作者可以使用两个连续的ssh命令登录:
$ ssh loginserver
$ ssh repositoryserver
登录后,它们可以开始在存储库服务器上进行开发。但是,他们希望制作一个克隆,并远程进行修改,然后将更改推回。
我知道可以通过ssh运行mercedial命令,这对我来说很好(因为我在网络上)。即:
$ hg clone ssh://uid@repositoryserver//path/to/repo
但是,有没有办法通过登录服务器运行命令?
类似于:
$ hg clone ssh://uid@loginserver ssh://uid@repositoryserver//path/to/repo
谢谢你的帮助。
原则上这是可能的,但底层ssh链接必然有点脆弱;如果你所在机构的政策允许在外部服务器上托管,我会首先考虑这个选项。
也就是说,是的,这是可以做到的。首先,您的用户需要至少从登录服务器登录到存储库服务器一次(如果您的设置受到限制,只需克隆一次hg存储库,然后将其丢弃也可以)。这将在~/.ssh/known_hosts
中为存储库服务器设置一个条目,这对于在没有用户提示的情况下进行ssh链接是必要的。如果您的存储库的服务器ssh配置发生了更改,则该条目将变为无效,并且他们必须在从~/.ssh/known_hosts
中删除该条目或完全删除~/.ssh/known_hosts
之后重复该过程。
其次,他们需要在自己的机器上启用身份验证代理转发(因为否则他们会被提示输入密码或密码短语,但无法输入)。为此,他们可以执行以下操作之一:
在他们的~/.ssh/config
中添加一个条目,例如:
Host lserve
User uid
HostName loginserver
ForwardAgent true
这种方法的另一种选择是通过在~/.hgrc
或.hg/hgrc
中添加以下条目来告诉Mercurial使用代理转发:
[ui]
ssh = ssh -A
在全局~/.hgrc
中这样做的缺点是,将对每个存储库进行代理转发,包括您可能不希望这样做的存储库。设置~/.ssh/config
是一个更干净的选项,还可以简化repo URL。
您也可以使用--ssh "ssh -A"
命令行选项,但这需要大量的输入。
根据他们编写回购URL的方式,其他配置可能会更好地工作。以上内容将允许使用ssh://lserver//path/to/repo
URL。但关键部分是ForwardAgent true
行,这意味着远程服务器将查询其本地机器进行身份验证,而不是要求密码或密码短语。不用说,这也意味着他们需要在本地设置ssh代理身份验证。
接下来,您必须在loginserver
上创建一个shell脚本来转发实际的hg
请求。你可以把它放在任何你喜欢的地方(假设它在/path/to/forward-hg
:中
#!/bin/sh
ssh repositoryserver hg "$@"
完成后,您的朋友现在可以访问远程存储库,如下所示:
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
因为这需要大量的键入,所以您可能需要创建别名或在本地.hg/hgrc
中放入一个条目(注意:对于hg clone
,这是不可能的,因为您仍然需要键入别名或创建一个hg rclone
别名)。此条目将是:
[ui]
remotecmd = /path/to/forward-hg
并告诉Mercurial将必要的--remotecmd
选项添加到所有支持它并在此存储库上操作的命令中(注意:不要将此条目放在用户的~/.hgrc
中,只放在特定存储库中)。
最后,这是为什么有效的:当访问远程存储库时,Mercurial基本上会尝试启动$REMOTEHG serve --stdio
(其中$REMOTEHG
是远程Mercurial可执行文件),并通过stdin和stdout与该进程通信。通过劫持$REMOTEHG
,这实际上变成了ssh repositoryserver hg serve --stdio
,它将在存储库服务器上执行此操作。同时——假设代理转发设置正确,密码提示等不会妨碍——本地Mercurial客户端将完全不知道这一点,只能通过stdin和stdout与存储库服务器进行正常通信(登录服务器上的ssh守护进程未经更改地通过)。