如何在git push时指定要使用的SSH密钥,以便将gitorious作为镜像?

44

我有一个托管在git.debian.org (alioth)上的项目,我想配置一个post-receive hook,在http://gitorious.org上更新该仓库的镜像。

我想我需要使用git push --mirror gitorious命令。

现在,我需要在gitorious上授权Alioth,以便推送成功。我该怎么做?

我想我需要在gitorious上配置一个用户并创建一个ssh密钥。然后,在post-receive hook中执行git push时,确保使用该ssh密钥。

我可以使用~/.ssh/config文件,但问题是许多用户都可以在alioth上推送,每个人都需要登录并配置~/.ssh/config文件。相反,我希望有一个命令行选项或环境变量告诉ssh使用哪个密钥。我能做到吗?

此外,您是否有其他关于如何实现镜像的想法?另外,是否有可能反过来配置(gitorious推送到alioth)?


另一个答案,在我看来比下面的两个更好(简单的ssh-config条目):https://dev59.com/wGsz5IYBdhLWcg3wZm3Q#7927828 - Seth Battin
3个回答

39
答案可以在git参考手册中找到。

GIT_SSH

如果设置了此环境变量,则当需要连接到远程系统时,git fetchgit push将使用此命令而不是ssh。给$GIT_SSH命令将准确地给出两个参数:URL中的username@host(或只有host)以及要在该远程系统上执行的shell命令。

要将选项传递给要列出在GIT_SSH中的程序,您需要将程序和选项封装到一个shell脚本中,然后将GIT_SSH设置为引用该shell脚本。

通常,通过您的个人.ssh/config文件配置所需的任何选项更容易。请查阅您的ssh文档获取更多详细信息。

因此,我需要编写一个包装脚本,我编写这个push-gitorious.sh脚本:

#!/bin/sh


if [ "run" != "$1" ]; then
  exec ssh -i "$GITORIOUS_IDENTITY_FILE" -o "StrictHostKeyChecking no" "$@"
fi

remote=YOUR_SSH_GITORIOUS_URL

echo "Mirroring to $remote"

export GITORIOUS_IDENTITY_FILE="`mktemp /tmp/tmp.XXXXXXXXXX`"
export GIT_SSH="$0"

cat >"$GITORIOUS_IDENTITY_FILE" <<EOF
YOUR SSH PRIVATE KEY

EOF
cat >"$GITORIOUS_IDENTITY_FILE.pub" <<EOF
YOUR SSH PUBLIC KEY

EOF

#echo git push --mirror "$remote"
git push --mirror "$remote"

rm -f "$GITORIOUS_IDENTITY_FILE"
rm -f "$GITORIOUS_IDENTITY_FILE.pub"

exit 0

当然,您必须填写私钥(公钥仅包含在脚本中供参考)。您还需要填写gitorious的URL。

在post-receive挂钩中,您必须放置:

path/to/push-gitorious.sh run

如果不加运行选项,它会直接运行 ssh。

警告: 远程主机的身份没有经过检查。如果您想要,可以从 ssh 命令行中删除该选项并自定义 known_hosts。在这种用例中,我认为这并不重要。


1
我认为你可以指向一个ssh配置文件,然后在该文件中使用所有SSH的配置功能。 - Hedgehog

31
有两种方法可以在git命令行中指定任何你想要使用的keyfile来管理git站点。你不需要在配置文件或脚本中硬编码这个keyfile,只需直接在git命令行中提供即可。 方法1:使用GIT_SSH环境变量 在命令行中使用方式如下:
$ PKEY=~/.ssh/keyfile.pem git clone git@github.com:me/repo.git

要使用此命令,您需要进行一些预先设置。首先,创建一个包含以下内容的shell脚本:

#!/bin/sh
if [ -z "$PKEY" ]; then
    # if PKEY is not specified, run ssh using default keyfile
    ssh "$@"
else
    ssh -i "$PKEY" "$@"
fi

接下来,导出并设置GIT_SSH变量的值等于上面所述的shell脚本的位置。
$ export GIT_SSH=~/ssh-git.sh

~/ssh-git.sh是上面shell脚本的文件名。

脚本必须可执行,所以执行chmod命令:

$ chmod +x ~/ssh-git.sh

现在,您可以使用任何密钥文件运行此命令:
$ PKEY=~/.ssh/keyfile1.pem git clone git@github.com:me/repo.git

要为不同的主机使用另一个密钥文件:

$ PKEY=~/.ssh/keyfile2.pem git clone git@myothersite.com:other/repo.git

这支持使用任何想要使用的密钥文件。每次您需要使用一个密钥文件运行git时,只需将其提供给PKEY变量即可。只要GIT_SSH已经预先配置好,您可以忘记其他所有内容。
请注意PKEY变量。只要与shell脚本GIT_SSH指向的内容匹配,您可以使用任何名称。
方法2:使用包装脚本
包装脚本的使用方式如下:
$ git.sh -i ~/.ssh/keyfile.pem clone git@github.com:me/repo.git

这种用法很直观,因为它看起来像是使用ssh的-i选项运行。
这不需要预先设置shell脚本和GIT_SSH。您只需要通过git命令下载并运行这个单独的包装器脚本。
您可以在此处获取此包装器脚本的副本: http://alvinabad.wordpress.com/2013/03/23/how-to-specify-an-ssh-key-file-with-the-git-command/

方法一:使用GIT_SSH环境变量对我有用。谢谢。 - suhailvs

3
一个不需要任何外部脚本的更简单的替代方法是使用SSH别名。我知道原帖子的作者特别要求不要改变~/.ssh/config文件,但我怀疑这里有一个误解。
服务器上的本地用户与提交操作的执行者不同,可以是与"git push"执行者不同的人。
服务器上托管软件可以作为单个用户(通常是'git')运行。
提交操作执行者的身份只与提交的元数据相关,对服务器来说无关紧要,并且不需要在服务器上进行认证。
"git push"执行者的身份是相关的,并且基于ssh密钥在运行Git托管软件的系统上确定。
因此,在进行推送的系统上,即使在相同的本地帐户和远程服务器上,甚至在同一Git存储库中,也可以强制使用特定身份来使用ssh别名,按照下面所述的方法。
假设您在gitorious.org服务器上拥有您的常规帐户,我们称之为“developer”。您不希望自动使用您的“developer”帐户进行推送[1],因此您为同步创建另一个gitorious帐户,我们称之为“robot”。
仅用于自动化的是“robot”帐户: 第 1 步: 将“robot”添加到需要推送到的gitorious项目中。 第 2 步: 在本地机器上创建一个无密码的密钥(这将与gitorious上的robot帐户相关联)。
ssh-keygen -f ~/.ssh/id_rsa_robot

步骤三:将公钥~/.ssh/id_rsa_robot.pub上传到'robot'账户在gitorious上。

步骤四:gitorious上的git SSH URIs格式为git@gitorious.org:prj_or_user/subproject.git。在您的~/.ssh/config文件中添加以下行:

host robot.gitorious.org
        HostName gitorious.org
        IdentityFile ~/.ssh/id_rsa_robot
        IdentitiesOnly "yes"

这将确保:
  • 每当使用“robot.gitorious.org”主机名时,它将连接到gitorious.org(HostName选项),
  • 它将使用无密码密钥作为机器人在gitorius.org上进行身份验证(IdentiFile选项),并且
  • 即使您有一个ssh代理正在运行,它也会忽略默认密钥并使用无密码密钥(IdentiesOnly“yes”)。
第5步:假设您的项目在gitorious上的SSH URI为“git@gitorious.org:project/project.git”,在本地存储库中使用稍微修改过的主机名定义一个新的远程“autopush”。
git remote add autopush git@robot.gitorious.org:project/project.git

安装已完成,现在尝试通过“autopush”远程推送到gitorious。
git push autopush master

如果一切顺利并且有更改需要推送,你应该会看到成功以“robot”身份推送到“gitorious.org”。
[1] 对于自动推送,必须为帐户生成无需密码的密钥,但将其附加到gitorious的“developer”帐户意味着自动作业可以将更改推送到任何涉及“developer”的gitorious项目。

这很有趣,但需要更改.ssh/config。在原始问题的背景下,我们不处于正常的客户端/服务器关系中,我们控制不了客户端。我们有一个客户端-阿里奥斯服务器-基托里亚斯服务器的关系。在阿里奥斯上有多个用户帐户可以访问相同的git存储库。想法是在阿里奥斯服务器上安装钩子,并使所有可以推送到此存储库的用户运行该钩子。每个用户帐户在阿里奥斯服务器上都有一个.ssh/config文件。 - Mildred
我有类似的问题:需要在同一服务上为不同的帐户切换密钥,但我没有限制修改SSH配置文件。对我来说,这个解决方案非常好。 - wires

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接