Testing Docker Image Secrets
I was looking into solutions into using a Dockerfile to build a Docker image while secrets inside the build process, like a private SSH key, which is typically used to pull code from private repositories.
This post mentions different solutions on how to use a secret key in a Docker image build:
- include the ssh key, then remove the file
- same as above, but use the
--squash
option when building
After reading these, I had the idea of using a ramdisk for the Docker image build process to see if that would prevent writing the secret to the Docker image during the build process.
Long story short: I wasn’t able to get a ramdisk setup in the Docker image build, so the build would not complete. :-/
tmpfs Docker Errors
The error I encountered when trying to mount the tmpfs sytem is:
I think there is an incompatibility with how the filesystem is already setup in Docker in a container or during a build. Docker may be using a combination of tmpfs and ext4 to abstract filesystems already, so another tmpfs might not be possible.
If you know of how to get tmpfs going in a Dockerfile, I would [love to hear from you](http://redgreenrepeat.com/contact]!!!
Skills Gained
Although my idea didn’t work out, One thing I did learn is how to work with Docker images at the file level and test out my hypothesis by searching through the Docker image.
Instead of just letting this information disappear as part of the experiment, I will write it up so others can use the techniques if anything ever changes in the future.
Requirements
If you would like to follow along and test out my work, these are the tools I used in this experiment:
- Docker Community Edition - version 17.12 (as of this writing)
- ag-the-silver-searcher
- ubuntu docker image
I have included a script that will generate all the files needed at this git repository.
Docker Image, where art tho?
Accessing a Docker image locally is pretty tricky because of the abstractions used. Docker images are not written to the filesystem of the host computer directly, but into a virtual file for all the images.
To extract the image from the virtual file, this is the command:
This is the easiest way to put a local Docker image into a file that is easily accessible on the filesystem. I want to do this so I can perform a search inside the file.
Searching Docker Image
To test whether a string is in the Docker image or not, I had to scan
inside the image. To do this, I use my favorite file scan tool:
ag
.
This allows ag-the-silveer-searcher to search inside a binary file for a string that matches.
Searching with grep
To search binary files with grep, the command is:
Testing Script
I wrote a script to generate all the Docker images, make them accessible, and search through them to verify whether a string matches or not.
Results
Going through known methods of creating an image with a secret and searching for it in cases where it was not written, written, written then removed, and then squashed:
docker image creation | text found in docker image? |
---|---|
image without secret written | no |
image with secret written | yes |
image with secret written then removed | yes |
image with secret written, removed, and squashed | yes |
From the above table, the secret is in the file whenever the
Dockerfile COPY
the file to the Docker image, even when using the
--squash
option.
The CMD rm <file>
option does not help, the file still remains in
the image.
This demonstrates that even when removing the secret directly or using
the --squash
, a quick scan finds the secret in the image file.
Conclusion
Do not store sensitive information in a Docker image file. The image will always have the information and is accessible.
Althought my initial idea of using an in-memory file system like tmpfs did not work out, I found a great process to validate my hypothesis, which I will use whenever I figure out another way to solve it.
This was a great way in learning how to work with Docker images, creating them with options, and testing my hypothesis on image contents.