你如何指定 `go get` 将使用哪个 ssh 密钥
How can you specify which ssh key `go get` will use
我在同一台笔记本电脑(运行 Ubuntu 版本 20)上使用两个不同的 github 帐户(个人和工作)。我需要能够使用我工作的 ssh 密钥从工作中访问私有存储库 github 帐户。
我使用一些简洁的 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 配置 core.sshCommand
.
经过大量的反复试验和深入挖掘,我找到了解决方案。如果我在私人仓库中设置环境变量 GIT_SSH_COMMAND="ssh -i ~/.ssh/id_ecdsa"
,那么 go get
使用正确的 ssh 密钥,然后用于私人仓库。 go get
似乎忽略了 git 配置 core.sshCommand
但正在考虑环境变量 GIT_SSH_COMMAND
.
为了简化我的生活,我使用程序 direnv
在我保存工作回购协议的文件夹中设置此环境变量。顶层文件夹中的 .envrc
文件如下所示:
export GIT_SSH_COMMAND="ssh -i ~/.ssh/id_ecdsa"
您的 ~/.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
您可以使用SSH-Agent。 ssh-agent
是 openssh 的一部分。它还在内存中保存未加密的密钥和证书。它们已准备好供 ssh 使用。
例如,当您拥有带有 passphase
的 ssh 密钥时,它会非常有用。默认情况下,它每次都会要求您输入密钥密码,go 正在尝试 clone/pull 来自上游的代码。
命令很少,可以使用:
echo $SSH_AGENT_PID
- 查看代理是否分配给当前会话。 SSH_AGENT_PID
变量应该 return 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$
之后我可以使用受 passphase 保护的 ssh 密钥拉取远程代码,而无需每次都输入它,密钥是必需的。
我在同一台笔记本电脑(运行 Ubuntu 版本 20)上使用两个不同的 github 帐户(个人和工作)。我需要能够使用我工作的 ssh 密钥从工作中访问私有存储库 github 帐户。
我使用一些简洁的 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 配置 core.sshCommand
.
经过大量的反复试验和深入挖掘,我找到了解决方案。如果我在私人仓库中设置环境变量 GIT_SSH_COMMAND="ssh -i ~/.ssh/id_ecdsa"
,那么 go get
使用正确的 ssh 密钥,然后用于私人仓库。 go get
似乎忽略了 git 配置 core.sshCommand
但正在考虑环境变量 GIT_SSH_COMMAND
.
为了简化我的生活,我使用程序 direnv
在我保存工作回购协议的文件夹中设置此环境变量。顶层文件夹中的 .envrc
文件如下所示:
export GIT_SSH_COMMAND="ssh -i ~/.ssh/id_ecdsa"
您的 ~/.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
您可以使用SSH-Agent。 ssh-agent
是 openssh 的一部分。它还在内存中保存未加密的密钥和证书。它们已准备好供 ssh 使用。
例如,当您拥有带有 passphase
的 ssh 密钥时,它会非常有用。默认情况下,它每次都会要求您输入密钥密码,go 正在尝试 clone/pull 来自上游的代码。
命令很少,可以使用:
echo $SSH_AGENT_PID
- 查看代理是否分配给当前会话。SSH_AGENT_PID
变量应该 returnssh-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$
之后我可以使用受 passphase 保护的 ssh 密钥拉取远程代码,而无需每次都输入它,密钥是必需的。