我有两个Git服务器,需要使用两个不同的SSH密钥。
git clone user1@server1:blahblahblah
使用 ~/.ssh/id_rsa
,但是我需要根据要连接的服务器指定使用哪个密钥。
哪个Git命令行参数可以完成这个工作?(我正在运行Linux。)
我有两个Git服务器,需要使用两个不同的SSH密钥。
git clone user1@server1:blahblahblah
使用 ~/.ssh/id_rsa
,但是我需要根据要连接的服务器指定使用哪个密钥。
哪个Git命令行参数可以完成这个工作?(我正在运行Linux。)
还有一种可能性,那就是设置core.sshCommand
,例如:
git config --local core.sshCommand "/usr/bin/ssh -i /home/me/.ssh/id_rsa_foo"
当你在Github上有多个账户时,这种策略特别有用:因为所有账户都使用git@github.com
作为ssh
连接Github,并且它使用ssh
密钥来确定你是哪个Github用户。 在这种情况下,无论是.ssh/config
还是ssh-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
命令来永久设置此项。
如果您是通过SSH连接的话,密钥将受到SSH参数的控制,而不是Git参数。
SSH在 ~/.ssh/config
文件中查找配置参数。编辑该文件并添加IdentityFile条目来为这两个Git服务器进行配置,就像这样:
Host server1.whatever.com
IdentityFile /path/to/key_1
Host server2.whatever.com
IdentityFile /path/to/key_2
这篇文章有更多细节。
ssh-agent
并使用ssh-add
,然后只需使用git。当git通过ssh连接时,密钥已经启用。你看,有几种方法,而你的原始答案并没有真正帮助到。 - keks通常情况下,您可以使用~/.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
设置为默认要使用的密钥。
[更新]: 可以查看我的另一个答案,其中介绍了基于配置的方法和一个现成的脚本供您使用。
在我的情况下,类似于@Richard Smith的情况(顺便说一下,他的解决方案对我没用),我需要在不同的代码库下为同一个服务器使用不同的密钥。
对我来说,解决方法是正确地使用环境变量GIT_SSH_COMMAND
设置会话,如下:
export GIT_SSH_COMMAND="ssh -o IdentitiesOnly=yes -i ~/.ssh/my-secret-identitiy"
更新:
这里需要注意的另一件事情是正确设置环境变量可能会很麻烦,因此我使用像Liquid Prompt或Fish Shell这样的命令提示符修改工具来连接到Shell并根据当前目录和某些规则持续更新环境变量。例如,我所有需要与Gitlab配合使用我的个人SSH密钥的个人项目都在~/Documents/Projects/personal
下,所以当shell hook运行pwd
并发现当前目录在该路径下时,它会自动设置所需的GIT_SSH_COMMAND
变量。
--global
或--local
配置,全局将更新~/.gitconfig
文件,本地将更新存储库.git/config
中的配置,并覆盖全局(~/.gitconfig
)配置。git config --local --add core.sshCommand 'ssh -i ~/.ssh/my_key'
使用 ssh-add path-to-private-key
命令可直接运行,无需进一步设置。
我是Windows用户,我遇到了这个问题,并且有一个与我在这里看到的解决方案略有不同的解决方法。我面临的问题是,我只想使用特定的私钥克隆存储库,而不必全局配置我的git配置文件或添加特定的git bash设置,因为我在PowerShell中工作。基本上,我只想让一些私有密钥坐在我的.ssh文件夹里,根据需要在特定的仓库中引用它们。
以下命令可用于此:
git clone -c core.sshCommand="ssh -i ~/.ssh/<PRIVATE KEY NAME>" <CLONE URL>
本质上,它在初始化git仓库时设置core.sshCommand选项,然后再运行克隆。因此,你希望为这个仓库使用的特定ssh密钥仅针对此仓库进行设置。这可能并不是所有情况下的理想解决方案,但对于我想要的内容来说是可以的。
git clone
命令中的 -c
选项。这比我在克隆时建议设置环境变量更好。 - Richard Smithcore.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/bin
是在SystemD操作系统上“放置用户脚本”的当前标准)
设置好后,您可以通过设置配置选项ssh.key
来配置任何存储库使用特定的SSH密钥:
git config --local ssh.key ~/.ssh/my-non-default-private-key
ssh.key
设置为“默认回退到非默认SSH密钥”或其他内容。core.sshCommand
,因此您的自定义git-ssh-command
可以查看该目录并具有一些关于目录名称的启发式方法。这可以在else
部分中完成,因此仅当没有在ssh.key
中指定特定密钥时启动启发式方法。git remote -v
检查来基于远程添加启发式方法,例如Eike的脚本remote="$1:$(sed "s,.* ,,;s,',,g"<<<"$2")"
来解决正在操作的远程 - 并针对此进行检查($remote
将类似于git remote -v
输出的中间列)。以下是自定义SSH命令的版本,它查看了远程URL并执行了一些启发式方法 - 在我的情况下,我具有相同公共git托管服务的多个不同身份(用于工作、个人等),我可以通过查看远程URL(检查Gitlab组或Github组织等)选择正确的身份:
#!/bin/bash
while ! [[ "$1" =~ "git@" ]]; do shift; done # git may send ssh options
if [[ "$2" =~ ^git-lfs-authenticate.* ]]; then # reconstruct url for git-lfs
remote="$1:$(awk '{print$2}'<<<"$2")"
else # reconstruct url for standard git commands
remote="$1:$(sed "s,.* ,,;s,',,g"<<<"$2")"
fi
echo "Detected $remote from $@" >&2
key="$(git config ssh.key)"
if [ -n "$key" ]; then # use specified SSH key, if set
ssh -o IdentitiesOnly=yes -i "$key" "$@"
elif [[ "$remote" == git@gitlab.com:my-company* ]]; then # use company id
ssh -o IdentitiesOnly=yes -i ~/.ssh/company-id "$@"
elif [[ "$remote" =~ git@bitbucket.org:.*other-org.* ]]; then # bitbucket has weird urls
ssh -o IdentitiesOnly=yes -i ~/.ssh/custom-org-key "$@"
else # otherwise use whatever the agent has (my personal key)
ssh "$@"
fi
#!/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