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

Con*_*ion 322 git ssh gitolite

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

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

Mar*_*air 571

即使用户和主机是相同的,它们仍然可以被区分~/.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
Run Code Online (Sandbox Code Playgroud)

然后你只需使用gitolite-as-alicegitolite-as-bob不是URL中的主机名:

git remote add alice git@gitolite-as-alice:whatever.git
git remote add bob git@gitolite-as-bob:whatever.git
Run Code Online (Sandbox Code Playgroud)

注意

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

  • 太好了,谢谢.我不明白你可以在〜/ .ssh/config中自由选择主机规范的'别名' (8认同)
  • 远程中的`git @`部分不是必需的,因为它在配置的`User`行中给出. (7认同)
  • 谢谢你的回答!对我来说,一个问题是IdentityFile需要是一个完整的路径(我只将id_rsa.rick作为我的参数置于IdentityFile,这失败了).有关IdentityFile的其他语法,请参见ssh_config(5)手册页. (4认同)
  • 我正在努力解决这个问题,直到我在主机的`IdentityFile`行之后立即添加另一行包含`IdentitiesOnly yes`的行.它似乎传递了多个身份,其中一个被阻止访问主机. (2认同)

sin*_*law 54

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

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

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

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

git admin push 
Run Code Online (Sandbox Code Playgroud)

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

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

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

#!/bin/bash
exec ssh ${SSH_KEYFILE+-i "$SSH_KEYFILE"} "$@"
Run Code Online (Sandbox Code Playgroud)

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

#!/bin/bash
SSH_KEYFILE=$1 GIT_SSH=${BASH_SOURCE%/*}/ssh-as.sh exec git "${@:2}"
Run Code Online (Sandbox Code Playgroud)

第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"
Run Code Online (Sandbox Code Playgroud)

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

  • 非常好的答案.不要忘记在`$ @` - >`"$ @"`周围添加双引号是安全的. (4认同)

Hus*_*ion 43

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

GIT_SSH_COMMAND='ssh -i ~/.ssh/your_private_key' git submodule update --init
Run Code Online (Sandbox Code Playgroud)

替换~/.ssh/your_private_key为您想要使用的ssh私钥的路径.你可以改变随后的git命令(在本例中是git submodule update --init)别人一样git pull,git fetch等等.

  • 请注意,您的 ~/.ssh/id_rsa(或任何您的默认密钥)将优先于您通过 -i 传入的那个。所以你真的想使用 GIT_SSH_COMMAND='ssh -i ~/.ssh/your_private_key -o IdentitiesOnly=yes' 让它忽略其他键 (8认同)
  • 感谢您提供一个简单的解决方案,除了设置一个环境变量外,什么都不需要。 (3认同)
  • 完整文档位于 https://git-scm.com/docs/git#git-codeGITSSHcode;不过,它需要一个 _recentish_ Git (>=2.3.*)。 (2认同)
  • 我还需要强制一个空配置,因为我的主要配置是覆盖 -i 标志 `-F /dev/null` (2认同)

kar*_*los 29

基于阅读其他答案,我将以下方法汇总并使用 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
Run Code Online (Sandbox Code Playgroud)

~/.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/
Run Code Online (Sandbox Code Playgroud)

~/dev/work/.gitconfig

[user]
    email = work@work.email
Run Code Online (Sandbox Code Playgroud)

只要您将所有工作存储库都保存在 ~/dev/work 和其他地方的个人资料下,git 在向服务器执行 pull/clone/push 操作时将使用正确的 SSH 密钥,并且它还会将正确的电子邮件地址附加到所有你的承诺。

参考:


Blo*_*kas 24

要即时使用特定键:

GIT_SSH_COMMAND='ssh -i $HOME/.ssh/id_ed25519 -o IdentitiesOnly=yes -F /dev/null' git push origin c13_training_network
Run Code Online (Sandbox Code Playgroud)

解释:

  • 在进行推送之前本地 ENV var
  • -i指定键
  • -F强制一个空配置,这样你的全局配置就不会覆盖这个临时命令

  • 这实际上对我的情况有帮助。仅仅“ssh -i ...”是不够的,还必须添加这些参数 (2认同)

epi*_*age 20

使用配置您的存储库 git config

git config --add --local core.sshCommand 'ssh -i <<<PATH_TO_SSH_KEY>>>'
Run Code Online (Sandbox Code Playgroud)

这仅适用于您的本地存储库

  • 我喜欢这种方式,因为它在每个存储库的基础上工作并且是持久的 (22认同)
  • 很好的答案!我们在 jenkins 作业中使用它,所以我们只需要它几秒钟,所以一旦完成,我们就像这样设置它 ```git config --unset --local core.sshCommand '&lt;&lt;ssh_token_path&gt;&gt; '```` (4认同)
  • 非常好的答案 - 与编辑 `~/.ssh/config` 不同 - 这是特定于存储库的 (2认同)
  • 也适用于 Windows - 请记住将路径中的“\”替换为“\\”。 (2认同)

小智 16

从 git 2.10 起,也可以使用 gitconfig sshCommand 设置。文档状态

如果设置了这个变量,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。


Châ*_*ĩnh 14

一个基于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

因此,每次使用ssh或(gitscp基本上ssh),您不必再使用选项-i.

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


rab*_*exc 10

另一种方法是使用ssh-ident来管理你的ssh身份.

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


use*_*546 9

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

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

Host your_host.com
     IdentityFile [absolute_path_to_your_.ssh]\id_rsa
Run Code Online (Sandbox Code Playgroud)

我想主机必须是一个URL,而不仅仅是主机的"名称"或参考号.例如,

Host github.com
     IdentityFile c:/users/[user_name]/.ssh/id_rsa
Run Code Online (Sandbox Code Playgroud)

该路径也可以用/ c/users/[user_name]/....格式编写

Giordano Scalzo提供的解决方案也很棒. /sf/answers/640466291/


Man*_*our 6

正如其他人提到的,core.sshCommandconfig 可用于覆盖 SSH 密钥和其他参数。

这是一个示例,其中您有一个名为的备用密钥,~/.ssh/workrsa并希望将它用于克隆在~/work.

  1. .gitconfig在 下创建一个新文件~/work
[core]
  sshCommand = "ssh -i ~/.ssh/workrsa"
Run Code Online (Sandbox Code Playgroud)
  1. 在您的全局 git config 中~/.gitconfig,添加:
[includeIf "gitdir:~/work/"]
  path = ~/work/.gitconfig
Run Code Online (Sandbox Code Playgroud)


And*_*phy 5

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

IdentityFile /c/Users/Whoever/.ssh/id_rsa.alice
Run Code Online (Sandbox Code Playgroud)

哪里/c是为了c:

要检查,在 git 的 bash 中做

cd ~/.ssh
pwd 
Run Code Online (Sandbox Code Playgroud)


Lui*_*isR 5

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

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

这使用 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
Run Code Online (Sandbox Code Playgroud)

在这个例子中,我假设~/.ssh/yourOwnPrivateKey包含你自己的私钥并且~/.ssh/gitolite-admin包含用户的私钥gitolite-admin。我包含了IdentitiesOnly yes声明,以确保只有一个密钥提供给 git 服务器,Mark Longair提到。其他声明只是 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
Run Code Online (Sandbox Code Playgroud)

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


小智 5

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

git config core.sshCommand "ssh -i ~/.ssh/github-personal -o IdentitiesOnly=yes -F /dev/null"
Run Code Online (Sandbox Code Playgroud)


Mic*_*ael 5

为了让 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
Run Code Online (Sandbox Code Playgroud)

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

例如,在克隆存储库时Host work.github.com用作work.github.comURL git@work.github.com:your/repository.git


归档时间:

查看次数:

219939 次

最近记录:

6 年,1 月 前