指定在使用或不使用Ruby的情况下执行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连接到远程服务器的示例,它使用指定的私钥,但是这是本地命令。 可能吗?

像这样的东西应该工作(由oripbuild议):

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

如果你喜欢subshel​​l,你可以尝试以下(虽然它更脆弱):

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

Git会调用SSH,通过环境variablesfind它的代理; 这将会反过来加载密钥。

另外,如果你愿意设置一个只包含一个.ssh目录作为HOME的目录,设置HOME也可以实现这个function。 这可能包含一个identity.pub,或configuration文件设置IdentityFile。

这些解决scheme都不适合我。

相反,我详细阐述了@Martin v。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必需的,以防止发送与每个协议的默认文件名匹配的标识文件的SSH默认行为 。 如果你有一个名为~/.ssh/id_rsa的文件,在你的~/.ssh/id_rsa.github没有这个选项的时候会试一下。

参考

  • 在一个客户端上使用多个SSH私钥的最佳方法
  • 我怎么能阻止ssh提供一个错误的关键

其他人对~/.ssh/config的build议是非常复杂的。 它可以像下面这样简单:

 Host github.com IdentityFile ~/.ssh/github_rsa 

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

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

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 

总结答案和评论 ,设置git使用不同的密钥文件,然后忘记它,也支持同一个主机(例如个人GitHub帐户和工作一个不同的用户),它适用于Windows编辑~/.ssh/config (或c:\Users\<your user>\.ssh\config ~/.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命令。

要以工作用户身份克隆回购,运行git clone git@github-work:company/project.git

我去了GIT_SSH环境variables。 这是我的包装,类似于从上面的Joe块,但处理任何数量的参数。

文件〜/ gitwrap.sh

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

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

 export GIT_SSH=~/gitwrap.sh 

使用git 2.10+(2016年第三季度:2016年9月2日发布),您可以为GIT_SSH_COMMAND设置configuration (而不仅仅是Rober Jack Will的答案中描述的环境variables)

参见NguyễnTháiNgọcDuy( pclouds )的 commit 3c8ede3 (2016年6月26日) 。
(由Junio C gitster合并- gitster – in commit dc21164 ,2016年7月19日)

已经添加了一个新的configurationvariablescore.sshCommand来指定GIT_SSH_COMMAND为每个存储库使用的值。

 core.sshCommand: 

如果设置了这个variables,当他们需要连接到远程系统时, git fetchgit push会使用指定的命令而不是ssh
该命令与GIT_SSH_COMMAND环境variables的forms相同,并且在GIT_SSH_COMMAND环境variables时被覆盖。

这意味着git clone可以是:

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

将主机或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) 

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

您可以configuration每个回购:

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

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

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

许多这些解决scheme看起来很诱人。 但是,我发现在下面的链接中使用通用的git-wrapping-script方法是最有用的:

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

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

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

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

 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 "$@" 

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

不是说R和Ruby是一样的,但是如果R可以做到的话…… O 🙂

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

请参阅git手册:在命令行中inputman git

我的伎俩是使用git @ hostname而不是http://主机名

在使用Git Bash的Windows中,您可以使用以下命令来添加存储库ssh-agent bash -c 'ssh-add "key-address"; git remote add origin "rep-address"' 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' ssh-agent bash -c 'ssh-add /d/test/PrivateKey.ppk; git remote add origin git@git.test.com:test/test.git'驱动器D中的私钥,计算机的文件夹testing。 另外,如果你想克隆一个仓库,你可以用git clone来改变git remote add origin

input这个Git Bash后,它会问你的密码!

意识到openssh私钥和putty私钥是不一样的!

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

我使用zsh ,不同的密钥自动加载到我的zsh shell的ssh-agent用于其他目的(即访问远程服务器)在我的笔记本电脑上。 我修改了@尼克的答案,我正在使用它作为我需要经常刷新的回购协议之一。 (在这种情况下,我所有的机器上都需要相同的最新版本的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代理
  • 将只读密钥添加到代理
  • 改变目录到我的git仓库
  • 如果cd回购目录成功,从远程回购拉
  • 杀死衍生的ssh-agent。 (我不想让很多代理人徘徊。)

对于gitlab RSAAuthentication yes

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

doc在这里

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

在我的情况下(synology),

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

然后在configuration中使用主机标题克隆。 (“my_synology”,避免@chopstik的“*”)

 git clone my_synology:path/to/repo.git