如何告诉 git 使用哪个私钥?

jrd*_*oko 877 ssh authentication git private-key

ssh可以-i选择在身份验证时告诉使用哪个私钥文件:

-i identity_file

    选择一个文件,从中读取用于 RSA 或 DSA 身份验证的身份(私钥)。?默认~/.ssh/identity为协议版本 1~/.ssh/id_rsa~/.ssh/id_dsa协议版本 2。?身份文件也可以在配置文件中按主机指定。可以有多个-i选项(以及在配置文件中指定的多个身份)。

是否有类似的方法来告诉git~/.ssh目录中有多个私钥的系统上使用哪个私钥文件?

she*_*lic 864

~/.ssh/config,添加:

Host github.com
 HostName github.com
 IdentityFile ~/.ssh/id_rsa_github
Run Code Online (Sandbox Code Playgroud)

如果配置文件是新的,你可能需要做 chmod 600 ~/.ssh/config

现在你可以做 git clone git@github.com:{ORG_NAME}/{REPO_NAME}.git

  • {ORG_NAME}您的 GitHub 用户帐户(或组织帐户)的 GitHub URI 名称在哪里。
    • 请注意,:后面有一个冒号github.com而不是斜杠/- 因为这不是 URI。
  • 而且{REPO_NAME}是你的GitHub库的URI名称
  • 例如,对于 Linux 内核,这将是git clone git@github.com:torvalds/linux.git)。

注意:在 Linux 和 macOS 上,验证您的权限是否IdentityFile为 400。SSH 会以一种不明确的方式拒绝太易读的 SSH 密钥。它看起来就像一个凭证拒绝。在这种情况下,解决方案是:

chmod 400 ~/.ssh/id_rsa_github
Run Code Online (Sandbox Code Playgroud)

  • 如果您需要使用不同的密钥连接到同一台主机怎么办? (201认同)
  • 如果配置文件是新的,不要忘记执行 `chmod 600 ~/.ssh/config` (19认同)
  • 关于使用不同密钥联系同一主机:这里必须了解,在“.ssh/config”中,“Host”是一个自定义名称,您可以为“HostName”下指定的主机指定名称。 git URL `git@github.com:torvalds/linux.git` 中的 `github.com` 部分引用了这个 `Host`,因此必须与其完全匹配。如果您有第二个 Github ssh 密钥,则可以在 `.ssh/config` 中创建一个 `Host github2` 部分,然后使用 URL `git@github2:torvalds/linux.git` (另请参阅 https://superuser.gitbooks)。 com/a/1519694/96128)。 (12认同)
  • @Quelltextfabrik - 您可以使用不同的主机添加另一个部分:http://nerderati.com/2011/03/simplify-your-life-with-an-ssh-config-file/ (8认同)
  • @ValentinKlinghammer 来自@Flimm 的答案有这个问题的解决方案。就是使用`core.sshCommand` git 配置。https://superuser.com/a/912281/162466 (6认同)
  • 这会强制 git 对整个域使用特定的密钥,这通常是行不通的。例如,如果有人拥有个人 github 帐户以及工作帐户,则此配置将破坏其中之一。 (4认同)

Fli*_*imm 538

环境变量GIT_SSH_COMMAND

从 Git 版本 2.3.0 开始,您可以GIT_SSH_COMMAND像这样使用环境变量:

GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_example" git clone example
Run Code Online (Sandbox Code Playgroud)

请注意,-i有时可能会被您的配置文件覆盖,在这种情况下,您应该为 SSH 提供一个空的配置文件,如下所示:

GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_example -F /dev/null" git clone example
Run Code Online (Sandbox Code Playgroud)

配置core.sshCommand

从 Git 版本 2.10.0 开始,您可以为每个 repo 或全局配置它,因此您不必再设置环境变量!

git config core.sshCommand "ssh -i ~/.ssh/id_rsa_example -F /dev/null"
git pull
git push
Run Code Online (Sandbox Code Playgroud)

  • @Abdull 在 Bash 中,在与命令相同的行上进行赋值,仅导出该命令的环境变量。试试看:`example=hello /usr/bin/env | grep 示例`。 (9认同)
  • 对我来说`GIT_SSH_COMMAND`直到我使用[`IdentitiesOnly`](https://superuser.com/q/268776/55307)才起作用,例如这个命令:`GIT_SSH_COMMAND="ssh -i ~/.ssh/ mysubdir/id_rsa -o 'IdentitiesOnly yes'" git push`。 (8认同)
  • 我必须将 *shell* 变量导出到环境变量才能完成这项工作,即`export GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_example"`,然后是`git clone example` (5认同)
  • 事情变得更好了:从 Git 2.10 开始,您可以将命令存储在 Git 配置中:http://stackoverflow.com/a/38474220/520162 (3认同)
  • @Noitidart `/dev/null` 只是类 UNIX 操作系统中的有效文件名,它不适用于 Windows。 (2认同)
  • 在 Windows 中,这将是 `-F nul`,但在 OpenSSH 中可以使用 `-F none` (2认同)
  • 有用的答案。此外,在 Mac 中,不需要 `-F /dev/null`。 (2认同)

ken*_*orb 156

没有直接的方式告诉git其私钥来使用,因为它依赖于ssh对存储库的认证。但是,仍有一些方法可以实现您的目标:

选项1: ssh-agent

您可以ssh-agent用来临时授权您的私钥。

例如:

$ ssh-agent sh -c 'ssh-add ~/.ssh/id_rsa; git fetch user@host'
Run Code Online (Sandbox Code Playgroud)

选项 2: GIT_SSH_COMMAND

使用GIT_SSH_COMMAND环境变量 (Git 2.3.0+)传递 ssh 参数。

例如:

$ GIT_SSH_COMMAND='ssh -i ~/.ssh/id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' \
  git clone user@host
Run Code Online (Sandbox Code Playgroud)

您可以在一行中输入所有内容 - 忽略$并省略\.

选项 3: GIT_SSH

通过使用GIT_SSH环境变量指定备用ssh二进制文件来传递 ssh 参数。

例如:

$ echo 'ssh -i ~/.ssh/id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $*' > ssh
$ chmod +x ssh
$ GIT_TRACE=1 GIT_SSH='./ssh' git clone user@host
Run Code Online (Sandbox Code Playgroud)

注意:以上几行是 shell(终端)命令行,您应该将其粘贴到终端中。他们将创建一个名为 的文件ssh,使其可执行,并(间接)执行它。

注意:GIT_SSH自 v0.99.4 (2005)起可用

选项 4: ~/.ssh/config

使用~/.ssh/config其他答案中建议的文件来指定您的私钥的位置,例如

Host github.com
  User git
  Hostname github.com
  IdentityFile ~/.ssh/id_rsa
Run Code Online (Sandbox Code Playgroud)

  • `$ ssh-agent sh -c 'ssh-add ~/.ssh/id_rsa; git fetch user@host'` 为我工作,而没有其他办法。荣誉。 (8认同)
  • // ,如果您在 ssh-agent 中的身份被转发,就像这个问题一样,该怎么办? http://superuser.com/questions/971732/how-do-i-undo-an-ssh-add-on-a-forwarded-identity-to-access-github (3认同)
  • 我必须使用 `~/.ssh/config` 方法,环境变量对我不起作用...... (3认同)
  • `GIT_SSH` 自 [v0.99.4(2005 年 8 月)](https://github.com/git/git/commit/4852f7232b7a83fbd1b745520181bd67bf95911b) 起可用,所以基本上自 Git 存在以来(2005 年 4 月)。 (2认同)

thu*_*yen 57

在 中使用自定义主机配置~/.ssh/config,如下所示:

Host gitlab-as-thuc  
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_rsa.thuc
    IdentitiesOnly yes
Run Code Online (Sandbox Code Playgroud)

然后像这样使用您的自定义主机名:

git remote add thuc git@gitlab-as-thuc:your-repo.git  
Run Code Online (Sandbox Code Playgroud)

  • 最后!!!这个答案实际上展示了如何利用你放在 `~/.ssh/config` 文件中的内容。每个其他答案都没有在添加源时如何设置主机,这会自动允许 git 使用正确的密钥文件。谢谢你!! (12认同)
  • 这是我一直在寻找的答案,因为我有单独的 GitHub 帐户用于家庭和工作。我只需要设置`Host work.github.com``HostName github.com``IdentityFile ~/.ssh/work`,然后每当我克隆一个作品时将“github.com”替换为“work.github.com”存储库。它仍然连接到“github.com”,但使用非默认密钥对。 (3认同)

Ign*_*ams 33

编写一个ssh使用您想要的参数调用的脚本,并将脚本的文件名放在$GIT_SSH. 或者只是将您的配置放在~/.ssh/config.

  • [另一个解释](http://superuser.com/a/355696/235231) 如何做到这一点。 (2认同)

小智 27

如果您不想在每次运行 git 时都指定环境变量,不想使用另一个包装脚本,不要/不能运行 ssh-agent(1),也不想为此下载另一个包,请使用 git -remote-ext(1) 外部传输:

$ git clone 'ext::ssh -i $HOME/.ssh/alternate_id git.example.com %S /path/to/repository.git'
Cloning into 'repository'
(...)
$ cd repository
$ git remote -v
origin  ext::ssh -i $HOME/.ssh/alternate_id git.example.com %S /path/to/repository.git (fetch)
origin  ext::ssh -i $HOME/.ssh/alternate_id git.example.com %S /path/to/repository.git (push)
Run Code Online (Sandbox Code Playgroud)

我认为这个解决方案优越,因为:

  • 它是存储库/远程特定的
  • 避免包装脚本膨胀
  • 不需要 SSH 代理——如果你想要无人值守的克隆/推/拉(例如在 cron 中)很有用
  • 当然,不需要外部工具

  • 哇!这真是太棒了,不知道这个。感谢您的回答,在人偶环境中也很有帮助,以防止管理`.ssh/config` 等的额外麻烦。+1! (3认同)
  • 如果您遇到以下错误 `fatal: transport 'ext' not allowed`,则必须通过 `export GIT_ALLOW_PROTOCOL=ext` 将 ext 协议列入白名单。基本上,git-remote-ext 远程助手(支持“ext::ssh example.com %S foo/repo”URL)允许任意命令执行。这通常不是问题,因为用户总是会看到并信任他们传递给 git 的 URL。然而 git 子模块,通过 .gitmodules 文件,允许攻击者请求客户端获取任意 git URL。https://hackerone.com/reports/104465 (3认同)
  • 这个答案正是我需要强制 Chef 的 `git` 资源使用特定于存储库的部署密钥从私有 Github 存储库克隆/获取所需的答案。与基于环境/脚本的方法相比,此方法的额外优势在于,由于密钥路径是在工作存储库的配置中编码的,因此它将在初始克隆和后续获取/推送中使用相同的密钥。 (2认同)
  • 此解决方案不能与 --recursive 标志一起使用。子模块不是使用指定的密钥获取的,因此如果它们需要身份验证,则会失败。 (2认同)

小智 23

这是我对多个帐户的设置,每个帐户使用单独的 rsa 密钥。不管是 github、bitbucket 还是其他什么都没关系;此设置不涉及 ssh 客户端配置,也不使用主机作为配置选择器。它使用目录结构和每个目录子树配置。

$HOME/.gitconfig
[user]
  name = My Public Account Name
  email = my-public-email@public.com

[core]
  sshCommand = "ssh -i ~/.ssh/my_public_account_id_rsa"

# public github user - IDEA
[includeIf "gitdir:~/idea/"]
  path = ~/idea/.gitconfig

# org-1 user
[includeIf "gitdir:~/idea/org-1/"]
  path = ~/idea/org-1/.gitconfig

# org-2 user
[includeIf "gitdir:~/idea/org-2/"]
  path = ~/idea/org-2/.gitconfig

# public github user - ruby
[includeIf "gitdir:~/rubymine/"]
  path = ~/rubymine/.gitconfig

# org-1 user
[includeIf "gitdir:~/rubymine/org-1/"]
  path = ~/rubymine/org-1/.gitconfig
Run Code Online (Sandbox Code Playgroud)

如果我需要覆盖某些项目的密钥和用户详细信息,那么我会将它们保存在同一目录中。在该目录中,我创建一个“.gitconfig”文件,例如:

$HOME/idea/org-1/.gitconfig
[user]
  name = My Org-1 Account Name
  email = my-org1-email@org-1.com

[core]
  sshCommand = "ssh -i ~/.ssh/my_org1_account_id_rsa"
Run Code Online (Sandbox Code Playgroud)

~/idea/org-1每当我在目录或其子目录中运行任何 git 命令时,它都会获取我的 org-1 特定配置并用于my_org1_account_id_rsassh。还有另一个名称/电子邮件也用于提交,而不仅仅是 rsa 密钥。

这是一种分层配置,即从更通用到更具体的配置进行评估。这是通过在您的文件中订购“includeIf”子句$HOME/.gitconfig并在 glob 模式中添加尾部斜杠来实现的,这会导致**在末尾添加。文档gitconfig includeIf docs对此进行了很好的描述。因此请记住,顺序很重要全局模式也很重要

  • 实现每个项目自定义密钥的最简单方法,这应该是公认的答案 (2认同)
  • 这绝对是最好的答案!谢谢 (2认同)

nyx*_*yxz 18

如果您需要使用不同的密钥连接到同一台主机,那么您可以通过以下方式实现:

  1. ~/.ssh/config使用不同的主机但相同的主机名配置。
  2. 使用适当的主机克隆您的存储库。

例子:

~/.ssh/config

主持工作
  主机名 bitbucket.org
  身份文件 ~/.ssh/ id_rsa_work
  用户 git
    
主持人个人
  主机名 bitbucket.org
  身份文件 ~/.ssh/ id_rsa_personal
  用户 git

然后,而不是克隆你的回购协议,如:

git clone git@bitbucket.org :username/my-work-project.git
git clone git@bitbucket.org :username/my-personal-project.git

你必须做

git clone git@ work :username/my-work-project.git
git clone git@ personal :username/my-personal-project.git

  • 这是简单的方法,特别是如果您在 Github 中使用部署密钥 (2认同)

Jan*_*sky 17

在与我斗争之后,$GIT_SSH我想分享对我有用的东西。

通过我的例子,我假设你的私钥位于/home/user/.ssh/jenkins

要避免的错误:GIT_SSH 值包括选项

$ export GIT_SSH="ssh -i /home/user/.ssh/jenkins"
Run Code Online (Sandbox Code Playgroud)

或者任何类似的都会失败,因为git 会尝试将值作为文件执行。因此,您必须创建一个脚本。

$GIT_SSH 脚本的工作示例 /home/user/gssh.sh

该脚本将按如下方式调用:

$ $GIT_SSH [username@]host [-p <port>] <command>
Run Code Online (Sandbox Code Playgroud)

示例脚本工作可能如下所示:

#!/bin/sh
ssh -i /home/user/.ssh/jenkins $*
Run Code Online (Sandbox Code Playgroud)

注意$*最后,它是其中的重要部分。

更安全的替代方案是:

#!/bin/sh
ssh -i /home/user/.ssh/jenkins -F /dev/null -p 22 $*
Run Code Online (Sandbox Code Playgroud)

假设脚本在 中/home/user/gssh.sh,那么您应该:

$ export GIT_SSH=/home/user/gssh.sh
Run Code Online (Sandbox Code Playgroud)

一切都将起作用。


Bre*_*win 9

所以我将 GIT_SSH 环境变量设置为$HOME/bin/git-ssh.

为了支持让我的 repo 配置决定使用哪个 ssh 身份,我的~/bin/git-ssh文件是这样的:

#!/bin/sh
ssh -i $(git config --get ssh.identity) -F /dev/null -p 22 $*
Run Code Online (Sandbox Code Playgroud)

然后我有一个全局 git 配置设置:

$ git config --global ssh.identity ~/.ssh/default_id_rsa
Run Code Online (Sandbox Code Playgroud)

在任何 git 存储库中,我都可以设置本地ssh.identitygit 配置值:

$ git config --local ssh.identity ~/.ssh/any_other_id_rsa
Run Code Online (Sandbox Code Playgroud)

瞧!

如果您可以为每个身份使用不同的电子邮件地址,它会变得更加简单,因为您可以在您的电子邮件地址之后命名您的密钥,然后让 git config 的 user.email 驱动密钥选择,~/bin/git-ssh如下所示:

#!/bin/sh
ssh -i $HOME/.ssh/$(git config --get user.email) -F /dev/null -p 22 $*
Run Code Online (Sandbox Code Playgroud)


Mic*_*ole 7

我有一个客户需要一个单独的 github 帐户。所以我需要为这个项目使用一个单独的密钥。

我的解决方案是将其添加到我的 .zshrc / .bashrc 中:

alias infogit="GIT_SSH_COMMAND=\"ssh -i ~/.ssh/id_specialkey\" git $@"
Run Code Online (Sandbox Code Playgroud)

每当我想在该项目中使用 git 时,我都会用 git 替换“infogit”:

infogit commit -am "Some message" && infogit push
Run Code Online (Sandbox Code Playgroud)

对我来说,更容易记住。


小智 6

您可以只使用 ssh-ident 而不是创建自己的包装器。

您可以在以下位置阅读更多信息:https : //github.com/ccontavalli/ssh-ident

它在第一次需要时按需加载 ssh 密钥,一次,即使有多个登录会话、xterms 或 NFS 共享主目录。

使用一个很小的配置文件,它可以自动加载不同的密钥,并根据您的需要将它们分开存放在不同的代理中(用于代理转发)。


归档时间:

查看次数:

973237 次

最近记录:

4 年,1 月 前