如何指定在Git上执行shell命令时使用的私有SSH密钥?

时间:2010-12-30 19:42:02

标签: git bash shell ssh

可能是一种非常不寻常的情况,但我想指定一个私有SSH密钥,以便在从本地计算机执行shell(git)命令时使用。

基本上是这样的:

git clone git@github.com:TheUser/TheProject.git -key "/home/christoffer/ssh_keys/theuser"

甚至更好(在Ruby中):

with_key("/home/christoffer/ssh_keys/theuser") do
  sh("git clone git@github.com:TheUser/TheProject.git")
end

我见过使用Net :: SSH连接远程服务器的示例,它使用指定的私钥,但这是一个本地命令。有可能吗?

30 个答案:

答案 0 :(得分:1039)

这些解决方案都不适合我。

相反,我详细阐述了@Martinv.Löwis提到为SSH设置config文件。

SSH将查找用户的~/.ssh/config文件。我有我的设置:

Host gitserv
    Hostname remote.server.com
    IdentityFile ~/.ssh/id_rsa.github
    IdentitiesOnly yes # see NOTES below

我添加了一个远程git存储库:

git remote add origin git@gitserv:myrepo.git

然后git命令对我来说正常工作。

git push -v origin master

备注

  • IdentitiesOnly yes需要prevent the SSH default behavior发送与每个协议的默认文件名匹配的身份文件。如果您有一个名为~/.ssh/id_rsa的文件,将在~/.ssh/id_rsa.github之前尝试使用此文件而不使用此选项。

<强>参考

答案 1 :(得分:642)

这样的事情应该有效(由orip建议):

ssh-agent bash -c 'ssh-add /somewhere/yourkey; git clone git@github.com:user/project.git'

如果您喜欢子壳,您可以尝试以下(虽然它更脆弱):

ssh-agent $(ssh-add /somewhere/yourkey; git clone git@github.com:user/project.git)

Git将调用SSH,它将通过环境变量找到其代理;反过来,这将加载密钥。

或者,如果您愿意将仅包含HOME目录的目录设置为.ssh,则设置HOME也可以解决问题。这可能包含identity.pub或config file设置IdentityFile。

答案 2 :(得分:379)

其他人对~/.ssh/config的建议格外复杂。它可以很简单:

Host github.com
  IdentityFile ~/.ssh/github_rsa

答案 3 :(得分:328)

从Git 2.3.0开始,我们也有简单的命令(不需要配置文件):

GIT_SSH_COMMAND='ssh -i private_key_file' git clone user@host:repo.git

您可能需要重新启动计算机上的ssh服务。

答案 4 :(得分:129)

my_git_ssh_wrapper的内容:

#!/bin/bash

ssh -i /path/to/ssh/secret/key $1 $2

然后你可以通过这样做来使用密钥:

GIT_SSH=my_git_ssh_wrapper git clone git@github.com:TheUser/TheProject.git

答案 5 :(得分:88)

总结答案和comments,设置git以使用不同密钥文件然后忘记它的最佳方法,它也支持同一主机的不同用户(例如个人GitHub帐户和工作一,也适用于Windows,是编辑~/.ssh/config(或c:\Users\<your user>\.ssh\config)并指定多个身份:

Host github.com
HostName github.com
IdentityFile /path/to/your/personal/github/private/key
User dandv

Host github-work
HostName github.com
IdentityFile /path/to/your/work/github/private/key
User workuser

然后,要将项目克隆为个人用户,只需运行常规git clone命令。

要将代表作为workuser克隆,请运行git clone git@github-work:company/project.git

答案 6 :(得分:75)

使用git 2.10 +(2016年第3季度:2016年9月2日发布),您可以为GIT_SSH_COMMAND设置 config (而不仅仅是环境变量,如Rober Jack Will&#39; s answer

commit 3c8ede3Nguyễn Thái Ngọc Duy (pclouds)(2016年6月26日) (由Junio C Hamano -- gitster --合并于commit dc21164,2016年7月19日)

  

添加了新的配置变量core.sshCommand   指定每个存储库使用GIT_SSH_COMMAND的值。

core.sshCommand:
  

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

这意味着git clone可以是:

cd /path/to/my/repo
git config core.sshCommand 'ssh -i private_key_file' 
# later on
git clone host:repo.git

答案 7 :(得分:60)

如上所述:https://superuser.com/a/912281/607049

您可以按每个回购配置:

git config core.sshCommand "ssh -i ~/.ssh/id_rsa_example -F /dev/null"
git pull
git push

答案 8 :(得分:30)

我选择了GIT_SSH环境变量。 这是我的包装器,类似于上面的Joe Block,但处理任何数量的参数。

文件〜/ gitwrap.sh

#!/bin/bash
ssh -i ~/.ssh/gitkey_rsa "$@"

然后,在我的.bashrc中,添加以下内容:

export GIT_SSH=~/gitwrap.sh

答案 9 :(得分:30)

最好将主机或ip添加到.ssh/config文件中,如下所示:

Host (a space separated list of made up aliases you want to use for the host)
    User git
    Hostname (ip or hostname of git server)
    PreferredAuthentications publickey
    IdentityFile ~/.ssh/id_rsa_(the key you want for this repo)

答案 10 :(得分:12)

从 Git 版本 2.10.0 开始,您可以针对每个 repo 或全局进行配置

git config core.sshCommand "ssh -i ~/.ssh/id_rsa_example -o 'IdentitiesOnly yes'"

这将指定当前存储库将使用什么 ssh 密钥。我假设如果你想指定这个全局只需要设置 --global 选项。

答案 11 :(得分:8)

其中许多解决方案看起来很诱人。但是,我发现以下链接中的通用git-wrapping-script方法最有用:

How to Specify an ssh Key File with the git command

关键是没有git命令,如下所示:

git -i ~/.ssh/thatuserkey.pem clone thatuser@myserver.com:/git/repo.git

Alvin的解决方案是使用一个明确定义的bash-wrapper脚本来填补这个空白:

git.sh -i ~/.ssh/thatuserkey.pem clone thatuser@myserver.com:/git/repo.git

git.sh的位置:

#!/bin/bash

# The MIT License (MIT)
# Copyright (c) 2013 Alvin Abad
# https://alvinabad.wordpress.com/2013/03/23/how-to-specify-an-ssh-key-file-with-the-git-command

if [ $# -eq 0 ]; then
    echo "Git wrapper script that can specify an ssh-key file
Usage:
    git.sh -i ssh-key-file git-command
    "
    exit 1
fi

# remove temporary file on exit
trap 'rm -f /tmp/.git_ssh.$$' 0

if [ "$1" = "-i" ]; then
    SSH_KEY=$2; shift; shift
    echo "ssh -i $SSH_KEY \$@" > /tmp/.git_ssh.$$
    chmod +x /tmp/.git_ssh.$$
    export GIT_SSH=/tmp/.git_ssh.$$
fi

# in case the git command is repeated
[ "$1" = "git" ] && shift

# Run the git command
git "$@"

我可以验证这解决了我使用git remote updategit pullgit clone的远程bitbucket仓库的用户/密钥识别问题。所有这些现在在cron作业脚本中工作正常,否则在导航有限shell时遇到问题。我也能从R中调用这个脚本,仍然可以解决完全相同的cron执行问题 (例如system("bash git.sh -i ~/.ssh/thatuserkey.pem pull"))。

不是R与Ruby相同,但如果R可以做到...... O: - )

答案 12 :(得分:8)

如果这里没有其他解决方案对您有用,并且您已经创建了多个ssh键,但是仍然无法执行类似的简单操作

git pull

然后假设您有两个ssh密钥文件,如

id_rsa
id_rsa_other_key

然后在您正在苦苦挣扎的git repo里面(cd进入那里),尝试:

eval `ssh-agent -s`
ssh-add ~/.ssh/id_rsa
ssh-add ~/.ssh/id_rsa_other_key

并通过以下方式确保您的github默认用户名和用户ID正确:

# Run these commands INSIDE your git directory
git config user.name "Mona Lisa"
git config user.email "mona.lisa@email.com"

有关更多信息,请参见https://gist.github.com/jexchan/2351996

答案 13 :(得分:8)

GIT_SSH_COMMAND =“ ssh -i / path / to / git-private-access-key” git clone $ git_repo

答案 14 :(得分:7)

当您需要使用正常请求(git pull origin master)连接到github时,将*中的主机设置为~/.ssh/config为我工作,任何其他主机(例如,“github”)或“gb”)无效。

Host *
    User git
    Hostname github.com
    PreferredAuthentications publickey
    IdentityFile ~/.ssh/id_rsa_xxx

答案 15 :(得分:7)

我只需要添加密钥,然后再次运行git clone。

ssh-add ~/.ssh/id_rsa_mynewkey
git clone git@bitbucket.org:mycompany/myrepo.git

答案 16 :(得分:5)

2021 年。如果您使用的是 Mac。

假设你在 aws 上有一个 ubuntu 服务器,你通常像这样连接:

% ssh -i blah/yourkeypair.pem ubuntu@test.fattie.com

在终端只是

% export GIT_SSH_COMMAND="ssh -i /Users/fattie/Desktop/blah/yourkeypair.pem"

完成后。然后你就可以自由...

% git clone ubuntu@test.fattie.com:/home/ubuntu/teste.git  

这会将您服务器上的 repo 克隆到您的本地文件夹“teste”,

然后您可以在 teste/ 中自由执行通常的命令,例如 ...

% git push origin master

等等。

--

另请注意:https://stackoverflow.com/a/67287133/294884


至于在服务器上,看来你基本

] git clone --bare the-actual-folder teste.git

然后在 teste.git

] git init --bare --shared

答案 17 :(得分:5)

很多好的答案,但是其中一些假设具有事先的管理知识。

我认为明确强调如果您通过克隆网络URL来启动项目很重要 -https://github.com/<user-name>/<project-name>.git
那么您需要确保url [remote "origin"]下的.git/config 更改为SSH URL (请参见下面的代码块)。

此外,请确保您按照以下说明添加sshCommmand

user@workstation:~/workspace/project-name/.git$ cat config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    sshCommand = ssh -i ~/location-of/.ssh/private_key -F /dev/null <--Check that this command exist
[remote "origin"]
    url = git@github.com:<user-name>/<project-name>.git  <-- Make sure its the SSH URL and not the WEB URL
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master

详细了解here

答案 18 :(得分:3)

您需要按如下所示创建〜/ .ssh / config

Host <Your bitbucket server>
User <userid>
Hostname <Your bitbucket server as above>
IdentitiesOnly yes
IdentityFile ~/.ssh/id_rsa<file> This is your private key file

权限如下

-rw------- $HOME/.ssh/config

将公共密钥添加到git(cat〜/ .ssh / id_rsa_pub [或类似名称])

然后按如下所示进行git clone

git clone ssh://blahblah@blah.com/userid/test.git

答案 19 :(得分:3)

如果您的路径上有要使用给定的identifyfile签名的目录,则可以通过设置ControlPath例如,通过.ssh / config文件来指定使用特定的identification文件:

host github.com
  ControlPath ~/Projects/work/**
  HostName github.com
  IdentityFile ~/.ssh/id_work
  User git

然后ssh在给定工作路径下执行git命令时将使用指定的标识文件。

答案 20 :(得分:2)

您可以使用GIT_SSH环境变量。但是您需要将ssh和options包装到shell脚本中。

请参阅命令shell中的git manual:man git

答案 21 :(得分:2)

此方法的问题是,至少在Windows上由bash.exe运行时,它将每次保持休眠状态时都会创建一个新进程。

ssh-agent bash -c 'ssh-add /somewhere/yourkey; git clone git@github.com:user/project.git'

如果要按计划将其用于syncig回购,则需要在末尾添加“ && ssh-agent -k”。

类似的东西:

ssh-agent bash -c 'ssh-add C:/Users/user/.ssh/your_key; git -C "C:\Path\to\your\repo" pull && ssh-agent -k' 

ssh-agent -k将在完成后终止该进程。

答案 22 :(得分:2)

在使用Git Bash的Windows中,您可以使用以下内容添加存储库 ssh-agent bash -c 'ssh-add "key-address"; git remote add origin "rep-address"' 例如:ssh-agent bash -c 'ssh-add /d/test/PrivateKey.ppk; git remote add origin git@git.test.com:test/test.git'驱动器D中的哪个私钥,计算机的文件夹测试。此外,如果要克隆存储库,可以使用git remote add origin更改git clone

将此输入Git Bash后,它会要求您输入密码!

请注意openssh私钥和putty私钥是不同的!

如果您使用puttygen创建了密钥,则必须将私钥转换为openssh!

答案 23 :(得分:1)

gitlab RSAAuthentication yes

Host gitlab.com
  RSAAuthentication yes
  IdentityFile ~/.ssh/your_private_key_name
  IdentitiesOnly yes

doc is here

答案 24 :(得分:0)

这是我在找到此问题的解决方案时发现的ssh密钥黑客:

例如,您有两组不同的键:

key1, key1.pub, key2, key2.pub

将这些密钥保留在您的.ssh目录中

现在在您的.bashrc.bash_profile别名文件中,添加以下命令

alias key1='cp ~/.ssh/key1 id_rsa && cp ~/.ssh/key1.pub id_rsa.pub'

alias key2='cp ~/.ssh/key2 id_rsa && cp ~/.ssh/key2.pub id_rsa.pub'

Voila!您可以通过快捷方式随时切换按键!

希望这对您有用。

答案 25 :(得分:0)

问题是,当您在同一主机上具有不同的远程存储库(例如github.com),并且希望使用不同的ssh密钥(即不同的GitHub帐户)。

为此:

1)首先,您应该在〜/ .ssh / config文件中声明不同的密钥。

# Key for usual repositories on github.com
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa

# Key for a particular repository on github.com
Host XXX
HostName github.com
User git
IdentityFile ~/.ssh/id_other_rsa

通过此操作,您将第二个密钥与github.com的新友好名称“ XXX”相关联。

2)然后,您必须更改特定存储库的远程来源,以便它使用您刚刚定义的友好名称。

在命令提示符下转到您的本地存储库文件夹,并显示当前的远程来源:

>git remote -v
origin  git@github.com:myuser/myrepo.git (fetch)
origin  git@github.com:myuser/myrepo.git (push)

然后通过以下方式更改原点:

>git remote set-url origin git@XXX:myuser/myrepo.git
>git remote -v
origin  git@XXX:myuser/myrepo.git (fetch)
origin  git@XXX:myuser/myrepo.git (push)

现在您可以使用右键自动推,取...。

答案 26 :(得分:0)

如果您像我,可以:

  • 保持ssh密钥井井有条

  • 使您的git clone命令保持简单

  • 为任意数量的存储库处理任意数量的密钥。

  • 减少您的ssh密钥维护。

我将密钥保存在~/.ssh/keys目录中。

与配置相比,我更喜欢约定。

我认为代码是法律;越简单越好。

步骤1-创建别名

将此别名添加到您的外壳程序中:alias git-clone='GIT_SSH=ssh_wrapper git clone'

第2步-创建脚本

将此 ssh_wrapper 脚本添加到PATH:

#!/bin/bash
# Filename: ssh_wrapper

if [ -z ${SSH_KEY} ]; then
    SSH_KEY='github.com/l3x'  # <= Default key
fi
SSH_KEY="~/.ssh/keys/${SSH_KEY}/id_rsa"
ssh -i "${SSH_KEY}" "$@"

示例

使用github.com/l3x密钥:

KEY=github.com/l3x git-clone https://github.com/l3x/learn-fp-go

以下示例还使用 github.com/l3x 键(默认情况下):

git-clone https://github.com/l3x/learn-fp-go

使用bitbucket.org/lsheehan密钥:

KEY=bitbucket.org/lsheehan git-clone git@bitbucket.org:dave_andersen/exchange.git

注释

将ssh_wrapper脚本中的默认SSH_KEY更改为大多数时间使用的SSH_KEY。这样,您就不需要在大多数时间使用KEY变量。

您可能会想,“嘿!别名,脚本和某些键目录正在发生很多事情,”但对我而言,这是惯例。我几乎所有的工作站(以及与此相关的服务器)的配置都相似。

我的目标是简化我经常执行的命令。

我的约定(例如Bash脚本,别名等)创建了一个一致的环境,并帮助我简化了事情。

吻和名字很重要。

有关更多设计技巧,请查看我的书中的第4章SOLID Design in Go https://www.amazon.com/Learning-Functional-Programming-Lex-Sheehan-ebook/dp/B0725B8MYW

希望有帮助。 -莱克斯

答案 27 :(得分:0)

如果SSH端口号不是22(默认值),请在Port xx

中添加~/.ssh/config

就我而言(synology),

Host my_synology
    Hostname xxxx.synology.me
    IdentityFile ~/.ssh/id_rsa_xxxx
    User myname
    Port xx

然后使用config中的主机标题进行克隆。 (“my_synology”。避免@chopstik的“*”)

git clone my_synology:path/to/repo.git

答案 28 :(得分:0)

我使用zsh并在我的笔记本电脑上自动将不同的密钥加载到我的zsh shell的ssh-agent以用于其他目的(即访问远程服务器)。我修改了@ Nick的答案,我将它用于我的一个需要经常更新的回购。 (在这种情况下,它是我的dotfiles,无论我在哪里工作,我都希望在我的所有机器上使用相同和最新版本。)

bash -c 'eval `ssh-agent`; ssh-add /home/myname/.dotfiles/gitread; ssh-add -L; cd /home/myname/.dotfiles && git pull; kill $SSH_AGENT_PID'
  • 产生ssh-agent
  • 向代理
  • 添加只读密钥
  • 将目录更改为我的git repo
  • 如果repo dir cd成功,则从远程仓库拉
  • 杀死ssh-agent。 (我不希望许多代理人徘徊。)

答案 29 :(得分:-2)

您可以尝试使用sshmulti npm软件包来维护多个ssh密钥。