A Step-by-Step Guide for Protecting Sensitive Data in Docker
In this tutorial, you'll learn how to create and manage Docker secrets in order to increase your container and cloud security.
Join the DZone community and get the full member experience.
Join For FreeManaging passwords, access tokens, and private keys in an application can be tedious. Any small mistake accidentally exposes all the secret information. Even storing such things in Docker images can be easily accessible - if you run the image in the interactive container mode, all your application code is available in the containers. Docker provides secrets to protect all secret data.
This post explains the low-level techniques using in information storage as well as creating secured access to Docker Secrets. So, let's get started.
What Is Docker Secrets?
A secret is a blob of data that may consist of a password or any other sensitive information. Docker secrets centrally manage this data and securely transmit them to the containers that need to access them. A secret is encrypted over transport and only accessible to granted containers. Docker secrets only work in swarm services and are not available to the standalone container. Let's understand how Docker secrets work.
Architecture
When a Docker secret is created, the secret information is transmitted from Docker to its swarm manager where it is stored in a raft log, which is encrypted. That encrypted log is then circulated to the other manager to have higher accessibility over the swarm. Docker service can access the secret by mounting an encrypted location to it. The mounting location is /run/secrets/
in the container. The secret is decrypted by the worker which is connected to that swarm. Let's follow the example to understand it practically.
Example
Starts with a very basic example in which we are going to provide a secret in MySQL to a container and, after that, we'll cross-check it by logging in with the same credentials inside the container. As I said at the beginning of the article, Docker secrets only work in swarm mode, so, first, create a swarm. One way to create a swarm is by using VirtualBox on a single machine. You may create one on multiple machines as well.
Step 1: Create and Initialize Docker Swarm
docker-machine create --driver virtualbox worker1
docker-machine create --driver virtualbox worker2
Make sure Docker (docker-machine
), as well as VirtualBox, is installed on your system before running the above commands. Now assure that the machines are correctly installed and running using the command docker-machine ls
. The output should look like:
docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
worker1 - virtualbox Running tcp://192.168.99.102:2376 v17.09.1-ce
worker2 - virtualbox Running tcp://192.168.99.103:2376 v17.09.1-ce
Now the machines are configured and ready to start. Start the machines using the command docker-machine start
which changes its state to ready.
docker-machine start worker1
docker-machine start worker2
Now initialize the swarm mode and connect the running worker to swarm.
docker swarm init --advertise-addr <manager-node-ip_address>
Swarm initialized: current node (nsvmftqpb5p6amcqm5bpzwbs2) is now a manager.
After initializing swarm, a token id is provided which is used to connect the workers to swarm. Let's connect the workers.
docker-machine ssh worker1 "docker swarm join --token "
docker-machine ssh worker2 "docker swarm join --token "
After connecting the workers, our swarm is ready to create a secret.
Step 2: Create a Secret and Make it Available to Service
For creating a secret, you need to be on the Docker leader machine, and then runthe following commands:
echo "mySqlUser" | docker secret create my_sql_uname -
echo "mySqlPassword" | docker secret create my_sql_pass -
echo "mySqlRootPass" | docker secret create my_sql_root_pass -
Both the username and password need to be provided as the secret to the service. For the service, we are going to pull an image of MySQL from dockerHub and then run the same as a service by providing secrets to it. It's necessary to provide root_password to make the image of MySQL run.
docker pull mysql
docker service create --name mysqlService --secret my_sql_uname --secret my_sql_pass --secret my_sql_root_pass --network=host -e MYSQL_PASSWORD_FILE=/run/secrets/my_sql_pass -e MYSQL_USER_FILE=/run/secrets/my_sql_uname -e MYSQL_ROOT_PASSWORD=/run/secrets/my_sql_root_pass mysql
In the environment variable, the MySQL user and password provide the path to the secret file which is always created at /run/secret/
.
After doing this, the service runs in a container while mounting the location of the secret file. Now, let's cross verify all this by entering the container using its id.
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3df9f60a81fc mysql:latest "docker-entrypoint..." 16 seconds ago Up 10 seconds mysqlService.1.mh7jcqak7cq5n0h5oq6v1bye7
Now, in the bash shell of the running container, verify whether mySqlUser
was created.
docker exec -it bash
root@3df9f60a81fc:/# mysql -u mySqlUser -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.20 MySQL Community Server (GPL)
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
Above, we are able to log in successfully with the password that was provided to the secret.
Step 3: Removing Secrets and Swarm
To remove a secret, use the command docker secret rm
. To leave the swarm, use the command docker swarm leave
. And don't forget to remove the services before removing the secret and swarm.
docker service rm
docker secret rm my_sql_root_pass my_sql_pass my_sql_uname
docker-machine ssh worker1 "docker swarm leave"
docker-machine ssh worker2 "docker swarm leave"
Let's verify the status of the worker node using the command docker node ls
.
docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
zdreo1sgjcokykg08wl7t94w2 * knoldus-Lenovo-G50-80 Ready Active Leader
sfk0y0fq2se57jf82x1jovcin worker1 Down Active
qcn0byi0yfrou4i5icdhg56d7 worker2 Down Active
Now we need to remove the leader node forcefully and then remove the virtual machine too.
docker swarm leave -f
docker-machine rm worker1
docker-machine rm worker2
Hope the post was helpful!
References: https://docs.docker.com/
Published at DZone with permission of Jatin Demla, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments