Passing application configuration information as environmental variables was once considered best practice in 12 factor applications. However, this practice can expose information in logs, can be difficult to track how and when information is exposed, third party applications can access this information. Instead of environmental variables, Docker implements secrets to manage configuration and confidential information.
Secrets are a way to keep information such as passwords and credentials secure in a Docker CE or EE with swarm mode. Docker manages secrets and securely transmits it to only those nodes in the swarm that need access to it. Secrets are encrypted during transit and at rest in a Docker swarm. A secret is only accessible to those services which have been granted explicit access to it, and only while those service tasks are running.
The AtSea Shop is an example storefront application that can be deployed on different operating systems and can be customized to both your enterprise development and operational environments. The previous post showed how to use multi-stage builds to create small and efficient images. In this post, I’ll demonstrate how secrets are implemented in the application.
Creating Secrets
Secrets can be created using the command line or with a Compose file. The AtSea application uses nginx as a reverse proxy secured with HTTPS. To accomplish this, I created a self-signed x509 certificate.
mkdir certs
openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key -x509 -days 365 -out certs/domain.crt
I then created secrets using the domain key and certificate for nginx.
docker secret create revprox_cert certs/domain.crt
docker secret create revprox_key certs/domain.key
I also used secrets to hold the PostgreSQL database password and a token for the payment gateway by making files that contained the password and token. For example, the postgres_password file contains the password ‘gordonpass’. In the compose file, I added the secrets:
secrets:
postgres_password:
file: ./devsecrets/postgres_password
payment_token:
file: ./devsecrets/payment_token
I then set the database password secret,
database:
build:
context: ./database
image: atsea_db
environment:
POSTGRES_USER: gordonuser
POSTGRES_DB_PASSWORD_FILE: /run/secrets/postgres_password
POSTGRES_DB: atsea
ports:
– “5432:5432″
networks:
– back-tier
secrets:
– postgres_password
and I make the postgres_password secret available to the application server.
appserver:
build:
context: .
dockerfile: app/Dockerfile
image: atsea_app
ports:
– “8080:8080″
– “5005:5005″
networks:
– front-tier
– back-tier
secrets:
– postgres_password
As you can see, you can set secrets at the command line and programmatically in the a compose file.
Docker Enterprise Edition (formerly known as Docker Datacenter) fully incorporates secrets management through creation, update and removal of secrets. In addition Docker EE supports authorization, rotation and auditing of secrets. Creating a secret in Docker Enterprise Edition is accomplished by clicking on the Resources tab and then the Secrets menu item.
Create the secret by entering the name and the value and clicking Create. In this example, I’m using the secret for the PostgreSQL password in the AtSea application.
Using Secrets
In order to use the Secret containing the certificate for nginx, I configured the nginx.conf file to point at the secret in the nginx container.
server {
listen 443;
ssl on;
ssl_certificate /run/secrets/revprox_cert;
ssl_certificate_key /run/secrets/revprox_key;
server_name atseashop.com;
access_log /dev/stdout;
error_log /dev/stderr;
location / {
proxy_pass http://appserver:8080;
}
}
The AtSea application uses the postgres_password secret to connect to the database. This is done by reading the secret from the container and setting it to Spring-Boot’s DataSourceProperties class in the JpaConfiguration.java file.
// Set password to connect to postgres using Docker secrets.
try(BufferedReader br = new BufferedReader(new FileReader(“/run/secrets/postgres_password”)))
{
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
dataSourceProperties.setDataPassword(sb.toString());
} catch (IOException e) {
System.err.println(“Could not successfully load DB password file”);
}
return dataSourceProperties;
}
Learn more about Docker secrets:
Documentation
Command line
Docker Enterprise Editionr Secrets
Play with Docker Secrets hands-on lab
Docker Captain Alex Ellis’ Docker Secrets in Action
Why you shouldn’t use ENV variables for secret data
Securing AtSea with #Docker Secrets by @spara #dockersecurityClick To Tweet
The post Securing the AtSea App with Docker Secrets appeared first on Docker Blog.
Quelle: https://blog.docker.com/feed/
Published by