选择要与Git一起使用的私钥


81

我有2个需要2个不同SSH密钥的Git服务器。

git clone user1@server1:blahblahblah使用~/.ssh/id_rsa,但是我需要根据要连接的服务器指定要使用的密钥。

这个工作需要什么Git命令行参数?(我正在运行Linux。)


2
可以在superuser.com/questions/232373/…上回答此问题。
Daira Hopwood


Answers:


59

如果您通过SSH连接,则密钥将由SSH参数而不是git参数控制。

SSH在~/.ssh/config文件中查找配置参数。修改该文件并为两个Git服务器添加IdentityFile条目,如下所示:

Host server1.whatever.com
  IdentityFile /path/to/key_1
Host server2.whatever.com
  IdentityFile /path/to/key_2

本文有更多详细信息。


12
那没有回答问题。问题是,当ssh处理授权时,如何给git这个参数?
Keks

@Keks:你无法通过的git命令行通过SSH参数。此答案提供了一种解决方法。还有其他可能的解决方法,例如git.wiki.kernel.org/index.php/…。请注意,该方法也不使用命令行参数来修改ssh行为。
卡梅隆·斯金纳

12
是的,但是您原来的答案没有回答问题。您还可以使用ssh-agent和使用ssh-add,然后仅使用git。当git通过ssh连接时,该密钥已启用。您会发现有几种方法,您的原始答案并没有真正的帮助。
keks

这几乎是仅链接的答案。您能否在答案中总结文章的相关内容?
Flimm

@Flimm:添加了摘要。
卡梅隆·斯金纳

92

还有另一种可能性。那是要设置的core.sshCommand,例如

git config --local core.sshCommand "/usr/bin/ssh -i /home/me/.ssh/id_rsa_foo"

在一种特定的情况下,该策略特别有用:那就是当您在Github上拥有多个帐户时,因为Github的所有帐户ssh都存在,git@github.com并且它使用ssh密钥来确定您是哪个Github用户。在这种情况下,您.ssh/configssh-agent不会做您想做的事情。

更新—在拥有本地存储库之前,不能运行上述操作,因此,如果您要克隆远程存储库,则需要根据drewbie18的答案手动指定密钥:

git clone -c core.sshCommand="/usr/bin/ssh -i /home/me/.ssh/id_rsa_foo" git@github.com:me/repo.git

克隆存储库后,可以使用git config命令将其永久设置。


7
这应该是选定的答案。所需的配置很好地定位在存储库中,该存储库需要使用不同的ssh密钥来访问不同的git服务器。无需修改〜/ .ssh / config(甚至在GitHub上有多个帐户的情况下,甚至无需修改/ etc / hosts)。
mr.b

1
但是,有一个问题:您无法在配置存储库之前对其进行克隆,而要对其进行配置,则需要先对其进行克隆。或者,您可以git init进行回购,在本地对其进行配置以使用正确的ssh命令,然后添加一个远程(3个步骤,“ git clone”只有1个步骤)。
mr.b

3
要克隆仓库,我将在下面使用@Guss的解决方案,方法是设置GIT_SSH_COMMAND环境变量。但是在正常使用中,我更喜欢我的解决方案,因为它避免了每次启动新的Shell时都必须重新导出该变量。
理查德·史密斯

救命!大量的人展示了如何使用./ssh/config进行设置,以及如何在Mac上使用ssh-agent / ssh-add -K。已经使用了一年,但是它突然在High Sierra中停止了最新补丁的工作。当其他所有操作均失败时,core.sshCommand即可工作。谢谢!
史蒂夫,

2
感谢您提供的优雅解决方案。但是我只想精确地说明core.sshCommand仅适用于git> = 2.10.0
slonepi '19

32

通常,您要为此使用~/.ssh/config。只需将服务器地址与您要用于它们的密钥配对,如下所示:

Host github.com
  IdentityFile ~/.ssh/id_rsa.github
Host heroku.com
  IdentityFile ~/.ssh/id_rsa.heroku
Host *
  IdentityFile ~/.ssh/id_rsa

Host *表示任何服务器,因此我将其设置~/.ssh/id_rsa为要使用的默认密钥。


9
如果您在GitHub之类的一台服务器上有多个帐户,并且每个服务器都想要一个不同的私钥,那么这种想法将行不通。
Flimm

对于一台服务器上的多个帐户看到这个答案stackoverflow.com/questions/3225862/...
lexicalscope

22

在我的方案中,类似于@Richard Smith方案(其解决方案BTW对我不起作用),我需要在不同存储库下的同一服务器上使用不同的密钥。

我的解决方法是使用环境变量正确设置会话GIT_SSH_COMMAND,如下所示:

export GIT_SSH_COMMAND="ssh -o IdentitiesOnly=yes -i ~/.ssh/my-secret-identitiy"

更新

这里要注意的另一件事是正确设置环境变量可能会很麻烦,因此我使用的是液体提示鱼壳之类的东西提供的命令提示符修改功能。来挂接到shell并继续根据环境变量更新环境变量。当前目录和一些规则。例如,我所有需要使用Gitlab使用我的个人SSH密钥的个人项目都在下面,~/Documents/Projects/personal因此当shell挂钩运行pwd并发现当前目录在该路径下时,它将GIT_SSH_COMMAND根据需要自动设置变量。


15

ssh-add path-to-private-key它工作的开箱即用。


5
如果您有两个部署密钥,并且它们仅适用于某些存储库,则不会。在这种情况下,它可能使用了错误的密钥,并说您没有访问权限。
cdmckay

我有问题cdmckay说
Suge

7

您可以设置--global或--local配置,global将更新~/.gitconfig文件,local将更新存储库中的配置.git/config并覆盖全局(〜/ .gitconfig)配置

git config --local --add core.sshCommand'ssh -i〜/ .ssh / my_key'


2
作为一种魅力,这正是我所需要的,是针对特定回购协议的解决方案。
Quaestor Lucem

5

Windows用户在这里,我只是遇到了这个问题,所以解决方案与到目前为止的内容略有不同。我面临的问题是,我只是想使用特定的ssh私钥克隆存储库,而不必像在PowerShell中一样进行全局配置git config或添加特定的git bash设置。本质上,我只想将一些私钥放在我的.ssh文件夹中,并根据需要在特定的存储库中引用它们。

以下命令可用于此目的:

git clone -c core.sshCommand="ssh -i ~/.ssh/<PRIVATE KEY NAME>" <CLONE URL>

本质上,这是在git repo初始化时执行的,它会在运行克隆之前设置core.sshCommand选项。因此,您仅希望为此存储库设置要用于此存储库的特定ssh密钥。对于我来说,这可能不是适用于所有情况的理想解决方案。


谢谢。我不知道该-c选择git clone。这比我在克隆时建议的环境更好。
理查德·史密斯

1

其他答案启发我编写了一个小脚本,该脚本根据命令行选项或git remote -v的值(如果存在)来选择ssh键。希望能帮助到你!

实际回答问题:使用gat。

另请参阅https://bitbucket.org/eikerobert/gat/src/master/

#!/bin/bash

usegat=false

for VAR in "$@"
do
    if [ "$VAR" != "${VAR/git@bitbucket.org:myaccount/}" ]; then
        usegat=true
    fi
done

if [ $usegat=false ]; then
   /usr/bin/git rev-parse --is-inside-work-tree >/dev/null 2>&1
   isinsidegitrepo=$?
    #echo $isinsidegitrepo
   if [ $isinsidegitrepo = 0 ]; then
       remote=`/usr/bin/git remote -v`
       if [ "$remote" != "${remote/git@bitbucket.org:myaccount/}" ]; then
           usegat=true
       fi
   fi
fi


if [ $usegat = true ]; then
    # echo "TRUE"
    /usr/bin/git -c core.sshCommand="/usr/bin/ssh -i /home/myaccount/.ssh/mykey" "$@"
else
     #echo "FALSE"
    /usr/bin/git "$@"
fi

0

另一种选择是编写一个小的脚本来 core.sshCommand变得更聪明-检查当前工作目录是否配置了特定的SSH密钥,如果使用,请使用它,否则-依靠标准SSH密钥解析。

这是我的第一个版本:

#!/bin/bash
key="$(git config ssh.key)"
if [ -n "$key" ]; then
        ssh -o IdentitiesOnly=yes -i "$key" "$@"
else
        ssh "$@"
fi

然后将其设置为全局git SSH命令:

chmod 755 ~/.local/bin/git-ssh-command
git config --global core.sshCommand ~/.local/bin/git-ssh-command

~/.local/binSystemD操作系统上“在此处放置用户脚本”的当前标准)

设置完成后,您可以通过设置配置选项将任何存储库配置为使用特定的SSH密钥ssh.key

git config --local ssh.key ~/.ssh/my-non-default-private-key

其他可选技巧

  • 将全局设置ssh.key为具有“默认回退到非默认SSH密钥”或类似内容。
  • 当gitcore.sshCommand在存储库的根目录中执行时,您的自定义项git-ssh-command可以查看该目录并具有有关目录名称的启发式功能。这可以在本else节中完成,因此启发式仅在没有特定键的情况下才起作用ssh.key
  • 您可以添加git remote -v检查以根据遥控器添加启发式方法,就像在Eike的脚本中一样
  • 如果要查看存储库远程,但有多个需要不同键的远程,则可以remote="$1:$(sed "s,.* ,,;s,',,g"<<<"$2")"在脚本的开头添加以解决正在操作的远程-并进行检查($remote看起来像git remote -v输出中的中间列)。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.