【问题标题】:How can you specify which ssh key `go get` will use如何指定将使用哪个 ssh 密钥 `go get`
【发布时间】:2021-04-10 15:15:36
【问题描述】:

我在同一台笔记本电脑(运行 Ubuntu 版本 20)上使用两个不同的 github 帐户(个人帐户和工作帐户)。我需要能够使用工作 github 帐户的 ssh 密钥从工作中访问私有存储库。

我已经使用一些简洁的 git 配置控件完成了所有工作,即在我放入的 ~/.gitconfig 文件中:

[url "git@github.com:work_account/"]
    insteadOf = https://github.com/work_account/
[includeIf "gitdir:~/src/github.com/personal_account/"]
    path=~/.gitconfig_personal
[includeIf "gitdir:~/src/github.com/work_account/"]
    path=~/.gitconfig_work

个人配置包含:

[user]
name = Your Name
email = your.name@gmail.com
[core]
sshCommand = ssh -i ~/.ssh/id_rsa

工作配置包含:

[user]
name = Your Name
email = your.name@work.com
signingkey = <ID of GPG key>
[core]
sshCommand = ssh -i ~/.ssh/id_ecdsa
[commit]
gpgsign = true
[gpg]
program = gpg

这一切都非常适合从 github 拉取和推送(并使用 gpg 密钥签署工作提交),但是对于私人仓库上的 go get 来说它失败了。出于某种奇怪的原因,go get 试图使用我的个人 ssh 密钥 (~/.ssh/id_rsa) 而不是我的工作 ssh 密钥 (~/.ssh/id_ecdsa)。我已经设置了GOPRIVATE 环境变量,即

export GOPRIVATE=github.com/work_account/*

go get 的输出是这样的:

$ go get github.com/work_account/private_repo
go get github.com/work_account/private_repo: module github.com/work_account/private_repo: git ls-remote -q origin in /home/marc/pkg/mod/cache/vcs/ff3efb332cb48232e5da90ff2073685cbdac4a86e3a47aa11663696f4943637a: exit status 128:
        ERROR: Repository not found.
        fatal: Could not read from remote repository.

        Please make sure you have the correct access rights
        and the repository exists.

我可以看到我的 ssh 代理有两个密钥:

$ ssh-add -l
521 SHA256:EKvhgg24_blah_bApjLSqX4J7l0 your.name@work.com (ECDSA)
4096 SHA256:r/qcO94F+ox_blah_JkTiVk+aERk your.name@gmail.com (RSA)

当我删除我的个人 ssh 密钥(即rm ~/.ssh/id_rsa*)时,go get 在私人存储库上工作得很好,所以我知道它肯定只是试图使用错误的 ssh 密钥。由于某种原因,它忽略了 git config core.sshCommand

【问题讨论】:

    标签: git go github ssh-keys go-get


    【解决方案1】:

    经过大量的反复试验和挖掘,我找到了解决方案。如果我在私有仓库中设置环境变量GIT_SSH_COMMAND="ssh -i ~/.ssh/id_ecdsa",那么go get 使用正确的 ssh 密钥,然后适用于私有仓库。 go get 似乎忽略了 git config core.sshCommand 但考虑到了环境变量 GIT_SSH_COMMAND

    为了简化我的生活,我使用程序 direnv 在我保存工作存储库的文件夹中设置此环境变量。顶级文件夹中的 .envrc 文件如下所示:

    export GIT_SSH_COMMAND="ssh -i ~/.ssh/id_ecdsa"
    

    【讨论】:

      【解决方案2】:

      您需要在您的 ~/.ssh/config 文件中使用它。如果它不存在,只需创建它。它指定用于每个主机的 ssh 密钥。您可以通过添加无效域来添加别名:

      Host gitlab.com
      IdentityFile ~/.ssh/id_ed25519
      
      Host github.com
      IdentityFile ~/.ssh/id_ed25519
      
      Host github.invalid
      HostName github.com
      IdentityFile ~/.ssh/id_rsa
      
      

      然后每次使用 git@github.invalid 时,都会使用正确的 ssh 密钥。

      相关的是 ~/.gitconfig 的新增功能,它有助于导入私有存储库。它使用 ssh 对这些主机进行所有 git 操作:

      
      [url "git@github.com:"]
              insteadOf = https://github.com/
      [url "git@gitlab.com:"]
              insteadOf = https://gitlab.com/
      

      另请参阅环境变量GOPRIVATE,其中列出了不使用代理的私有存储库。 Example:

      GOPRIVATE=*.corp.example.com,rsc.io/private
      

      【讨论】:

      • 这都是有用的东西,但它并没有真正解决试图让go get 使用两个不同的 github 帐户的问题,每个帐户都有自己的 ssh 密钥。
      【解决方案3】:

      您可以使用 SSH 代理。 ssh-agent 是 openssh 的一部分。它还在内存中保存未加密的密钥和证书。它们可供 ssh 使用。

      例如,当您拥有带有passphase 的 ssh-key 时,它会非常有用。默认情况下,它每次都会要求您输入密钥密码阶段,go 正在尝试从上游克隆/拉取代码。

      命令很少,可以使用:

      • echo $SSH_AGENT_PID - 查看代理是否分配给当前会话。 SSH_AGENT_PID 变量应该返回 ssh-agent 的 pid。
      • eval $(ssh-agent) - 开始一个新的ssh-agent 会话。
      • ssh-add -l - 列出 ssh 会话中可用的密钥
      • ssh-add ~/.ssh/tmp/id_rsa - 将 ~/.ssh/tmp/id_rsa 键添加到当前会话。

      示例会话可以是:

      ip-192-168-200-63:tf-r0 daniel$ echo $SSH_AGENT_SOCK
      ip-192-168-200-63:tf-r0 daniel ^C
      
      ip-192-168-200-63:src daniel$ eval `ssh-agent`
      Agent pid 50734
      ip-192-168-200-63:src daniel$ echo $SSH_AGENT_PID 
      50734
      ip-192-168-200-63:src daniel$ ssh-add -l
      The agent has no identities.
      ip-192-168-200-63:src daniel$ ssh-add ~/.ssh/tmp/id_rsa
      Enter passphrase for /Users/daniel/.ssh/tmp/id_rsa: 
      Identity added: /Users/daniel/.ssh/tmp/id_rsa (/Users/daniel/.ssh/tmp/id_rsa)
      ip-192-168-200-63:src daniel$ ssh-add -l
      2048 SHA256:nm/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX /Users/daniel/.ssh/tmp/id_rsa (RSA)
      ip-192-168-200-63:src daniel$ 
      

      之后我可以使用受密码保护的 ssh 密钥拉取远程代码,而无需每次都输入,需要密钥。

      【讨论】:

      • 我已经在使用ssh-agent,它可以看到两个ssh密钥。
      • 您还看到错误吗? @DeanSchulze 编写的关于 go get 和 go 模块的解释非常好:stackoverflow.com/questions/60645866/…
      • 是的,这是一篇有趣的文章。我确实找到了答案(请参阅接受的答案)。本质上,它从ssh-agent 中提取了错误的密钥,因为它忽略了git config core.sshCommand。但是,出于某种奇怪的原因,设置环境变量而不是配置设置有效!即export GIT_SSH_COMMAND="ssh -i ~/.ssh/id_ecdsa"
      猜你喜欢
      • 2012-06-21
      • 2017-02-27
      • 2011-03-30
      • 2014-11-14
      • 2017-01-30
      • 1970-01-01
      • 2019-02-12
      • 1970-01-01
      • 2021-09-21
      相关资源
      最近更新 更多