General guidelines and recommendations
Run as a non-root user
Running containers as a non-root user substantially decreases the risk that container -> host privilege escalation could occur.
Recommends to run our components as a normal user preferably with UID, GID >10000
Use a static UID, GID
Eventually some point in time there would require volume sharing between containers, which will lead to manipulating file permissions. For eg: read here, this, and this.
It is best that you use a single static UID/GID for all of your containers that never change. We suggest 10000:10000 such that "$ chown 10000:10000 files" always works for containers following these best practices.
Use the binary as the ENTRYPOINT
Try to use the main binary as your ENTRYPOINT, and use CMD to pass only arguments. It allows people to ergonomically pass arguments to your binary without having to guess its name.
And also this way helps to write k8s YAMLs without having to know about its name and args.
Create ephemeral containers
The image defined by your Dockerfile
should generate containers that are as ephemeral as possible. By “ephemeral”, we mean that the container can be stopped and destroyed, then rebuilt and replaced with an absolute minimum set up and configuration. Also adding unwanted dependencies or packages will increase the image size. For eg: if we have an image with a binary as the ENTRYPOINT, try to avoid other dependencies that are not needed to run binary. Also, we should use a distro less base image or use "FROM scratch". The same we could achieve also by making use of multi-stage builds.
It is a Dockerfile best practice to include metadata labels when building your image.
Labels will help in image management, like including the application version, a link to the website, how to contact the maintainer, and more.
You can take a look at the predefined annotations from the OCI image spec .
Locally scan images during development
Image scanning is another way of detecting potential problems before running your containers.
It is a security best practice to apply the “shift left security” paradigm by directly scanning your images, as soon as they are built, in your CI pipelines before pushing them to the registry.
This also includes the developer's computer.
Sign images and verify signatures
It is one of the Dockerfile best practices to use docker content trust, Docker notary, Harbor notary, or similar tools to digitally sign your images and then verify them on runtime.
Tag mutability
In the container world, tags are a volatile reference to a concrete image version at a specific point in time.
Tags can change unexpectedly, and at any moment. See this “Attack of the mutant tags”.
Suggested to use format like this: docker pull kindest/node:v1.19.1@sha256:98cf5288864662e37115e362b23e4369c8c4a408f99cbc06e58ac30ddc721600
Misconfigurations
- Exposing insecure ports, like the ssh port 22 that shouldn’t be open on containers.
- Including private files accidentally via a bad “COPY” or “ADD” command.
- Including (leaking) secrets or credentials instead of injecting them via environment variables or mounts.
- Envs or mounts may be encrypted in K8s YAMLs, but decrypting them and exporting them as plain texts at runtime, exposes the secrets. Decryption shall be done within the code, and decrypted values shall not be exposed as ENVs or mounts.
Below lists some of the tools and utilities available that can be used in the lifecycle of a container. Also, lists below are some findings after trying out some of the available open-source tools.
docker-bench-security
(https://github.com/docker/docker-bench-security)
The Docker Bench for Security is a script that checks for dozens of common best-practices around deploying Docker containers in production. The tests are all automated and are based on the CIS Docker Benchmark v1.3.1.
Quick run:
$git clone https://github.com/docker/docker-bench-security.git
$cd docker-bench-security/
$./docker-bench-security.sh
This script will scan all the images available in the docker host.
Pros:
It's easy to set up and use.
Cons:
Hope it had a nice report and some structured output like in JSON format.
docker-scan
The docker CLI has an option,"scan" (which uses "snyk" tool as the provider) to scan for vulnerabilities in the image.
Linux installation steps here.
Pros:
Detailed reports
Easy to set up and use
Cons:
Require docker hub/snyk login
hadolint Dockerfile Linter
https://github.com/hadolint/hadolint
This is a Dockerfile linter, validate inline bash, written in Haskell.
quick run: $ docker run --rm -i ghcr.io/hadolint/hadolint < Dockerfile
Pros:
Easy to use.
Docker image available.
Scans for inline bash scripts.
Cons:
--
docker-lock
https://github.com/safe-waters/docker-lock
clair
Clair is an application for parsing image contents and reporting vulnerabilities affecting the contents. This is done via static analysis and not at runtime.
https://quay.github.io/clair/howto/getting_started.html
https://github.com/quay/clair
Pros:
Open-source, widely adopted, and active project
Well documented
Cons:
Not yet fully adopted CIS benchmark
Yet-to-try
dockle
https://github.com/goodwithtech/dockle
Container Image Linter for Security, Helping build the Best-Practice Docker Image.
quick run eg:
$ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock goodwithtech/dockle:v0.4.2 <your-image-url>
Pros:
Single binary, easy to set up and use
docker image available
Open source, active
Cons:
--
openscap by RedHat
https://www.open-scap.org/resources/documentation/security-compliance-of-rhel7-docker-containers/
https://www.open-scap.org/
notary
https://github.com/notaryproject/notary
Notary is a project that allows anyone to have trust over arbitrary collections of data.
syft
https://github.com/anchore/syft
SBOM generator from docker images.
threatmapper
https://github.com/deepfence/ThreatMapper
Identify vulnerabilities in running containers, images, hosts, and repositories
FAQs
Refs
https://techbeacon.com/enterprise-it/container-security-what-you-need-know-about-nist-standards
https://www.nist.gov/publications/application-container-security-guide
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
https://github.com/hexops/dockerfile
https://docs.docker.com/get-started/09_image_best/
https://sysdig.com/blog/dockerfile-best-practices/
https://github.com/docker/docker-bench-security
https://12factor.net/processes
https://geekflare.com/container-security-scanners/