Docker and password protection

I recently experimented with Docker to create some services for a game, and one thing that twitched was to enter passwords into the Docker file. I am a developer, so storing passwords in the source seems like a blow to the face. Should this be a problem? Are there any good conventions on how to handle passwords in Dockerfiles?

+82
security docker build
Mar 26 '14 at 4:42
source share
10 answers

This is definitely a problem. Docker files are usually checked in repositories and shared with other people. An alternative is to provide any credentials (usernames, passwords, tokens, something sensitive) as environment variables at runtime . This is possible with the -e argument (for individual vars in the CLI) or the --env-file argument (for multiple variables in a file) before docker run .

However, env vars are also not particularly safe. They are visible through docker inspect , and therefore are available to anyone who can run docker commands. (Of course, any user who has access to docker on the host also has root .

My preferred template is to use a wrapper script like ENTRYPOINT or CMD . The wrapper script can first import secrets from an external location into the container at runtime, and then execute the application by providing secrets. The exact mechanics of this depends on your runtime. In AWS, you can use a combination of IAM, Key Management Service, and S3 roles to store encrypted secrets in an S3 bucket. Something like HashiCorp Vault or credstash is another option.

AFAIK there is no optimal template for using sensitive data as part of the build process. Actually, I have a question https://stackoverflow.com/a/312618/2128 on this topic. You can use docker-squash to remove layers from the image. But for this purpose, Docker has no built-in functions.

You can find shykes configuration comments in containers .

+47
Mar 26 '14 at 5:59
source share

Our team avoids placing credentials in repositories, so this means that they are not allowed in the Dockerfile . Our best practice in applications is to use creds from environment variables.

We solve for this with docker-compose .

Inside docker-compose.yml you can specify a file containing environment variables for the container:

  env_file: - .env 

Be sure to add .env to .gitignore , then set the credentials in the .env file, for example:

 SOME_USERNAME=myUser SOME_PWD_VAR=myPwd 

Store the .env file locally or in a safe place where the rest of the command can capture it.

See: https://docs.docker.com/compose/environment-variables/#/the-env-file

+45
Jul 31 '15 at 22:41
source share

Now Docker (version 1.13 or 17.06 and higher) supports the management of sensitive information. Here is an overview and more detailed documentation.

A similar feature exists in kubernetes and DCOS.

+12
Jul 13 '17 at 17:40
source share

You should never add credentials to a container unless you transfer credits live to those who can upload the image. In particular, execution and ADD creds and later RUN rm creds are not safe because the creds file remains in the final image at the intermediate level of the file system. Easy for anyone who has access to an image to extract it.

The typical solution I saw when you need creds for validation dependencies is to use one container to build another. Ie, as a rule, you have some build environment in the base container, and you need to call this to create your application container. Thus, a simple solution is to add your application source and then the RUN build command. This is not safe if you need loans in RUN . Instead, you put your source in a local directory, run (as in docker run ) a container to complete the build step with the local source directory mounted as a volume, and credits are either inserted or mounted as another volume. Once the build step is complete, you will create your last container with a simple ADD in the local source directory, which now contains embedded artifacts.

I hope Docker adds some features to simplify all this!

Update: it looks like the method going forward will have nested assemblies. In short, the docker file will describe the first container that is used to create the runtime, and then the second sub-assembly of the container, which can assemble all parts into the final container. Thus, the build time is not in the second container. This is a Java application where you need the JDK to create the application, but only the JRE to run it. A number of suggestions are discussed, it is best to start with https://github.com/docker/docker/issues/7115 and follow some links for alternative suggestions.

+8
01 Oct
source share

With Docker v1.9, you can use the ARG command to get the arguments passed by the command line into the build operation image. Just use the flag - build-arg . This way you can avoid storing explicit password (or other reasonable information) in the Docker file and transfer them on the fly.

source: https://docs.docker.com/engine/reference/commandline/build/ http://docs.docker.com/engine/reference/builder/#arg

Example:

Dockerfile

 FROM busybox ARG user RUN echo "user is $user" 

image assembly team

 docker build --build-arg user=capuccino -t test_arguments -f path/to/dockerfile . 

print during assembly

 $ docker build --build-arg user=capuccino -t test_arguments -f ./test_args.Dockerfile . Sending build context to Docker daemon 2.048 kB Step 1 : FROM busybox ---> c51f86c28340 Step 2 : ARG user ---> Running in 43a4aa0e421d ---> f0359070fc8f Removing intermediate container 43a4aa0e421d Step 3 : RUN echo "user is $user" ---> Running in 4360fb10d46a **user is capuccino** ---> 1408147c1cb9 Removing intermediate container 4360fb10d46a Successfully built 1408147c1cb9 

Hope this helps! Bye

+4
Nov 21 '15 at 18:09
source share

As an alternative to using environment variables, which can be messy if you have a lot of them, use volumes to create a directory on the host accessible in the container.

If you put all your credentials as files in this folder, then the container can read the files and use them as it sees fit.

For example:

 $ echo "secret" > /root/configs/password.txt $ docker run -v /root/configs:/cfg ... In the Docker container: # echo Password is `cat /cfg/password.txt` Password is secret 

Many programs can read their credentials from a separate file, so this way you can simply point the program to one of the files.

+1
Aug 19 '16 at 4:57
source share

My approach seems to work, but probably naively. Tell me why this is wrong.

ARGs installed during docker build are displayed by the history subcommand, so they are not needed there. However, when the container starts, the environment variables specified in the start command are available to the container, but are not part of the image.

So, in the Dockerfile, configure a setting that does not include sensitive data. Install CMD something like /root/finish.sh . In the run command, use environment variables to send sensitive data to the container. finish.sh uses variables essentially to complete build tasks.

To simplify the management of sensitive data, put it in a file downloaded by docker using the --env-file switch. Of course, keep the file secret. .gitignore etc.

For me, finish.sh runs the Python program. It checks to see if it is running earlier, then completes the configuration (for example, copies the database name to Django settings.py ).

+1
Jul 28 '17 at 20:37
source share

As long as I completely agree, there is no easy solution. There is still one point of failure. Or a docker file, etc., and so on. Apcera has a plan similar to sidekick - double authentication. In other words, two containers cannot talk unless the Apcera configuration rule exists. In its demo, uid / pwd was clear and could not be reused until the administrator established a connection. However, to work, this probably meant fixing the Docker, or at least the network plugin (if there is such a thing).

0
Jul 21 '15 at 15:01
source share

There is a new docker [1] command for managing secrets, but this only works for swarm clusters.

 docker service create --name my-iis --publish target=8000,port=8000 --secret src=homepage,target="\inetpub\wwwroot\index.html" microsoft/iis:nanoserver 

[1] https://docs.docker.com/engine/swarm/secrets/

0
Dec 02 '17 at 15:56 on
source share

runtime only

docker-compose also provides a solution without a swarm (since v1.11: Secrets using binding bindings ).

Secrets are mounted as files below /run/secrets/ using docker-compose. This solves the problem at runtime (container start), but not at build time (image creation), because /run/secrets/ not mounted at build time. In addition, this behavior depends on the launch of the container with the docker layout.




Example:

Dockerfile

 FROM alpine RUN cat /run/secrets/password CMD sleep inifinity 

Docker-compose.yml

 version: '3.1' services: app: build: . secrets: - password secrets: password: file: password.txt 

To execute, run:

 docker-compose up -d 

Further reading:

0
Jan 26 '18 at 11:32
source share



All Articles