关于bash:如何指定在git上执行shell命令时要使用的专用ssh密钥?

How to specify the private SSH-key to use when executing shell command on Git?

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

基本上是这样的:

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

或者更好(红宝石):

1
2
3
with_key("/home/christoffer/ssh_keys/theuser") do
  sh("git clone [email protected]:TheUser/TheProject.git")
end

我已经看到了使用使用指定私钥的net::ssh连接到远程服务器的示例,但这是一个本地命令。有可能吗?


这些解决方案对我都不起作用。

相反,我详细阐述了@martin v.l?WIS提到为ssh设置一个config文件。

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

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

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

1
git remote add origin git@gitserv:myrepo.git

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

1
git push -v origin master

笔记

  • 为了防止ssh默认行为发送与每个协议的默认文件名匹配的标识文件,需要使用IdentitiesOnly yes。如果您有一个名为~/.ssh/id_rsa的文件,在没有此选项的情况下,它将在您的~/.ssh/id_rsa.github之前被试用。

工具书类

  • 在一个客户机上使用多个ssh私钥的最佳方法
  • 我怎么能停止ssh提供错误的密钥呢?


这样的方法应该有效(由ORIP建议):

1
ssh-agent bash -c 'ssh-add /somewhere/yourkey; git clone [email protected]:user/project.git'

如果您喜欢子shell,可以尝试以下方法(尽管它更脆弱):

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

Git将调用ssh,ssh将按环境变量查找其代理;这将依次加载密钥。

或者,设置HOME也可以做到这一点,前提是您愿意将只包含.ssh目录的目录设置为HOME;这可以包含identity.pub,也可以包含设置identity file的配置文件。


其他人对~/.ssh/config的建议是非常复杂的。它可以简单到:

1
2
Host github.com
  IdentityFile ~/.ssh/github_rsa


从Git2.3.0开始,我们还有简单的命令(不需要配置文件):

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

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


我的Git-ssh-u包装的内容:

1
2
3
#!/bin/bash

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

然后您可以通过执行以下操作来使用密钥:

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


为了总结答案和评论,设置Git以使用不同的密钥文件然后忽略它的最佳方法是编辑~/.ssh/configc:\Users\\.ssh\config并指定多个标识,这也支持同一主机的不同用户(例如个人GitHub帐户和工作帐户),该帐户也在Windows上工作:

1
2
3
4
5
6
7
8
9
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命令。

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


使用git 2.10+(2016年第3季度:2016年9月2日发布),您可以为GIT_SSH_COMMAND设置配置(而不仅仅是rober jack will's answer中描述的环境变量)。

见NGUY提交的承诺书3c8ede3(2016年6月26日)?第二次世界大战?杜伊(pclouds)。(由Junio C Hamano——EDOCX1【2】——于2016年7月19日提交DC21164合并)

A new configuration variable core.sshCommand has been added to
specify what value for GIT_SSH_COMMAND to use per repository.

1
core.sshCommand:

If this variable is set, git fetch and git push will use the specified command instead of ssh when they need to connect to a remote system.
The command is in the same form as the GIT_SSH_COMMAND environment variable and is overridden when the environment variable is set.

这意味着git clone可以是:

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


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

您可以为每个回购配置它:

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


我使用了git_sh环境变量。这是我的包装器,类似于上面的JoeBlock,但可以处理任意数量的参数。

文件~/gitwrap.sh

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

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

1
export GIT_SSH=~/gitwrap.sh


将主机或IP添加到.ssh/config文件中的更好方法是这样:

1
2
3
4
5
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)


其中许多解决方案看起来很诱人。但是,我发现下面链接中的通用Git包装脚本方法最有用:

如何使用git命令指定ssh密钥文件

要点是没有git命令,如下所示:

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

Alvin的解决方案是使用一个定义良好的bash包装器脚本来填补这个空白:

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

其中,git.sh为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/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进行远程bitback repo的用户/密钥识别时遇到的一个问题;所有这些问题现在在cron作业脚本中都可以正常工作,否则在有限shell的导航中会遇到问题。我还可以从R中调用这个脚本,仍然可以解决完全相同的cron执行问题。(如system("bash git.sh -i ~/.ssh/thatuserkey.pem pull"))。

不是R和Ruby一样,但是如果R能做到…O:)


当您需要以正常请求(git pull origin master连接到github时,在~/.ssh/config中将主机设置为*对我有效,任何其他主机(如"github"或"gb")都不起作用。

1
2
3
4
5
Host *
    User git
    Hostname github.com
    PreferredAuthentications publickey
    IdentityFile ~/.ssh/id_rsa_xxx


git_ssh_command="ssh-i/path/to/git private access key"git克隆$git_repo


如果这里的其他解决方案都不适用于您,并且您已经创建了多个ssh密钥,但仍然不能执行诸如

1
git pull

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

1
2
id_rsa
id_rsa_other_key

然后,在您正在努力处理的git repo(cd)内部,尝试:

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

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

1
2
3
# Run these commands INSIDE your git directory
git config user.name"Mona Lisa"
git config user.email"[email protected]"

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


您可以使用git_ssh环境变量。但您需要将ssh和选项包装到shell脚本中。

参见你的命令shell中的git手册:man git


在带有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 [email protected]:test/test.git',哪个私钥在驱动器D中,计算机的文件夹测试。另外,如果要克隆存储库,可以使用git clone更改git remote add origin

在进入git bash之后,它会要求您输入密码!

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

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


您需要创建~/.ssh/config,如下所示

1
2
3
4
5
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

许可如下

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

将您的公钥添加到Git中(cat~/.ssh/id_rsa_pub[或similar name])

然后git克隆如下

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

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

1
2
3
4
5
host github.com
  ControlPath ~/Projects/work/**
  HostName github.com
  IdentityFile ~/.ssh/id_work
  User git

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


用于Gitlab RSAAuthentication yes

1
2
3
4
Host gitlab.com
  RSAAuthentication yes
  IdentityFile ~/.ssh/your_private_key_name
  IdentitiesOnly yes

医生在这里


以下是我在寻找解决此问题的方法时发现的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'

哇!您有一个快捷方式,可以随时切换按键!

希望这对你有用。


如果ssh端口号不是22(默认),则在~/.ssh/config中添加Port xx

在我的案例中(概要)

1
2
3
4
5
Host my_synology
    Hostname xxxx.synology.me
    IdentityFile ~/.ssh/id_rsa_xxxx
    User myname
    Port xx

然后使用配置中的主机标题进行克隆。"我的概要"。避免@chopstik的"*")

1
git clone my_synology:path/to/repo.git

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

1
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代理
  • 向代理添加只读密钥
  • 将目录更改为我的git repo
  • 如果cdto repo dir成功,从远程repo拉
  • 杀死生成的ssh代理。(我不想让很多特工在这里逗留。)

如果你和我一样,你可以:

  • 保持您的ssh密钥井然有序

  • 保持Git克隆命令简单

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

  • 减少ssh密钥维护。

我把钥匙放在我的~/.ssh/keys目录中。

比起配置,我更喜欢约定。

我认为法典就是法律,越简单越好。

步骤1-创建别名

在shell中添加这个别名:alias git-clone='GIT_SSH=ssh_wrapper git clone'

步骤2-创建脚本

将此ssh_包装脚本添加到您的路径:

1
2
3
4
5
6
7
8
#!/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键:

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

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

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

使用bitback.org/lsheehan键:

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

笔记

将ssh-wrapper脚本中的缺省ssh-u密钥更改为您大多数时候使用的密钥。这样,大多数时候不需要使用键变量。

你可能会想,"嘿!一个别名、一个脚本和一些键的目录经常发生这种情况,"但对我来说,这是惯例。几乎我所有的工作站(以及相关的服务器)的配置都是类似的。

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

我的约定(如bash脚本、别名等)创建了一个一致的环境,并帮助我保持简单。

吻和名字很重要。

更多设计技巧请参阅Go from my book中的第4章实体设计:https://www.amazon.com/learning-functional-programming-lex-sheehan-ebook/dp/b0725b8myw

希望有帮助。-莱克斯