Docker 加载键“/root/.ssh/id_rsa”:格式无效

Posted

技术标签:

【中文标题】Docker 加载键“/root/.ssh/id_rsa”:格式无效【英文标题】:Docker Load key "/root/.ssh/id_rsa": invalid format 【发布时间】:2020-04-17 23:14:45 【问题描述】:

我正在尝试克隆其中包含子模块的存储库。主仓库可以很好地克隆,但是当我在 dockerfile 中执行 git submodule update --init --recursive 时,子模块会抛出错误。

fatal: clone of 'git@github.com:jkeys089/lua-resty-hmac.git' into submodule path '/tmp/third-party/lua-resty-hmac' failed
Failed to clone 'third-party/lua-resty-hmac'. Retry scheduled
Cloning into '/tmp/third-party/lua-resty-jwt'...
load pubkey "/root/.ssh/id_rsa": invalid format
Warning: Permanently added the RSA host key for IP address '140.82.118.3' to the list of known hosts.
Load key "/root/.ssh/id_rsa": invalid format
git@github.com: Permission denied (publickey).

在图片中我有这个

# authorise ssh host
RUN mkdir /root/.ssh/ \
    && chmod 700 /root/.ssh \
    && ssh-keyscan github.com > /root/.ssh/known_hosts

# add key and set permission
RUN echo "$SSH_PRIVATE_KEY" >> /root/.ssh/id_rsa \
    && echo "$ssh_pub_key" > /root/.ssh/id_rsa.pub \
    && chmod 600 /root/.ssh/id_rsa.pub \
    && chmod 600 /root/.ssh/id_rsa

我无法控制子模块。我不确定是否可以从 git@github.com 更改为 https 以获取子模块。

我什至尝试过使用GITHUB_TOKEN 路由

# start up git and clone
RUN git config --global url."https://$GITHUB_TOKEN@github.com/".insteadOf "https://github.com/" \
    && git clone https://github.com/GluuFederation/gluu-gateway.git /tmp \
    && cd /tmp/ \
    && git submodule update --init --recursive

下面是构建命令的一部分。 build --build-arg GITHUB_TOKEN=$GITHUB_TOKEN --build-arg SSH_PRIVATE_KEY="$(cat ~/.ssh/id_rsa)" --build-arg ssh_pub_key="$(cat ~/.ssh/id_rsa.pub)"

请帮忙解决这个问题。这非常令人沮丧。 :(

【问题讨论】:

您作为SSH_PRIVATE_KEY 传递的文件是公钥。请注意,这样做会损害您的密钥对,因为任何获取映像的人都可以轻松提取它,并且在 Dockerfile 中运行 git 命令还有其他几个缺点;在运行 docker build 之前,我会在主机上进行设置(克隆存储库,查看我想要构建的特定分支,...)。 您可以使用相同的 insteadOf 技巧将 git@github.com:... 更改为 https URL,但请参阅 David Maze 的评论。 我的想法是,如果这样可行,我可以使用多阶段构建来避免在构建历史中留下私钥痕迹。 我已经更新了问题 - 关于构建命令中的 pub 键。我仍然遇到同样的错误。 你的私钥第一行的文本(破折号之间的部分)是什么,你在容器中运行的是什么操作系统? 【参考方案1】:

另一个可能的问题是,如果您使用 Makefile 来运行 docker build 命令。在这种情况下,Makefile 中的命令如下所示:

docker-build:
    docker build --build-arg SSH_PRIVATE_KEY="$(shell cat ~/.ssh/id_rsa)"

Make 不幸地将换行符替换为空格 (make shell)

这意味着写入容器中的ssh密钥格式不同,产生上述错误。

我无法找到在 Makefile 命令中保留换行符的方法,因此我采用了一种解决方法,将 .ssh 目录复制到 docker build 上下文中,通过 Dockerfile 复制文件,然后删除它们。

【讨论】:

【参考方案2】:

如果密钥是“无效格式”,请尝试使用old PEM format 重新生成它。

ssh-keygen -m PEM -t rsa -P "" 

确保将公钥添加到您的 GitHub 帐户以进行正确的身份验证。

OP Shammir 加上in the comments:

我认为问题是在构建过程中没有任何内容从主机复制到 docker 映像。

在“docker build --build-arg SSH_PRIVATE_KEY="$(cat ~/.ssh/id_rsa)" returning empty”中,Shammir 使用dockito/vault 管理私钥,但也将其配置为“AddKeysToAgent”:如果私钥没有密码保护(如我上面的命令),则不需要/p>

【讨论】:

我认为问题是在构建期间没有任何内容从主机复制到 docker 映像。我在这里问过这个问题***.com/questions/59541238/… @Shammir 我已将您的评论和解决方案包含在答案中以提高知名度。【参考方案3】:

不要使用echo "$SSH_PRIVATE_KEY" >> /root/.ssh/id_rsa 传递私钥(公钥也一样)。我尝试时遇到了类似的错误Load key "/root/.ssh/id_rsa": invalid format

RUN echo "$ssh_prv_key" > /root/.ssh/id_rsa &&     chmod 600 /root/.ssh/id_rsa

这导致了像identity file /root/.ssh/id_rsa type -1 invalid formatread_passphrase: can't open /dev/tty 这样的错误。

正确的方法是使用

COPY id_rsa /root/.ssh/id_rsa
RUN chmod 600 /root/.ssh/id_rsa

解决方案解释:我的私钥格式错误 - 它不是多行,而是作为单行传递,您可能有任何其他格式问题,例如在开头或结尾忘记了“-”,或其他行尾错误,例如缺少换行符格式或行尾多了一个字母。

更多详情请参见Dockerfile: clone repo with passwordless private key. Errors: “authentication agent” or “read_passphrase: can't open /dev/tty”,主要思想来自Add private key to ssh-agent in docker file,其思想又来自Gitlab CI/Docker: ssh-add keeps asking for passphrase。

【讨论】:

为此,每次构建映像时,您都必须将密钥文件保存在同一目录中,这可能是一个安全问题(想想如果您错误地将密钥推送到 GitHub 或任何版本控制) @ChayanBansal 您也可以从不在 github 目录中的文件夹中复制密钥。除此之外,您必须在每次使用后删除私钥,因为它以纯文本形式保存在图像中。这很尴尬,然而,这里主要的不是高效,而是让它在 Dockerfile 中运行。还有一种方法可以避免将私钥保存在图像中,方法是在第一个图像之上设置第二个图像并仅复制需要的内容,请参阅Using SSH keys inside docker container。最近,您可能更愿意使用部署密钥。【参考方案4】:

仅供参考。

我手动创建了一个私钥文件key.id_rsa 并将内容粘贴到其中。但是当我用它来克隆 git 存储库时:

$ git clone my_repo
Cloning into 'my_repo'...
Load key "/path/to/key.id_rsa": invalid format

密钥的内容绝对正确。然后我尝试将我的密钥与ssh-keygen 生成的另一个密钥进行比较,它确实是无效格式

我的钥匙中只有没有换行符的结尾

在key末尾添加新行后,一切都很顺利~惊喜!

[更新]:记得使用 \n 而不是 \r\n,即使在 Windows 上也是如此。

【讨论】:

我想这只是解决使用COPY 而不是echo 无法解决的问题?则无需手动添加\n。请参阅同一线程的my answer。【参考方案5】:

此答案适用于 Windows 用户(未在 linux 上尝试过)。

我搜索了许多答案和文章,但在构建我的 docker 映像时仍然遇到格式无效错误。

实际原因是当我们将私钥文件的内容作为参数传递时,它们是在一行中传递的。转义字符被转换为空格,这对于键来说基本上是无效的格式。为了避免这个错误,有两种方法可以将私钥传递给 docker 镜像:

    在docker文件中使用COPY命令复制私钥文件并在docker镜像中使用。这不是一个好的选择,因为它可能会暴露您的私钥。示例:COPY id_rsa /root/.ssh/id_rsa 这是我使用的一种 hack,它很有效。在文本编辑器中打开私钥文件并在私钥的每一行末尾添加\n,然后将每一行连接起来以在一行中创建整个密钥。例如,您生成的密钥如下所示:

-----开始打开SSH私钥----- b3BlbnNzaC1redjEAAAAABG5vvmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW QyNTUxOQAAACdmF7/Vo4m2FWPf+8uZRRF88dnsyj+z+lCWNWBrT8gAAAJh1tssodbbL -----结束 OPENSSH 私钥-----

让它看起来像这样:

----- BEGIN OpenSSH的私钥----- \n b3BlbnNzaC1redjEAAAAABG5vvmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW \n QyNTUxOQAAACdmF7 / Vo4m2FWPf + 8uZRRF88dnsyj + Z + lCWNWBrT8gAAAJh1tssodbbL \n ----- END OPENSSH 私钥-----\n

将其保存在密钥文件中,并在构建 docker 映像时将修改后的文件传递到参数中。

【讨论】:

这是对同一线程的my answer 的重复。 谢谢!经过 2 小时的战斗,将 \n 添加到 windows 上的私有 ssh 密钥修复了问题。问题仍然是,有没有办法以正确的格式生成密钥,以便它适用于所有系统?很久以来这是我第一次遇到这个问题。 @DanielKemeny,实际上密钥是以正确的格式生成的。没有什么问题。当我们通过 --build-arg 传递它并通过 dockerfile 中的“echo”使用它时,密钥的格式会发生变化。参数在一行中传递,因此破坏了密钥。【参考方案6】:

确保在最后一行之后有一个 \n。 我花了太长时间才弄清楚这一点。

【讨论】:

以上是关于Docker 加载键“/root/.ssh/id_rsa”:格式无效的主要内容,如果未能解决你的问题,请参考以下文章

在/etc/docker/下 创建daemon.json重新加载后docker无法启动问题 /etc/docker/daemon.json编辑不了 找不到

在/etc/docker/下 创建daemon.json重新加载后docker无法启动问题 /etc/docker/daemon.json编辑不了 找不到

使用 Docker 和 PHP 从 env 文件加载环境变量

无法加载缓存键:拉取访问被拒绝 powershell

Docker 构建无法计算缓存键

docker加载本地镜像