Rus*_*lan 23 ssh docker docker-compose docker-machine
我在Mac OS X上使用Docker与Docker Machine(使用默认的boot2docker机器),我使用docker-compose来设置我的开发环境.
假设其中一个容器名为" stack
".现在我想做的是打电话:
docker-composer run stack ssh user@stackoverflow.com
Run Code Online (Sandbox Code Playgroud)
我的公钥(已添加到stackoverflow.com
用于验证我的公钥)位于主机上.我希望这个密钥可以在Docker Machine容器中使用,这样我就能够stackoverflow
在容器内使用该密钥进行身份验证.最好不要将我的密钥物理复制到Docker Machine.
有没有办法做到这一点?此外,如果我的密钥受密码保护,有没有办法解锁它一次,所以每次注入后我不必手动输入密码?
小智 37
您可以将它添加到docker-compose.yml(假设您的用户在容器内是root):
volumes:
- ~/.ssh:/root/.ssh
Run Code Online (Sandbox Code Playgroud)
Ant*_*gun 22
Docker有一个名为secrets的功能,在这里可以提供帮助.要使用它,可以将以下代码添加到docker-compose.yml
:
---
version: '3.1' # Note the minimum file version for this feature to work
services:
stack:
...
secrets:
- host_ssh_key
secrets:
host_ssh_key:
file: ~/.ssh/id_rsa
Run Code Online (Sandbox Code Playgroud)
然后可以Dockerfile
像这样访问新的秘密文件:
RUN mkdir ~/.ssh && ln -s /run/secrets/host_ssh_key ~/.ssh/id_rsa
Run Code Online (Sandbox Code Playgroud)
秘密文件不会被复制到容器中:
当您授予新创建或正在运行的服务访问权限时,解密的机密将装入内存文件系统的容器中
有关详细信息,请参阅:
如果您使用的是OS X和加密密钥,则将是PITA。这是我解决此问题的步骤。
有人可能会认为这没有问题。只需挂载ssh文件夹:
...
volumes:
- ~/.ssh:/root/.ssh:ro
...
Run Code Online (Sandbox Code Playgroud)
这应该可行,对吗?
接下来,我们会注意到我们使用了错误的用户ID。很好,我们将编写一个脚本来复制和更改ssh密钥的所有者。我们还将在配置中设置ssh用户,以便ssh服务器知道谁在连接。
...
volumes:
- ~/.ssh:/root/.ssh-keys:ro
command: sh -c ‘./.ssh-keys.sh && ...’
environment:
SSH_USER: $USER
...
# ssh-keys.sh
mkdir -p ~/.ssh
cp -r /root/.ssh-keys/* ~/.ssh/
chown -R $(id -u):$(id -g) ~/.ssh
cat <<EOF >> ~/.ssh/config
User $SSH_USER
EOF
Run Code Online (Sandbox Code Playgroud)
在我们公司中,我们使用密码保护SSH密钥。在docker中这是行不通的,因为每次启动容器时都无法输入密码。我们可以删除密码短语(请参见下面的示例),但是存在安全隐患。
openssl rsa -in id_rsa -out id_rsa2
# enter passphrase
# replace passphrase-encrypted key with plaintext key:
mv id_rsa2 id_rsa
Run Code Online (Sandbox Code Playgroud)
您可能已经注意到,在本地不需要每次ssh访问都需要输入密码。这是为什么?这就是SSH代理的用途。SSH代理基本上是一个服务器,它侦听称为ssh auth sock的特殊文件unix套接字。您可以在系统上看到其位置:
echo $SSH_AUTH_SOCK
# /run/user/1000/keyring-AvTfL3/ssh
Run Code Online (Sandbox Code Playgroud)
SSH客户端通过此文件与SSH代理进行通信,因此您只需输入一次密码即可。解密后,SSH代理会将其存储在内存中,并根据请求发送到SSH客户端。我们可以在Docker中使用它吗?当然,只需挂载该特殊文件并指定相应的环境变量即可:
environment:
SSH_AUTH_SOCK: $SSH_AUTH_SOCK
...
volumes:
- $SSH_AUTH_SOCK:$SSH_AUTH_SOCK
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我们甚至不需要复制密钥。为了确认密钥是否可用,我们可以使用ssh-add实用程序:
if [ -z "$SSH_AUTH_SOCK" ]; then
echo "No ssh agent detected"
else
echo $SSH_AUTH_SOCK
ssh-add -l
fi
Run Code Online (Sandbox Code Playgroud)
不幸的是,对于OS X用户,Docker for Mac有许多缺点,其中之一就是它无法在Mac和Linux之间共享Unix套接字。D4M Github中存在一个未解决的问题。截至2019年2月,它仍然开放。
那么,这是死胡同吗?不,有一个解决方法。
幸运的是,这个问题并不新鲜。在Docker出现很久之前,就有一种在远程ssh会话中使用本地ssh密钥的方法。这称为ssh代理转发。这个想法很简单:您可以通过ssh连接到远程服务器,并且可以在那里使用所有相同的远程服务器,从而共享密钥。
使用Mac的Docker,我们可以使用一个聪明的技巧:使用TCP ssh连接将ssh代理共享到docker虚拟机,然后将该文件从虚拟机挂载到需要SSH连接的另一个容器中。这是用于说明解决方案的图片:
首先,我们通过TCP端口在Linux VM中的容器内创建到ssh服务器的ssh会话。我们在这里使用真正的ssh auth袜子。
接下来,ssh服务器将我们的ssh密钥转发到该容器上的ssh代理。SSH代理具有Unix套接字,该套接字使用安装到Linux VM的位置。即Unix套接字可在Linux中使用。Mac中无法正常工作的Unix套接字文件无效。
之后,我们使用SSH客户端创建有用的容器。我们共享本地SSH会话使用的Unix套接字文件。
有很多脚本可以简化该过程:https : //github.com/avsm/docker-ssh-agent-forward
在Docker中使用SSH可能更容易。但这是可以完成的。并且将来可能会得到改进。至少Docker开发人员知道此问题。甚至为带有构建时间秘密的Dockerfile解决了该问题。而且有一个建议,如何支持Unix域套接字。
您可以转发SSH代理:
something:
container_name: something
volumes:
- $SSH_AUTH_SOCK:/ssh-agent # Forward local machine SSH key to docker
environment:
SSH_AUTH_SOCK: /ssh-agent
Run Code Online (Sandbox Code Playgroud)
您可以使用多阶段构建来构建容器这是您可以采取的方法:-
Stage 1 building an image with ssh
FROM ubuntu as sshImage
LABEL stage=sshImage
ARG SSH_PRIVATE_KEY
WORKDIR /root/temp
RUN apt-get update && \
apt-get install -y git npm
RUN mkdir /root/.ssh/ &&\
echo "${SSH_PRIVATE_KEY}" > /root/.ssh/id_rsa &&\
chmod 600 /root/.ssh/id_rsa &&\
touch /root/.ssh/known_hosts &&\
ssh-keyscan github.com >> /root/.ssh/known_hosts
COPY package*.json ./
RUN npm install
RUN cp -R node_modules prod_node_modules
Run Code Online (Sandbox Code Playgroud)
第 2 阶段:构建容器
FROM node:10-alpine
RUN mkdir -p /usr/app
WORKDIR /usr/app
COPY ./ ./
COPY --from=sshImage /root/temp/prod_node_modules ./node_modules
EXPOSE 3006
CMD ["npm", "run", "dev"]
Run Code Online (Sandbox Code Playgroud)
在您的 compose 文件中添加 env 属性:
environment:
- SSH_PRIVATE_KEY=${SSH_PRIVATE_KEY}
Run Code Online (Sandbox Code Playgroud)
然后从构建脚本传递参数,如下所示:
docker-compose build --build-arg SSH_PRIVATE_KEY="$(cat ~/.ssh/id_rsa)"
Run Code Online (Sandbox Code Playgroud)
并移除中间容器以确保安全。这会帮助你欢呼。
归档时间: |
|
查看次数: |
24624 次 |
最近记录: |