当在 ssh-agent 中同时加载两个 ssh-keys 时,克隆(更新)git 子模块失败

Cloning (updating) git submodule fails when two ssh-keys are loaded at the same time in ssh-agent

我正在处理几个 maven 项目,其中常见的 java-类 被放置在一个子模块中。然后将子模块添加到每个 maven 项目,并将项目从私有 github-repo 克隆到 docker 容器。

我为每个项目和子模块创建了一个 ssh-key,将 public 密钥添加到 github-repo 中 'Settings' 中的 'Deploy keys'。所有密钥都是在没有密码的情况下创建的。

下载主仓库很顺利,但添加子模块失败 git@github.com: Permission denied (publickey).。因此编译失败。在克隆 repo 和更新子模块之前加载了两个密钥。

原来我一次只能加载一个密钥。所以我修改了克隆的脚本,以便它在加载子模块的密钥之前卸载所有密钥。

eval $(ssh-agent -s)
ssh-add /home/docker/.ssh/id_ed25519_maven_repo
ssh-keyscan -H github.com >> /home/docker/.ssh/known_hosts

cd /home/docker/code
git clone git@github.com:foo/main.git
cd main

ssh-add -D   <--- Unload all keys ---
ssh-add /home/docker/.ssh/id_ed25519_submodule
git submodule init
git submodule update

mvn compile

为什么我必须在更新子模块之前卸载和加载而不是同时加载两个密钥?

(故障排除时间)

听起来您有两个 SSH 密钥,它们要么与不同的 GitHub 帐户相关联,要么是具有不同存储库的部署密钥。如果是这样,发生这种情况的原因是 SSH 协议。

当任何用户想要使用 SSH 密钥通过 SSH 连接到远程计算机时,身份验证发生在发送任何命令或了解所需行为之前。在这种情况下,所有用户都连接到 github.com 上的 git 用户,因此区分用户和他们拥有的访问权限的唯一方法是通过 SSH 密钥。如果您使用特定密钥进行身份验证并且该密钥对 some 访问有效,GitHub 将接受它,然后如果它对您要访问的内容无效,则它会拒绝你的请求。

由于 SSH 协议不允许在身份验证完成之前指定要访问的资源,GitHub 无法知道您是否真的想使用不同的密钥来访问该资源,而这个密钥确实可以有能力访问它。

如果您需要为不同的资源使用多个 SSH 密钥,这种情况是 covered in the Git FAQ:

For example, you could write something like the following in ~/.ssh/config, substituting the proper private key file:

# This is the account for author on git.example.org.
Host example_author
    HostName git.example.org
    User git
    # This is the key pair registered for author with git.example.org.
    IdentityFile ~/.ssh/id_author
    IdentitiesOnly yes
# This is the account for committer on git.example.org.
Host example_committer
    HostName git.example.org
    User git
    # This is the key pair registered for committer with git.example.org.
    IdentityFile ~/.ssh/id_committer
    IdentitiesOnly yes

Then, you can adjust your push URL to use git@example_author or git@example_committer instead of git@example.org (e.g., git remote set-url git@example_author:org1/project1.git).