[英]How to use SSH key in a Windows Container
I have created a windows container that includes a Git client and I am able to clone and checkout from our Bitbucket server using HTTP. This means I need to provide username and password for every transaction with Git. I am now wanting to rather use SSH. So I have generated an SSH key using ssh-keygen and have added the public key to my user account in Bitbucket and on my local PC I am able to transact with Bitbucket successfully as I loaded my key using Pageant.我创建了一个 windows 容器,其中包含一个 Git 客户端,我可以使用 HTTP 从我们的 Bitbucket 服务器克隆和结帐。这意味着我需要为 Git 的每笔交易提供用户名和密码。我现在想使用 854290168因此,我使用 ssh-keygen 生成了一个 SSH 密钥,并将公钥添加到我在 Bitbucket 中的用户帐户,并且在我的本地 PC 上,当我使用 Pageant 加载我的密钥时,我能够成功地与 Bitbucket 进行交易。
Within the container I am struggling to get this to work.在容器内,我正在努力让它发挥作用。 I found some info here which I included in my Dockerfile - specifically the commands Set-Service, Start-Service and Get-Service.
我在这里找到了一些信息,这些信息包含在我的 Dockerfile 中 - 特别是命令 Set-Service、Start-Service 和 Get-Service。 This works up to a point, this line
RUN printf "${SSH_KEY_PASSPHRASE}" | ssh-add C:\Users\Jenkins\.ssh\id_rsa
这在一定程度上起作用,这一行
RUN printf "${SSH_KEY_PASSPHRASE}" | ssh-add C:\Users\Jenkins\.ssh\id_rsa
RUN printf "${SSH_KEY_PASSPHRASE}" | ssh-add C:\Users\Jenkins\.ssh\id_rsa
fails to build - it doesn't recognize printf
. RUN printf "${SSH_KEY_PASSPHRASE}" | ssh-add C:\Users\Jenkins\.ssh\id_rsa
无法构建 - 它无法识别printf
。 I have tried to replace it with echo
but also fails.我试图用
echo
替换它,但也失败了。
If I remove this line from my Dockerfile I can build and run this container;如果我从我的 Dockerfile 中删除这一行,我就可以构建并运行这个容器; I then tried go into it with a powershell session and tried to run
ssh-add C:\Users\Jenkins\.ssh\id_rsa
manually but I get response Could not open a connection to your authentication agent.
然后我尝试使用 go 和 powershell session 并尝试运行
ssh-add C:\Users\Jenkins\.ssh\id_rsa
手动但我得到响应Could not open a connection to your authentication agent.
If I run Get-Service ssh-agent
it reports that ssh-agent is running.如果我运行
Get-Service ssh-agent
,它会报告 ssh-agent 正在运行。
So my questions are as follows:所以我的问题如下:
ssh-add
command not working?ssh-add
命令不起作用?ssh-add
command to work, how do I specify the passphrase in the Dockerfile?ssh-add
命令时,如何在 Dockerfile 中指定密码? Here is my Dockerfile:这是我的 Dockerfile:
# escape=`
FROM mcr.microsoft.com/windows/servercore
ARG SSH_KEY_PASSPHRASE
COPY .\files\Git-2.18.0-64-bit.exe C:\installers\git-installer.exe
COPY .\files\Git-2.18.0-64-bit.inf C:\installers\git-installer-script.inf
RUN powershell -Command `
# Install Git ; `
Start-Process -filepath C:\installers\git-installer.exe -passthru -wait -argumentlist "/LOADINF=C:\installers\git-installer-script.inf","/VERYSILENT","/NORESTART" ; `
Remove-Item C:\installers\ -Force -Recurse;
RUN powershell -Command `
net user /add Jenkins; `
net localgroup Administrators Jenkins /add;
USER Jenkins
RUN powershell -Command `
mkdir ~\.ssh;
COPY .\id_rsa C:\Users\Jenkins\.ssh\id_rsa
RUN powershell -Command `
# Make sure you're running as an Administrator `
Set-Service ssh-agent -StartupType Automatic; `
Start-Service ssh-agent; `
Get-Service ssh-agent;
# This doesn't work and I don't know how to do this
RUN printf "${SSH_KEY_PASSPHRASE}" | ssh-add C:\Users\Jenkins\.ssh\id_rsa
Edit 1编辑 1
I have now discovered that if run this container (without the ssh-add
command in the dockerfile) and then run a git clone using the ssh URL, it states that the authenticity of the bitbucket host can't be established, do you want to continue connecting?我现在发现,如果运行这个容器(没有dockerfile中的
ssh-add
命令),然后使用ssh URL运行一个git克隆,它表明无法建立bitbucket主机的真实性,你想吗继续连接? I enter "yes" and it then " permanently adds my bit bucket host to the list of known hosts " before asking for the passphrase for key 'c/Users/Jenkins/.ssh/id_rsa'.我输入“是”,然后在询问密钥“c/Users/Jenkins/.ssh/id_rsa”的密码之前,它“将我的位桶主机永久添加到已知主机列表”。
Once I enter the passphrase it successfully clones the repo.一旦我输入密码,它就会成功克隆回购协议。 This result surprises me and results in a new question:
这个结果让我感到惊讶,并产生了一个新问题:
Edit 2编辑 2
I have played around with my Dockerfile and found that the line RUN powershell -Command mkdir ~\.ssh
seems to be important in some way.我玩过我的 Dockerfile,发现行
RUN powershell -Command mkdir ~\.ssh
在某种程度上似乎很重要。 If I remove this line and run the container, I can see that my key is present in C:\Users\Jenkins\.ssh\
but if I run ssh-add.\Users\Jenkins\.ssh\id_rsa
it fails with Permissions for id_rsa are too open
.如果我删除此行并运行容器,我可以看到我的密钥存在于
C:\Users\Jenkins\.ssh\
但如果我运行ssh-add.\Users\Jenkins\.ssh\id_rsa
它会因Permissions for id_rsa are too open
而失败Permissions for id_rsa are too open
。 If I include the mkdir
line there is no obvious difference to me but the ssh-add
command seems to work and reports Identity added: .\Users\Jenkins\.ssh\id_rsa (<my company domain>+<my windows username@PC name>)
.如果我包含
mkdir
行,对我来说没有明显区别,但ssh-add
命令似乎有效并报告Identity added: .\Users\Jenkins\.ssh\id_rsa (<my company domain>+<my windows username@PC name>)
。
If I don't manually create the.ssh folder it still seems to be implicitly created during the COPY
command but the ssh-add
fails.如果我不手动创建 .ssh 文件夹,它似乎仍然是在
COPY
命令期间隐式创建的,但ssh-add
失败。 What is going on here?这里发生了什么?
Next I included the ssh-add
command into my Dockerfile and rebuilt it and could see that the key was added - it reports Identity added: .\Users\Jenkins\.ssh\id_rsa
.接下来,我将
ssh-add
命令包含到我的 Dockerfile 中并重建它,可以看到密钥已添加 - 它报告Identity added: .\Users\Jenkins\.ssh\id_rsa
。
At this stage I am not able to interact with Git as the path was not setup, so I modified my Dockerfile to setup the path by adding the following lines to the command where I install Git;在此阶段,由于未设置路径,我无法与 Git 进行交互,因此我修改了我的 Dockerfile 以设置路径,方法是将以下行添加到我安装 Git 的命令中;
${env:PATH} = 'C:\Git\bin;C:\Git\usr\bin;C:\Git\mingw64\bin;' + $env:PATH;
[Environment]::SetEnvironmentVariable('PATH', ${env:PATH}, [EnvironmentVariableTarget]::Machine);
Now when I build the image the ssh-add command fails with "Could not open a connection to your authentication agent."现在,当我构建映像时,ssh-add 命令失败并显示“无法打开与您的身份验证代理的连接”。 I ran
Get-Service ssh-agent
which reports that it is running.我运行了
Get-Service ssh-agent
报告它正在运行。
So somehow the inclusion of Git into the path has resulted in a difference regarding the ssh-add
command.因此,以某种方式将 Git 包含到路径中导致了
ssh-add
命令的差异。 What is happening here?这里发生了什么? How do I resolve this?
我该如何解决这个问题?
I also recreated the key without a passphrase so have removed the need to enter a passphrase during the docker build and I specified the version of windows.我还重新创建了没有密码的密钥,因此在 docker 构建期间不再需要输入密码,并且我指定了 windows 的版本。
Here is my updated Dockerfile:这是我更新的 Dockerfile:
# escape=`
FROM mcr.microsoft.com/windows/servercore:1903
# Install Git
COPY .\files\Git-2.18.0-64-bit.exe C:\installers\git-installer.exe
COPY .\files\Git-2.18.0-64-bit.inf C:\installers\git-installer-script.inf
RUN powershell -Command `
Start-Process -filepath C:\installers\git-installer.exe -passthru -wait -argumentlist "/LOADINF=C:\installers\git-installer-script.inf","/VERYSILENT","/NORESTART" ; `
Remove-Item C:\installers\ -Force -Recurse; `
# Set the path to include Git folders - not listed in my original post `
${env:PATH} = 'C:\Git\bin;C:\Git\usr\bin;C:\Git\mingw64\bin;' + $env:PATH; `
[Environment]::SetEnvironmentVariable('PATH', ${env:PATH}, [EnvironmentVariableTarget]::Machine);
# Create a Jenkins user with admin permissions
RUN powershell -Command `
net user /add Jenkins; `
net localgroup Administrators Jenkins /add;
USER Jenkins
# The presence or absence of this mkdir command affects ssh-add for some reason
RUN powershell -Command `
mkdir ~\.ssh;
# This key was created without a passphrase
COPY .\id_rsa C:\Users\Jenkins\.ssh\id_rsa
RUN powershell -Command `
# Make sure you're running as an Administrator `
Set-Service ssh-agent -StartupType Automatic; `
Start-Service ssh-agent; `
Get-Service ssh-agent; `
ssh-add .\Users\Jenkins\.ssh\id_rsa;
Edit 3编辑 3
Thanks to information I found here I it seems that the inability to run ssh-add
successfully was due to the SSH_AUTH_SOCK
environment variable not being set.感谢我在这里找到的信息,我似乎无法成功运行
ssh-add
是由于未设置SSH_AUTH_SOCK
环境变量。
Running ssh-agent
provides the data needed to set this environment variable and in Linux you could run eval $(ssh-agent)
but powershell in windows doesn't recognize the eval
command.运行
ssh-agent
提供了设置此环境变量所需的数据,在 Linux 中您可以运行eval $(ssh-agent)
但 windows 中的 powershell 无法识别eval
命令。 At this stage I tried commenting out the ssh-add
command from my last dockerfile and then inside the container I manually ran the ssh-agent
command and set the environment variable using $Env:SSH_AUTH_SOCK = "<value returned from ssh-agent>"
which succeeded and if I run Get-ChildItem Env:
I see this new environment variable listed.在这个阶段,我尝试注释掉我最后一个 dockerfile 中的
ssh-add
命令,然后在容器中我手动运行ssh-agent
命令并使用$Env:SSH_AUTH_SOCK = "<value returned from ssh-agent>"
设置环境变量成功了,如果我运行Get-ChildItem Env:
我看到列出了这个新的环境变量。
I then tried to run a git clone ssh://git@mybitbucketurl/myrepo.git
which reported that "the authenticity of host mybitbucketurl (xx.yy.zz.aa:port) can't be established. Are you sure you want to continue (yes/no)?"然后我尝试运行
git clone ssh://git@mybitbucketurl/myrepo.git
报告“无法确定主机 mybitbucketurl (xx.yy.zz.aa:port) 的真实性。你确定要继续(是/否)?”
I entered "yes" and it "Permanently added mybitbucketurl:port,[xx.yy.zz.aa]:port (RSA) to the list of known hosts" and then cloned my repository.我输入“是”,它“永久添加 mybitbucketurl:port,[xx.yy.zz.aa]:port (RSA) 到已知主机列表”,然后克隆了我的存储库。
I thought I had this cracked now and thought I just needed to work out how to do the eval
command equivalent in powershell. While I was searching for clues on how to do this I found this link with an answer that listed this command: ssh-agent ssh-add C:\Users\<username>\.ssh\id_rsa
.我以为我现在已经破解了这个并且认为我只需要弄清楚如何在 powershell 中执行等效的
eval
命令。当我在寻找如何执行此操作的线索时,我找到了这个链接,其中包含一个列出此命令的答案: ssh-agent ssh-add C:\Users\<username>\.ssh\id_rsa
。 I tried running this manually inside my container and it reported that the identity was added, however when I tried to run a git clone
it first add the URL to the list of known hosts and then failed with "fatal: could not read from remote repository".我尝试在我的容器中手动运行它,它报告已添加身份,但是当我尝试运行
git clone
时,它首先将 URL 添加到已知主机列表中,然后失败并显示“致命:无法从远程存储库读取”。 Running Get-ChildItem Env:
showed that the SSH_AUTH_SOCK
environment variable is not set so I guess that running it like this is an isolated session of sorts although I don't really know what is happening with this command.运行
Get-ChildItem Env:
表明未设置SSH_AUTH_SOCK
环境变量,所以我猜像这样运行它是一种孤立的 session,尽管我真的不知道这个命令发生了什么。
So from here it looks like I need to work out how to run the ssh-agent
command and use its result in powershell to setup the environment variable permanently.所以从这里看来我需要弄清楚如何运行
ssh-agent
命令并使用它在 powershell 中的结果来永久设置环境变量。 Once I have got that working I need to work out how to add my Git host URL to the list of known hosts.完成这项工作后,我需要弄清楚如何将我的 Git 主机 URL 添加到已知主机列表中。
Edit 4编辑 4
The crux of my issue seems to be the difference between the build-time and run-time of my docker image and specifically of what I am hoping to achieve with ssh-agent
and ssh-add
.我的问题的关键似乎是我的 docker 图像的构建时和运行时之间的差异,特别是我希望通过
ssh-agent
和ssh-add
实现的目标。 If I setup my image to include the ssh key and then run it, I am able to manually do the following (note that I've switched from powershell to bash):如果我将我的图像设置为包含 ssh 键然后运行它,我可以手动执行以下操作(注意我已经从 powershell 切换到 bash):
$ echo $SSH_AUTH_SOCK
$ eval $(ssh-agent)
Agent pid 2036
$ sh-add Users/Jenkins/.ssh/id_rsa
Identity added: Users/Jenkins/.ssh/id_rsa
$ echo $SSH_AUTH_SOCK
/tmp/ssh-qCM264wFqpqq/agent.1748
So from this I can see that at run-time in the container it does what I want it to.所以从这里我可以看到,在容器中运行时,它会做我想做的事。 However if I try and run these commands at build-time from the Dockerfile things do not work as I would hope.
但是,如果我尝试在构建时从 Dockerfile 运行这些命令,事情不会像我希望的那样工作。 After some thought I suspect that the
eval $(ssh-agent)
command probably runs but the SSH_AUTH_SOCK
environment variable is not retained within the image's layer and when the container is run ssh-agent will not be running, something probably needs to launch it.经过一番思考后,我怀疑
eval $(ssh-agent)
命令可能会运行,但SSH_AUTH_SOCK
环境变量未保留在图像层中,并且当容器运行时 ssh-agent 将不会运行,可能需要启动它。
What is the right way to do this:这样做的正确方法是什么:
SSH_AUTH_SOCK
environment variable but this seems to be different every time you run ssh-agent
- is this worth pursuing?SSH_AUTH_SOCK
环境变量,但是每次运行ssh-agent
时这似乎都不一样——这值得追求吗?Thank you so much for doing all of this work and documenting your progress.非常感谢您完成所有这些工作并记录您的进度。 I also tried many things on my side and I finally got something working.
我也在我这边尝试了很多东西,我终于得到了一些工作。
I added the file known_hosts that you can find inside the.ssh directory.我添加了文件 known_hosts,您可以在 .ssh 目录中找到该文件。 This is working for me:
这对我有用:
FROM mcr.microsoft.com/windows/servercore:ltsc2019
RUN powershell -Command \
mkdir C:\Users\ContainerAdministrator\.ssh
COPY ["./id_ed25519", "./Users/ContainerAdministrator/.ssh/"]
COPY ["./known_hosts", "./Users/ContainerAdministrator/.ssh/"]
RUN powershell -Command \
Set-Service ssh-agent -StartupType Automatic ; \
Start-Service ssh-agent ; \
ssh-add .\Users\ContainerAdministrator\.ssh\id_ed25519 ; \
git clone <your repo> ; \
Remove-Item C:\Users\ContainerAdministrator\.ssh -Force -Recurse
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.