为给定域指定git push的SSH密钥

时间:2011-10-28 09:57:04

标签: git ssh gitolite

我有以下用例:我希望能够使用用户git@git.company.com:gitolite-admin的私钥推送到gitolite-admin,而我想使用'my git@git.company.com:some_repo推送到~/.ssh/config自己的私钥。 AFAIK,我无法使用~/.ssh/config解决此问题,因为在这两种情况下用户名和服务器名称都相同。由于我主要使用自己的私钥,因此git@git.company.comgit定义了私钥。有没有人知道覆盖用于单个{{1}}调用的密钥的方法?

(旁白:gitolite根据密钥来区分谁在进行推送,因此在访问权限,所有权和审计方面,用户@服务器字符串对于不同的用户来说是相同的。)

17 个答案:

答案 0 :(得分:550)

即使用户和主机相同,仍然可以在~/.ssh/config中区分它们。例如,如果您的配置如下所示:

Host gitolite-as-alice
  HostName git.company.com
  User git
  IdentityFile /home/whoever/.ssh/id_rsa.alice
  IdentitiesOnly yes

Host gitolite-as-bob
  HostName git.company.com
  User git
  IdentityFile /home/whoever/.ssh/id_dsa.bob
  IdentitiesOnly yes

然后,您只需使用gitolite-as-alicegitolite-as-bob代替网址中的主机名:

git remote add alice git@gitolite-as-alice:whatever.git
git remote add bob git@gitolite-as-bob:whatever.git

注意

您希望包含选项IdentitiesOnly yes以防止使用默认ID。否则,如果您还有与默认名称匹配的id文件,则首先尝试它们,因为与其他配置选项(遵循“赢得第一个”)不同,IdentityFile选项追加到要尝试的身份列表。请参阅:https://serverfault.com/questions/450796/how-could-i-stop-ssh-offering-a-wrong-key/450807#450807

答案 1 :(得分:54)

one offered above by Mark Longair的另一种方法是使用一个别名,该别名将使用备用SSH密钥在任何远程上运行任何 git命令。这个想法基本上是在运行git命令时切换你的SSH身份。

在另一个答案中相对于主机别名方法的优点:

  • 即使您无法明确指定remote,也可以使用任何 git命令或别名。
  • 更容易使用许多存储库,因为您只需要为每台客户端计算机设置一次,而不是每台客户端计算机上的每个存储库设置一次。

我使用了一些小脚本和一个git别名admin。我可以这样做,例如:

git admin push 

使用备用(“admin”)SSH密钥推送到默认远程。同样,您可以使用此别名的任何命令(不仅仅是push)。您甚至可以git admin clone ...来克隆您只能使用“admin”键访问的存储库。

步骤1:创建备用SSH密钥,可选择设置密码,以防您在其他人的计算机上执行此操作。

第2步:创建一个名为“ssh-as.sh”的脚本,该脚本运行使用SSH的东西,但使用给定的SSH密钥而不是默认密码:

#!/bin/bash
exec ssh ${SSH_KEYFILE+-i "$SSH_KEYFILE"} "$@"

步骤3:创建一个名为“git-as.sh”的脚本,该脚本使用给定的SSH密钥运行git命令。

#!/bin/bash
SSH_KEYFILE=$1 GIT_SSH=${BASH_SOURCE%/*}/ssh-as.sh exec git "${@:2}"

第4步:添加别名(使用适合下面“PATH_TO_SCRIPTS_DIR”的内容):

# Run git commands as the SSH identity provided by the keyfile ~/.ssh/admin
git config --global alias.admin \!"PATH_TO_SCRIPTS_DIR/git-as.sh ~/.ssh/admin"

更多详情请见:http://noamlewis.wordpress.com/2013/01/24/git-admin-an-alias-for-running-git-commands-as-a-privileged-ssh-identity/

答案 2 :(得分:35)

您可以使用git环境变量GIT_SSH_COMMAND。在您的终端下的git存储库中运行:

GIT_SSH_COMMAND='ssh -i ~/.ssh/your_private_key' git submodule update --init

~/.ssh/your_private_key替换为您想要使用的ssh私钥的路径。您可以将后续git命令(在示例中为git submodule update --init)更改为git pullgit fetch等其他人。

答案 3 :(得分:11)

一个基于Unix的系统(Linux,BSD,Mac OS X),默认身份存储在 $ HOME / .ssh 目录中的2个文件中: private key: $HOME/.ssh/id_rsa public key: $HOME/.ssh/id_rsa.pub 当您使用ssh而没有选项-i时,它会使用默认私钥对远程系统进行身份验证。

如果您要使用其他私钥,例如 $ HOME / .ssh / deploy_key ,则必须使用ssh -i ~/.ssh/deploy_key ...

这很烦人。您可以在 $ HOME / .bash_profile 中添加以下行: ssh-add ~/.ssh/deploy_key ssh-add ~/.ssh/id_rsa

因此,每次您使用sshgitscp(基本上也是ssh)时,您都不必再使用选项-i了。

您可以在 $ HOME / .bash_profile 文件中添加任意数量的密钥。

答案 4 :(得分:10)

另一种选择是使用ssh-ident, to manage your ssh identities

它根据您当前的工作目录,ssh选项等自动加载和使用不同的密钥...这意味着您可以轻松地拥有一个工作/目录和私有/目录,透明地使用不同的密钥和身份SSH。

答案 5 :(得分:8)

我在Win7上使用Git Bash。以下对我有用。

在〜/ .ssh / config或c:/ users / [your_user_name] / .ssh / config创建配置文件。在文件中输入:

Host your_host.com
     IdentityFile [absolute_path_to_your_.ssh]\id_rsa

我猜主持人必须是一个网址,而不仅仅是一个"名称"或者为你的主人做准备。例如,

Host github.com
     IdentityFile c:/users/[user_name]/.ssh/id_rsa

路径也可以用/ c / users / [user_name] / .... format

编写

Giordano Scalzo提供的解决方案也很棒。 https://stackoverflow.com/a/9149518/1738546

答案 6 :(得分:3)

如果在Windows上使用Git的ssh版本,ssh配置中的标识文件行看起来像

IdentityFile /c/Users/Whoever/.ssh/id_rsa.alice

其中/c适用于c:

要在git的bash中查看

cd ~/.ssh
pwd 

答案 7 :(得分:3)

您可能需要删除(或注释掉)默认主机配置 .ssh/config

答案 8 :(得分:3)

基于阅读其他答案,我结合在一起并使用github测试了以下方法,该方法结合了一些技术:

  • 正确的SSH配置
  • git URL重写

此方法的优点是,设置完成后,不需要任何额外的工作即可完成操作-例如,您无需更改远程URL或记住以其他方式克隆事物-URL重写使一切正常。

~/.ssh/config

# Personal GitHub
Host github.com
  HostName github.com
  User git
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/github_id_rsa

# Work GitHub
Host github-work
  HostName github.com
  User git
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/work_github_id_rsa

Host *
  IdentitiesOnly yes

~/.gitconfig

[user]
    name = My Name
    email = personal@personal.email

[includeIf "gitdir:~/dev/work/"]
    path = ~/dev/work/.gitconfig

[url "github-work:work-github-org/"]
    insteadOf = git@github.com:work-github-org/

~/dev/work/.gitconfig

[user]
    email = work@work.email

只要您将所有工作库都放在〜/ dev / work和其他个人物品下,git在对服务器执行拉/克隆/推送操作时将使用正确的SSH密钥,并且还会附加正确的电子邮件地址所有的提交。

参考文献:

答案 9 :(得分:3)

正如其他人所述,core.sshCommand配置可用于覆盖SSH密钥和其他参数。

在这里有个例子,您有一个名为~/.ssh/workrsa的备用密钥,并想将其用于在~/work下克隆的所有存储库。

  1. .gitconfig下创建一个新的~/work文件:
[core]
  sshCommand = "ssh -i ~/.ssh/workrsa"
  1. 在全局git配置~/.gitconfig中,添加:
[includeIf "gitdir:~/work/"]
  path = ~/work/.gitconfig

答案 10 :(得分:2)

从git 2.10起,也可以使用gitconfig sshCommand设置。 Docs state

  

如果设置了此变量,则在需要连接到远程系统时,git fetch和git push将使用指定的命令而不是ssh。该命令与GIT_SSH_COMMAND环境变量的格式相同,并且在设置环境变量后将被覆盖。

一个用法示例为:git config core.sshCommand "ssh -i ~/.ssh/[insert_your_keyname]

在某些情况下,此操作不起作用,因为ssh_config会覆盖命令,在这种情况下,请尝试ssh -i ~/.ssh/[insert_your_keyname] -F /dev/null以不使用ssh_config。

答案 11 :(得分:2)

使用~/.ssh/config的一种可能性是使用Match限制而不是Host限制。特别是Match Exec调用shell命令来决定是否应用声明。在bash中,您可以使用以下命令:

[ git@git.company.com:gitolite-admin = $(git config --get remote.origin.url)'' ]

这使用bash [命令来验证两个字符串是否相等。在这种情况下,它正在测试字符串git@git.company.com:gitolite-admin是否与从$(git config --get remote.origin.url)''命令获得的输出匹配。

您可以使用任何其他命令来标识Shell所在的存储库。为此,在您的shell中定义$SHELL变量(在我的情况下为/bin/bash中,是很重要的)。完整的示例将是以下~/.ssh/config

Match Exec "[ git@git.company.com:gitolite-admin = $(git config --get remote.origin.url)'' ]"
  IdentityFile ~/.ssh/gitolite-admin
  IdentitiesOnly yes
  ForwardAgent no
  ForwardX11 no
  ForwardX11Trusted no

Match Exec "[ git@git.company.com:some_repo = $(git config --get remote.origin.url)'' ]"
  IdentityFile ~/.ssh/yourOwnPrivateKey
  IdentitiesOnly yes
  ForwardAgent no
  ForwardX11 no
  ForwardX11Trusted no

在此示例中,我假设~/.ssh/yourOwnPrivateKey包含您自己的私钥,而~/.ssh/gitolite-admin包含用户gitolite-admin的私钥。我加入了IdentitiesOnly yes声明,以确保仅向Mark Longair提到的git服务器提供一个密钥。其他声明只是git的标准ssh选项。

如果要使用不同的键使用多个some_repo,则可以添加此配置。如果您在git@git.company.com上有多个存储库,并且大多数存储库都使用~/.ssh/yourOwnPrivateKey,则将此密钥作为主机的默认值包含会更有意义。在这种情况下,~/.ssh/config将是:

Match Exec "[ git@git.company.com:gitolite-admin = $(git config --get remote.origin.url)'' ]"
  IdentityFile ~/.ssh/gitolite-admin
  IdentitiesOnly yes

Host git.company.com
  IdentityFile ~/.ssh/yourOwnPrivateKey
  IdentitiesOnly yes
  ForwardAgent no
  ForwardX11 no
  ForwardX11Trusted no

请注意,顺序很重要,Host git.company.com限制应出现在Match Exec一个或多个之后。

答案 12 :(得分:2)

使用git config配置存储库。例如:

git config --add --local core.sshCommand 'ssh -i ~/.ssh/<<<PATH_TO_SSH_KEY>>>'

答案 13 :(得分:2)

如果您已经有默认的 ssh 密钥配置,但想对特定存储库使用不同的配置,那么这应该可以解决问题:

git config core.sshCommand "ssh -i ~/.ssh/github-personal -o IdentitiesOnly=yes -F /dev/null"

答案 14 :(得分:1)

您在文件配置键ssh中最指定的地址:

# Default GitHub user
Host one
 HostName gitlab.com
 User git
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/key-one
 IdentitiesOnly yes

#two user
Host two
 HostName gitlab.com
 User git
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/key-two
 IdentitiesOnly yes

答案 15 :(得分:0)

要即时使用特定键:

GIT_SSH_COMMAND='ssh -i $HOME/.ssh/id_ed25519 -o IdentitiesOnly=yes -F /dev/null' git push origin c13_training_network

说明:

  • 执行推送之前的本地ENV变量
  • -i指定密钥
  • -F强制使用空配置,以使您的全局配置不会覆盖此临时命令

答案 16 :(得分:0)

为了让 git 弄清楚,除了更改配置文件外,它还应该使用不同的 SSH 密钥,如下所述: https://stackoverflow.com/a/7927828/1306884 您可能还需要清除并重新加载活动的 SSH 身份。

在 Mac 上,执行以下操作:

ssh-add -D
ssh-add ~/.ssh/id_rsa_one_that_you_want_to_use_instead

使用这两个命令,并设置 GIT URL 以匹配 ssh/config 文件的 Host 中定义的字符串,应该允许您为不同的存储库使用不同的 SSH 密钥。

例如,对于 Host work.github.com,在克隆存储库 work.github.com 时使用 git@work.github.com:your/repository.git 作为 URL。