Reputation: 10198
My Tomcat Container needs data that has to be well protected, i.e. passwords for database access and certificates and keys for Single Sign On to other systems.
I´ve seen some suggestions to use -e
or -env-file
to pass secret data to a container but this can be discovered with docker inspect (-env-file
also shows all the properties of the file in docker inspect).
Another approach is to link a data container with the secrets to the service container but I don´t like the concept of having this data container in my registry (accessible for a broader range of people). I know I can set up a private registry, but I would need different registries for test and production and still everyone with access to the production registry could access the secret data.
I´m thinking about setting up my servers with a directory that contains the secret data and to mount the secret data into my containers. This would work nicely with test- and production servers having different secrets. But it creates a dependency of the containers to my specific servers.
So my question is: How do you handle secret data, what´s the best solution to that problem?
Upvotes: 7
Views: 4602
Reputation: 1323343
Update January 2017
Docker 1.13 now has the command docker secret
with docker swarm.
See also "Why is ARG
in a DOCKERFILE
not recommended for passing secrets?".
Original answer (Sept 2015)
The notion of docker vault
, alluded to by Adrian Mouat in his previous answer, was actively discussed in issue 1030 (the discussion continues on issues 13490).
It was for now rejected as being out of scope for docker, but also included:
We've come up with a simple solution to this problem: A bash script that once executed through a single
RUN
command, downloads private keys from a local HTTP server, executes a given command and deletes the keys afterwards.Since we do all of this in a single
RUN
, nothing gets cached in the image. Here is how it looks in the Dockerfile:RUN ONVAULT npm install --unsafe-perm
Our first implementation around this concept is available at
dockito/vault
.To develop images locally we use a custom development box that runs the Dockito Vault as a service.
The only drawback is requiring the HTTP server running, so no Docker hub builds.
The question asks about secrets for runtime, not for build.
True. As of Docker 1.13, which supports Docker Swarm, Docker provides a feature called Docker Secrets specifically intended for safely handling secret data at runtime, as I mentioned above.
Secrets are stored securely in the Docker Swarm manager's RAFT log which is encrypted.
echo "your_database_password" | docker secret create db_password -
When deploying containers, you can attach these secrets to them. The secrets are not exposed as environment variables but are available as files in a temporary filesystem within the container.
docker service create --name my_service --secret db_password my_image
Applications inside the container can access the secrets at a predefined file location, such as /run/secrets/db_password
. That location only holds the secrets while the container is running and does not persist on disk.
┌─────────────────┐ ┌──────────────────┐
│ Tomcat │ │ Docker Swarm │
│ Container ├──────────► Secret Storage │
│ (Access secrets│ Mount │ (Encrypted) │
│ at runtime) │ └──────────────────┘
└─────────────────┘
That approach makes sure secrets are never exposed in Docker inspect commands, logs, or stored insecurely on disk. It addresses the primary concern of securely managing runtime secrets without linking containers to specific servers or dependencies, meeting the requirement for a more secure and flexible deployment across different environments.
By utilizing Docker Secrets in a Docker Swarm environment, you can manage runtime secrets more securely and flexibly, suitable for different operational stages (development, testing, production) without exposing sensitive information in less secure ways.
That would directly addresses the concern about runtime secret management in containerized applications like Tomcat.
Upvotes: 5
Reputation: 646
Mount the encrypted keys into container, then pass the password via pipe. The difficulty comes with the detach
mode, which will hang while reading the pipe within the container. Here is a trick to work around:
cid=$(docker run -d -i alpine sh -c 'read A; echo "[$A]"; exec some-server')
docker exec -i $cid sh -c 'cat > /proc/1/fd/0' <<< _a_secret_
First, create the docker daemon with -i
option, the command read A
will hang waiting for the input from /proc/1/fd/0
;
Then run the second docker command, reading the secret from stdin and redirect to the last hanging process.
Upvotes: 0