FoxuTech

Docker Security: Docker image Security Best Practices

Docker image Security

Docker accelerates your development and deployment cycles, letting you push code out faster than ever before. But it also comes with an unexpected set of security implications that you should be aware of.

  1. Container image authenticity

There are plenty of Docker images and repositories on the Internet doing all kinds of awesome and useful stuff, but if you are pulling images without using any trust and authenticity mechanism, you are basically running arbitrary software on your systems.

Docker will let you pull and run anything you throw at it by default, so encapsulation won’t save you from this. Even if you only consume your own custom images, you want to make sure nobody inside the organization is able to tamper with an image. The solution usually boils down to the classical PKI-based chain of trust.

How to secure?

Example:

Deploying a full-blown trust server is beyond the scope of this article, but you can start signing your images right away.

Get a Docker Hub account if you don’t have one already.

Create a directory containing the following trivial Dockerfile:

# cat Dockerfile
FROM alpine:latest

Build the image:

# docker build -t <youruser>/alpineunsigned .

Log into your Docker Hub account and submit the image:

# docker login
[…]
# docker push <youruser>/alpineunsigned:latest

Enable Docker trust enforcement:

# export DOCKER_CONTENT_TRUST=1

Now try to retrieve the image you just uploaded:

# docker pull <youruser>/alpineunsigned

You should receive the following error message:

Using default tag: latest

Error: remote trust data does not exist for docker.io/<youruser>/alpineunsigned:

notary.docker.io does not have trust data for docker.io/<youruser>/alpineunsigned

Now that DOCKER_CONTENT_TRUST is enabled, you can build the container again and it will be signed by default.

# docker build --disable-content-trust=false -t <youruser>/alpinesigned:latest .

Now you should be able to push and pull the signed container without any security warning. The first time you push a trusted image, Docker will create a root key for you, you will also need a repository key for the image, both will prompt for a user defined password.

Your private keys are in the ~/.docker/trust directory, safeguard and backup them.

The DOCKER_CONTENT_TRUST is just an environment variable, and will die with your shell session but trust validation should be implemented across the entire process, from the images building, the images hosting in the registry through images execution in the nodes.

2.   Docker security vulnerabilities present in the static image

Containers are isolated black boxes, if they are doing their work as expected it’s easy to forget which software and version is specifically running inside. Maybe a container is performing like a charm from the operational point of view but it’s running version X.Y.Z of the web server which happens to suffer from a critical security flaw. This flaw has been fixed long ago upstream, but not in your local image. This kind of problem can go unnoticed for a long time if you don’t take the appropriate measures.

How to Secure?

Picturing the containers as immutable atomic units is really nice for architecture design, from the security perspective however, you need to regularly inspect their contents:

Example:

There are multiple Docker images registry services that offer image scanning, for this example we decided to use CoreOS Quay that uses the open source Docker security image scanner Clair. Quay it’s a commercial platform but some services are free to use. You can create a personal trial account following these instructions.

Read More:  Docker Security Tutorial

Once you have your account, go to Account Settings and set a new password (you need this to create repos).

Click on the + symbol on your top right and create a new public repo:

We go for an empty repository here, but you have several other options as you can see in the image above.

Now, from the command line, we log into the Quay registry and push a local image:

# docker login quay.io
# docker push quay.io/<your_quay_user>/<your_quay_image>:<tag>

Once the image is uploaded into the repo you can click on its ID and inspect the image security scan, ordered by severity, with the associated CVE report link and also upstream patched package versions.

Exit mobile version