Using SSH keys inside docker container

2019-01-03 07:35发布

I have an app that executes various fun stuff with Git (like running git clone & git push) and I'm trying to docker-ize it.

I'm running into an issue though where I need to be able to add an SSH key to the container for the container 'user' to use.

I tried copying it into /root/.ssh/, changing $HOME, creating a git ssh wrapper, and still no luck.

Here is the Dockerfile for reference:

#DOCKER-VERSION 0.3.4                                                           

from  ubuntu:12.04                                                              

RUN  apt-get update                                                             
RUN  apt-get install python-software-properties python g++ make git-core openssh-server -y
RUN  add-apt-repository ppa:chris-lea/node.js                                   
RUN  echo "deb http://archive.ubuntu.com/ubuntu precise universe" >> /etc/apt/sources.list
RUN  apt-get update                                                             
RUN  apt-get install nodejs -y                                                  

ADD . /src                                                                       
ADD ../../home/ubuntu/.ssh/id_rsa /root/.ssh/id_rsa                             
RUN   cd /src; npm install                                                      

EXPOSE  808:808                                                                 

CMD   [ "node", "/src/app.js"]

app.js runs the git commands like git pull

22条回答
Explosion°爆炸
2楼-- · 2019-01-03 07:54

If you don't care about the security of your SSH keys, there are many good answers here. If you do, the best answer I found was from a link in a comment above to this GitHub comment by diegocsandrim. So that others are more likely to see it, and just in case that repo ever goes away, here is an edited version of that answer:

Most solutions here end up leaving the private key in the image. This is bad, as anyone with access to the image has access to your private key. Since we don't know enough about the behavior of squash, this may still be the case even if you delete the key and squash that layer.

We generate a pre-sign URL to access the key with aws s3 cli, and limit the access for about 5 minutes, we save this pre-sign URL into a file in repo directory, then in dockerfile we add it to the image.

In dockerfile we have a RUN command that do all these steps: use the pre-sing URL to get the ssh key, run npm install, and remove the ssh key.

By doing this in one single command the ssh key would not be stored in any layer, but the pre-sign URL will be stored, and this is not a problem because the URL will not be valid after 5 minutes.

The build script looks like:

# build.sh
aws s3 presign s3://my_bucket/my_key --expires-in 300 > ./pre_sign_url
docker build -t my-service .

Dockerfile looks like this:

FROM node

COPY . .

RUN eval "$(ssh-agent -s)" && \
    wget -i ./pre_sign_url -q -O - > ./my_key && \
    chmod 700 ./my_key && \
    ssh-add ./my_key && \
    ssh -o StrictHostKeyChecking=no git@github.com || true && \
    npm install --production && \
    rm ./my_key && \
    rm -rf ~/.ssh/*

ENTRYPOINT ["npm", "run"]

CMD ["start"]
查看更多
小情绪 Triste *
3楼-- · 2019-01-03 07:54

In a running docker container, you can issue ssh-keygen with the docker -i (interactive) option. This will forward the container prompts to create the key inside the docker container.

查看更多
闹够了就滚
4楼-- · 2019-01-03 07:55

This issue is really an annoying one. Since you can't add/copy any file outside the dockerfile context, which means it's impossible to just link ~/.ssh/id_rsa into image's /root/.ssh/id_rsa, and when you definitely need a key to do some sshed thing like git clone from a private repo link..., during the building of your docker image.

Anyways, I found a solution to workaround, not so persuading but did work for me.

  1. in your dockerfile:

    • add this file as /root/.ssh/id_rsa
    • do what you want, such as git clone, composer...
    • rm /root/.ssh/id_rsa at the end
  2. a script to do in one shoot:

    • cp your key to the folder holding dockerfile
    • docker build
    • rm the copied key
  3. anytime you have to run a container from this image with some ssh requirements, just add -v for the run command, like:

    docker run -v ~/.ssh/id_rsa:/root/.ssh/id_rsa --name container image command

This solution results in no private key in both you project source and the built docker image, so no security issue to worry about anymore.

查看更多
Explosion°爆炸
5楼-- · 2019-01-03 07:56

Docker containers should be seen as 'services' of their own. To separate concerns you should separate functionalities:

1) Data should be in a data container: use a linked volume to clone the repo into. That data container can then be linked to the service needing it.

2) Use a container to run the git cloning task, (i.e it's only job is cloning) linking the data container to it when you run it.

3) Same for the ssh-key: put it is a volume (as suggested above) and link it to the git clone service when you need it

That way, both the cloning task and the key are ephemeral and only active when needed.

Now if your app itself is a git interface, you might want to consider github or bitbucket REST APIs directly to do your work: that's what they were designed for.

查看更多
6楼-- · 2019-01-03 07:59

Forward the ssh authentication socket to the container:

docker run --rm -ti \
        -v $SSH_AUTH_SOCK:/tmp/ssh_auth.sock \
        -e SSH_AUTH_SOCK=/tmp/ssh_auth.sock \
        -w /src \
        my_image

Your script will be able to perform a git clone.

Extra: If you want cloned files to belong to a specific user you need to use chown since using other user than root inside the container will make git fail.

You can do this publishing to the container's environment some additional variables:

docker run ...
        -e OWNER_USER=$(id -u) \
        -e OWNER_GROUP=$(id -g) \
        ...

After you clone you must execute chown $OWNER_USER:$OWNER_GROUP -R <source_folder> to set the proper ownership before you leave the container so the files are accessible by a non-root user outside the container.

查看更多
仙女界的扛把子
7楼-- · 2019-01-03 07:59

You can also link your .ssh directory between the host and the container, I don't know if this method has any security implications but it may be the easiest method. Something like this should work:

$ sudo docker run -it -v /root/.ssh:/root/.ssh someimage bash

Remember that docker runs with sudo (unless you don't), if this is the case you'll be using the root ssh keys.

查看更多
登录 后发表回答