如何指定在Git上执行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") dosh("git clone git@github.com:TheUser/TheProject.git")end

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

1673960 次浏览

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

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

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

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

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

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

可以使用GIT_SSH环境变量,但需要将ssh和选项包装到外壳脚本中。

请参阅命令shell中的git手册:man 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

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

相反,我详细说明@Martin v. Löwis提到的为SSH设置config文件。

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

Host gitservHostname remote.server.comIdentityFile ~/.ssh/id_rsa.githubIdentitiesOnly 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之前尝试。

参考文献

更好的方法是将该主机或IP添加到.ssh/config文件中,如下所示:

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

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

文件~/gitwrap.sh

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

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

export GIT_SSH=~/gitwrap.sh

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

Host *User gitHostname github.comPreferredAuthentications publickeyIdentityFile ~/.ssh/id_rsa_xxx

其他人关于~/.ssh/config的建议更加复杂。它可以像这样简单:

Host github.comIdentityFile ~/.ssh/github_rsa

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

Host github.comHostName github.comIdentityFile /path/to/your/personal/github/private/keyUser dandv
Host github-workHostName github.comIdentityFile /path/to/your/work/github/private/keyUser workuser

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

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

这些解决方案中的许多看起来很诱人。然而,我发现以下链接中的通用git-包装脚本方法是最有用的:

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

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

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

Alvin的解决方案是使用定义良好的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 ]; thenecho "Git wrapper script that can specify an ssh-key fileUsage:git.sh -i ssh-key-file git-command"exit 1fi
# remove temporary file on exittrap 'rm -f /tmp/.git_ssh.$$' 0
if [ "$1" = "-i" ]; thenSSH_KEY=$2; shift; shiftecho "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 commandgit "$@"

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

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

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

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

请注意,需要-o IdentitiesOnly=yes来防止发送与每个协议的默认文件名匹配的标识文件的SSH默认行为,如上面的答案所述。

使用git 2.10+(2016年第三季度:2016年9月2日发布),您可以为GIT_SSH_COMMAND设置配置(而不仅仅是罗伯特·杰克·威尔回答中描述的环境变量)

参见提交3c8ede3(2016年6月26日)byNguy n Thái Ng c Duy(#0)
(由Junio C Hamano----#0----合并于提交dc21164,19 Jul 2016)

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

core.sshCommand:

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

这意味着git pull可以是:

cd /path/to/my/repo/already/clonedgit config core.sshCommand 'ssh -i private_key_file'# later ongit pull

您甚至可以将其设置为一个命令,例如git clone

git -c core.sshCommand="ssh -i private_key_file" clone host:repo.git

这比设置GIT_SSH_COMMAND环境变量更容易,在Windows上,注意 byMátyásKuti-Kreszács将是

set "GIT_SSH_COMMAND=ssh -i private_key_file"

在带有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私钥是不同的!

如果你已经创建了你的密钥,你必须将你的私钥转换为openssh!

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

您可以将其配置为per-repo:

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

我使用zsh,不同的密钥会自动加载到我笔记本电脑上的zsh shellssh-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代理
  • 向代理添加只读密钥
  • 将目录更改为我的git repo
  • 如果cd到repo dir成功,则从远程repo拉取
  • 杀死派生的ssh代理。(我不希望很多代理在周围徘徊。)

对于gitlabRSAAuthentication yes

Host gitlab.comRSAAuthentication yesIdentityFile ~/.ssh/your_private_key_nameIdentitiesOnly yes

文档在这里

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

在我的情况下(语法),

Host my_synologyHostname xxxx.synology.meIdentityFile ~/.ssh/id_rsa_xxxxUser mynamePort xx

然后使用配置中的主机标题克隆。(“my_synology”。以避免@chopstik的“*”)

git clone my_synology:path/to/repo.git

如果这里的其他解决方案都不适合您,并且您已经创建了多个ssh-key,但仍然无法执行以下简单操作

git pull

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

id_rsaid_rsa_other_key

然后在git repo中,尝试:

# Run these commands INSIDE your git directoryeval `ssh-agent -s`ssh-add ~/.ssh/id_rsassh-add ~/.ssh/id_rsa_other_key

并确保您的github默认用户名和userid是正确的:

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

查看https://gist.github.com/jexchan/2351996了解更多信息。

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

Host <Your bitbucket server>User <userid>Hostname <Your bitbucket server as above>IdentitiesOnly yesIdentityFile ~/.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

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

  • 让你的ssh密钥井井有条

  • 保持git clone命令简单

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

  • 减少ssh密钥维护。

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

我更喜欢约定而不是配置。

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

步骤1-创建别名

将此别名添加到您的shell:alias git-clone='GIT_SSH=ssh_wrapper git clone'

第2步-创建脚本

将此ssh_wrapper脚本添加到您的PATH:

#!/bin/bash# Filename: ssh_wrapper
if [ -z ${SSH_KEY} ]; thenSSH_KEY='github.com/l3x'  # <= Default keyfiSSH_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更改为您大部分时间使用的内容。这样,您大部分时间都不需要使用KEY变量。

你可能会想,嘿!别名、脚本和一些密钥目录太多了,但对我来说,这是惯例。几乎我所有的工作站(和服务器)都是类似的配置。

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

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

吻和名字很重要。

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

希望有帮助-莱克斯

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

export GIT_SSH_COMMAND="ssh -i /path/to/git-private-access-key"git clone REPOgit push

这是我在寻找解决此问题的方法时发现的ssh key hack:

例如,您有2个不同的密钥集:

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'

瞧!你有一个快捷方式来随时切换键!

希望这对你有用。

如果您的路径上有目录,您想使用给定的标识文件进行签名,您可以通过设置#0来指定使用特定的标识文件,例如:

host github.comControlPath ~/Projects/work/**HostName github.comIdentityFile ~/.ssh/id_workUser git

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

问题是当你有同一主机上的不同远程存储库(比如github.com),你想使用不同的ssh密钥(即不同的GitHub帐户)与它们交互。

为了做到这一点:

  1. 首先,您应该在~/.ssh/config文件中声明不同的键。

    # Key for usual repositories on github.comHost github.comHostName github.comUser gitIdentityFile ~/.ssh/id_rsa
    # Key for a particular repository on github.comHost XXXHostName github.comUser gitIdentityFile ~/.ssh/id_other_rsa

    通过这样做,您将第二个键与一个新的友好名称“XXX”相关联github.com.

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

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

    >git remote -vorigin  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 -vorigin  git@XXX:myuser/myrepo.git (fetch)origin  git@XXX:myuser/myrepo.git (push)

    现在您可以自动使用正确的键推送、获取……。

让GIT_SSH_COMMAND环境变量在Windows(CMD)下工作,而不是:

set GIT_SSH_COMMAND="ssh -i private_key_file"

用途:

set "GIT_SSH_COMMAND=ssh -i private_key_file"

引文必须是这样的

set "variable=value"

##https://stackoverflow.com/a/34402887/10671021

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

我认为重要的是要明确强调,如果您通过克隆Web URL开始您的项目-https://github.com/<user-name>/<project-name>.git
然后你需要在.git/config已更改为SSHURL[remote "origin"]确保url(见下面的代码块)。

除此之外,请确保您添加sshCommmand,如下所述:

user@workstation:~/workspace/project-name/.git$ cat config[core]repositoryformatversion = 0filemode = truebare = falselogallrefupdates = truesshCommand = 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 URLfetch = +refs/heads/*:refs/remotes/origin/*[branch "master"]remote = originmerge = refs/heads/master

阅读更多关于它这里

您可以尝试sshmultil npm包来维护多个ssh密钥。

这种方法的问题是,至少在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代理-k将在进程完成后终止该进程。

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

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

从Git版本2.10.0开始,您可以根据存储库或全局配置此

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

这将为当前存储库指定ssh键将使用的内容。我假设如果您想指定此全局只需要设置--global选项。

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

这将克隆您服务器上的存储库到您的本地文件夹“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

最快和最简单的方法是:

使用ssh克隆您的repo:

git -c core.sshCommand="ssh -i ~/.ssh/<your_key>" clone git@github.com:<user>/<repo>.git

然后cd到你克隆的repo和:

git config core.sshCommand 'ssh -i ~/.ssh/<your_key>'

要测试它的工作:

git --git-dir=/path/to/repo/.git pull

所以你可能想知道:在我在github中植入. pub并且私有在默认目录中之后为什么我创建的ssh密钥不起作用

留档给了我们一个澄清问题的命令:ssh -vT git@github.com

输出显示git查找的ssh键名称列表。因此,您可能希望使用其中一个名称创建密钥,或者使用上述过程来包含您需要的名称。

这里给出的大多数答案都没有解释最基本用法的细节。

在云中设置服务器(在本例中为linux服务器)后,您可以从终端使用ssh连接到它。

在您的计算机上,将您的云服务提供商(如Azure、AWS等)提供给您的私钥dyson-ubuntu-vm.pem添加到您本地计算机上的. ssh配置中,如下所示:

.pem文件复制到/home/ssenyonjo/.ssh文件夹,然后打开/home/ssenyonjo/.ssh/config文件并添加以下条目:

Host 20.85.213.44HostName 20.85.213.44User DysonIdentityFile /home/ssenyonjo/.ssh/dyson-ubuntu-vm.pemIdentitiesOnly yes

现在从您的终端,像这样访问云Linux服务器:

ssh Dyson@20.85.213.44

当它工作时,在云服务器上创建一个git项目,如下所示:

Dyson@dyson-ubuntu-vm:~/projects$ git init --bare s2

现在回到您的本地机器并像这样克隆该空存储库:

ssenyonjo@ssenyonjo-pc:~/Projects/mastering-git$ git clone ssh://Dyson@20.85.213.44/home/Dyson/projects/s2

如果您看到类似于:fatal: Could not read from remote repository的错误,则表示您访问了错误的文件夹。确保您已经概述了从根到创建的存储库的正确路径。

如果您不想设置配置文件,但想访问需要密钥的ssh服务器,您可以使用以下命令:

GIT_SSH_COMMAND='ssh -i ~/Projects/aws/keys/aws_ubuntu.pem'  git clone ssh://ubuntu@15.207.99.158/home/ubuntu/projects/mastering-git/rand

您可以导出命令以继续将其用于git pushgit pull等其他任务

export GIT_SSH_COMMAND='ssh -i ~/Projects/aws/keys/aws_ubuntu.pem'

见:https://stackoverflow.com/a/29754018/10030693

这是对@VonC答案的扩展。请先阅读。

用例是我需要使用SSH使用个人和工作GitHub帐户。我想默认使用工作SSH密钥,因为我的项目内部将有其他工作存储库作为依赖项。所以克隆它们应该可以无缝工作。

我遵循的步骤是:

  • 生成默认SSH密钥并将其添加到工作git帐户。

  • 在单独的文件中生成个人SSH密钥并将其添加到个人git帐户。

  • .bashrc.zshrc文件中添加以下函数代码并获取源代码。

     gclone() {# Clone the repo-url using personal ssh-keygit -c core.sshCommand="ssh -i path_to_personal_key" clone "$1" &&
    # Extract repo name from URL using "awk" and switch to that folder using "cd"cd $(awk '{ sub(/.*\//, ""); sub(/\.git.*/, ""); print }' <<< "$1") &&
    # Set personal ssh-key as default for this repogit config core.sshCommand "ssh -i path_to_personal_key";}
  • 使用gclone命令使用个人SSH键克隆存储库,并将存储库设置为默认使用该键。

  • 使用普通git clone命令克隆默认(工作)SSH键的存储库。

此命令克隆存储库并将SSH键配置为永久使用:

git clone -c "core.sshCommand=ssh -i ~/.ssh/<key>" git@github.com:<user>/<repo>.git

现在,如果您运行git fetchgit pullgit push,它将使用core.sshCommand中配置的SSH键(保存在.git/config中)。

在一个命令中克隆

git -c core.sshCommand='ssh -i /path/to/key/' clone git@github.com:your_repository.git /path/target/clone --branch git_branch_name