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

我有以下用例:我希望能够使用用户gitolite-admin的私钥推到git@git.company.com:gitolite-admin,而我想使用“我自己的”私钥推到git@git.company.com:some_repo。AFAIK,我不能使用~/.ssh/config解决这个问题,因为用户名和服务器名在这两种情况下是相同的。由于我主要使用自己的私钥,所以我在~/.ssh/config中为git@git.company.com定义了私钥。有人知道一种方法来覆盖用于单个git调用的键吗?

(另外:gitolite根据键来区分谁在进行推送,所以就访问、所有权和审计而言,user@server字符串对于不同的用户是相同的,这不是问题。)

363075 次浏览

即使用户和主机是相同的,它们仍然可以在~/.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

然后你只需要在URL中使用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文件,它们将首先被尝试,因为不像其他配置选项(遵守“first in wins”),IdentityFile选项附加到要尝试的身份列表。看:https://serverfault.com/questions/450796/how-could-i-stop-ssh-offering-a-wrong-key/450807#450807

上面马克·朗盖尔提出的一个的另一种方法是使用一个别名,该别名将在任何远程上运行任何 git命令,并使用另一个SSH密钥。这个想法基本上是在运行git命令时切换您的SSH身份。

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

  • 将与任何 git命令或别名一起工作,即使你不能显式指定remote
  • 更容易使用多个存储库,因为您只需要在每个客户端机器上设置一次,而不是在每个客户端机器上的每个存储库设置一次。

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

git admin push

使用替代SSH密钥(“admin”)推到默认远程。同样,你可以用这个别名使用任何命令(不仅仅是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/

另一个替代方法是使用SSH -ident,用于管理您的SSH身份

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

如果在windows上使用Git版本的ssh, ssh配置中的身份文件行如下所示

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

其中/c代表c:

要检查,在git的bash做

cd ~/.ssh
pwd

我在Win7上使用Git Bash。下面的方法对我很有效。

在~/处创建一个配置文件。Ssh /config或c:/users/[your_user_name]/. Ssh /config。在文件中输入:

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

我想主机必须是一个URL,而不仅仅是一个“名称”或参考您的主机。例如,

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

也可以写入“/c/users/[user_name]/....”格式

Giordano Scalzo提供的解决方案也很棒。 https://stackoverflow.com/a/9149518/1738546 < / p >
一个基于Unix的系统(Linux, BSD, Mac OS X),默认标识存储在目录$ HOME / . ssh中,分为2个文件: 私钥:$HOME/.ssh/id_rsa 公钥:$HOME/.ssh/id_rsa.pub 当你使用没有选项-issh时,它使用默认的私钥来验证远程系统

如果你想使用另一个私钥,例如< em > $ HOME / . ssh / deploy_key < / em >,你必须使用ssh -i ~/.ssh/deploy_key ...

这很烦人。你可以在你的< em > $ HOME / . bash_profile < / em >中添加以下行: ssh-add ~ / . ssh / deploy_key ssh-add ~ / . ssh / id_rsa < /代码> < / p >

所以每次你使用sshgitscp(基本上也是ssh)时,你不必再使用选项-i

你可以在文件< em > $ HOME / . bash_profile < / em >中添加任意多的键。

你可以利用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等。

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

你最多在文件配置键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

从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. conf。

我已经在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

只要你把所有的工作reppos放在~/dev/work和其他地方的个人物品下,git在向服务器进行拉/克隆/推操作时将使用正确的SSH密钥,并且它还将为你的所有提交附加正确的电子邮件地址。

引用:

  • 1 < a href = " https://stackoverflow.com/a/43654115/4907881 " > < / >

  • 2 < a href = " https://stackoverflow.com/questions/3860112/multiple-github-accounts-on-the-same-computer " > < / >

正如其他人提到的,core.sshCommand配置可以用来覆盖SSH密钥和其他参数。

下面是一个例子,你有一个名为~/.ssh/workrsa的替代键,并希望将它用于在~/work下克隆的所有存储库。

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

使用~/.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声明,以确保只有一个密钥提供给git服务器,即马克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

注意顺序很重要,并且Host git.company.com限制应该出现在Match Exec one或ones之后。

使用git config配置存储库

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

这只适用于你的本地存储库

要在运行中使用特定的键:

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

解释:

  • 在执行推送之前,使用本地ENV变量
  • -i指定键
  • -F强制一个空配置,所以你的全局配置不会覆盖这个临时命令

如果你已经有默认的ssh密钥配置,但想要对特定的存储库使用不同的配置,那么这应该可以做到:

git config core.sshCommand "ssh -i ~/.ssh/github-personal -o IdentitiesOnly=yes -F /dev/null"
对于git来说,它应该使用不同的SSH密钥,除了改变你的配置文件,就像这里提到的: https://stackoverflow.com/a/7927828/1306884 < a href = " 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,在克隆存储库git@work.github.com:your/repository.git时使用work.github.com作为URL。

注意:有一种方法可以在以前的回答中为目录应用git配置,而不仅仅是在回购级别。

在我的例子中,所有的项目都在~/work/目录下,所以我更新了我的gitconfig如下:

# ~/.gitconfig
...


[includeIf "gitdir:~/work/**"]
path = "~/work/.gitconfig"
# ~/work/.gitconfig
[user]
email = amr@work.com
name = Amr Awad
sshCommand = ssh -i ~/.ssh/work

现在,~/work/目录中的所有回购都使用工作键~/.ssh/work,而不需要单独配置每个回购。

以下是简单的方法:

-从你的本地根git文件夹。

-检查当前本地存储库的认证方法类型为HTTPS或SSH。

   git remote -v


Example using HTTPS:
origin  https://github.com/juantorres9/SQLite_crash_cours.git (fetch)
origin  https://github.com/juantorres9/SQLite_crash_cours.git (push)
Example using SSH:
origin  git@github.com:juantorres9/SQLite_crash_cours.git (fetch)
origin  git@github.com:juantorres9/SQLite_crash_cours.git (push)

-设置您选择的身份验证方法,以防尚未设置。

 For setting SSH
git remote set-url origin git@github.com:USERNAME/REPOSITORY.git
For setting HTTPS
git remote set-url origin https://github.com/USERNAME/REPOSITORY.git

-再检查一遍以防你想再次检查

 git remote -v

-你现在可以使用你配置的方法来使用git push:fetch。

git push origin master

< >强注 最后但并非最不重要的,检查更新的官方文件 https://docs.github.com/en/get-started/getting-started-with-git/managing-remote-repositories < / p >