DEV Community

Tomoya Amachi
Tomoya Amachi

Posted on

How to keep secure your Docker Image

Overviews

Containers are one of the best tools in recent years.
But it hasn't been established for DevSecOps for containers. Many organizations are unable to keep secure containers' ecosystem.

This article aims to what is the security best practices Docker Images.

Do you know Clair and Docker Bench for Security? but It's insufficient.

TL;DL

  • CIS Benchmarks published Docker security checkpoints
  • Check your images by Dockle and Trivy
  • Easy to check in CI before docker push

CIS Benchmarks

One of the best security best practice provided by The Center for Internet Security(CIS).
Their Container Images and Build File has 11 checkpoints.

  1. Create a user for the container
  2. Use trusted base images for containers
  3. Do not install unnecessary packages in the container
  4. Scan and rebuild the images to include security patches
  5. Enable Content trust for Docker
  6. Add HEALTHCHECK instruction to the container image
  7. Do not use update instructions alone in the Dockerfile
  8. Remove setuid and setgid permissions in the images
  9. Use COPY instead of ADD in Dockerfile
  10. Do not store secrets in Dockerfiles
  11. Install verified packages only

Clair only supports Scan and rebuild the images to include security patches.

What is Dockle

Dockle is Simple Security Auditing and helping build the Best Docker Image tool.

Dockle Docker Bench for Security Clair Trivy
1. Create a user for the container - -
2. Use trusted base images for containers - - -
3. Do not install unnecessary packages in the container - - -
4. Scan and rebuild the images to include security patches - -
5. Enable Content trust for Docker -
6. Add HEALTHCHECK instruction to the container image -
7. Do not use update instructions alone in the Dockerfile - -
8. Remove setuid and setgid permissions in the images - -
9. Use COPY instead of ADD in Dockerfile - -
10. Do not store secrets in Dockerfiles - -
11. Install verified packages only  - -

and Dockle can detect CVE-2019-5021 and some other securityholes.

Use Dockle

You can start easy!

Homebrew (Mac / Linux)



$ export DOCKER_CONTENT_TRUST=1
$ docker build -t test-image:v1 .
$ brew install goodwithtech/dockle/dockle
$ dockle test-image:v1


Enter fullscreen mode Exit fullscreen mode

Linux



$ export DOCKER_CONTENT_TRUST=1
$ docker build -t test-image:v1 .
$ VERSION=$(
 curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \
 grep '"tag_name":' | \
 sed -E 's/.*"v([^"]+)".*/\1/' \
) && curl -L -o dockle.tar.gz https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Linux-64bit.tar.gz
$ tar zxvf dockle.tar.gz
$ ./dockle test-image:v1


Enter fullscreen mode Exit fullscreen mode

Windows



$ export DOCKER_CONTENT_TRUST=1
$ docker build -t test-image:v1 .
$ VERSION=$(
 curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \
 grep '"tag_name":' | \
 sed -E 's/.*"v([^"]+)".*/\1/' \
) && curl -L -o dockle.zip https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Windows-64bit.zip
$ unzip dockle.zip && rm dockle.zip
$ ./dockle.exe test-image:v1


Enter fullscreen mode Exit fullscreen mode

You can check installation here.

Run Result is here.
passed
failed

Check in CI

You can use Trivy instead of Clair.
Trivy is easy to start and supports library packages and better accuracy than Clair.

CircleCI



jobs:
build:
docker:
- image: docker:18.09-git
steps:
- checkout
- setup_remote_docker
- restore_cache:
key: vulnerability-db
- run:
name: Build image
command: docker build -t ci-test:${CIRCLE_SHA1} .
- run:
name: Install dockle
command: |
apk add --update curl
VERSION=$(
curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | </span>
grep '"tag_name":' | </span>
sed -E 's/."v([^"]+)"./\1/'
)

        <span class="s">wget https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Linux-64bit.tar.gz</span>
        <span class="s">tar zxvf dockle_${VERSION}_Linux-64bit.tar.gz</span>
        <span class="s">mv dockle /usr/local/bin</span>
  <span class="pi">-</span> <span class="na">run</span><span class="pi">:</span>
      <span class="na">name</span><span class="pi">:</span> <span class="s">Scan the local image with dockle</span>
      <span class="na">command</span><span class="pi">:</span> <span class="s">dockle --exit-code 1 ci-test:${CIRCLE_SHA1}</span>          

  <span class="pi">-</span> <span class="na">run</span><span class="pi">:</span>
      <span class="na">name</span><span class="pi">:</span> <span class="s">Install trivy</span>
      <span class="na">command</span><span class="pi">:</span> <span class="pi">|</span>
        <span class="s">apk add --update curl</span>
        <span class="s">VERSION=$(</span>
            <span class="s">curl --silent "https://api.github.com/repos/knqyf263/trivy/releases/latest" | \</span>
            <span class="s">grep '"tag_name":' | \</span>
            <span class="s">sed -E 's/.*"v([^"]+)".*/\1/'</span>
        <span class="s">)</span>
        <span class="s">wget https://github.com/knqyf263/trivy/releases/download/v${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz</span>
        <span class="s">tar zxvf trivy_${VERSION}_Linux-64bit.tar.gz</span>
        <span class="s">mv trivy /usr/local/bin</span>
  <span class="pi">-</span> <span class="na">run</span><span class="pi">:</span>
      <span class="na">name</span><span class="pi">:</span> <span class="s">Scan the local image with trivy</span>
      <span class="na">command</span><span class="pi">:</span> <span class="s">trivy --exit-code 1 --quiet --auto-refresh trivy-ci-test:${CIRCLE_SHA1}</span>
  <span class="pi">-</span> <span class="na">save_cache</span><span class="pi">:</span>
      <span class="na">key</span><span class="pi">:</span> <span class="s">vulnerability-db</span>
      <span class="na">paths</span><span class="pi">:</span>
        <span class="pi">-</span> <span class="s">$HOME/.cache/trivy</span>
Enter fullscreen mode Exit fullscreen mode

workflows:
version: 2
release:
jobs:
- build

Enter fullscreen mode Exit fullscreen mode




TravisCI




services:
- docker

env:
global:
- COMMIT=${TRAVIS_COMMIT::8}

before_install:
- docker build -t ci-test:${COMMIT} .
- export DOCKLE_VERSION=$(curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | grep '"tag_name":' | sed -E 's/."v([^"]+)"./\1/')
- wget https://github.com/goodwithtech/dockle/releases/download/v${DOCKLE_VERSION}/dockle_${DOCKLE_VERSION}_Linux-64bit.tar.gz
- tar zxvf dockle_${DOCKLE_VERSION}Linux-64bit.tar.gz
- export TRIVY_VERSION=$(curl --silent "https://api.github.com/repos/knqyf263/trivy/releases/latest" | grep '"tag_name":' | sed -E 's/."v([^"]+)"./\1/')
- wget https://github.com/knqyf263/trivy/releases/download/v${TRIVY_VERSION}/trivy${TRIVY_VERSION}Linux-64bit.tar.gz
- tar zxvf trivy${TRIVY_VERSION}_Linux-64bit.tar.gz
script:
- ./dockle --exit-code 1 ci-test:${COMMIT}
- ./trivy --exit-code 1 --quiet --auto-refresh ci-test:${COMMIT}
cache:
directories:
- $HOME/.cache/trivy

Enter fullscreen mode Exit fullscreen mode




Conclusion

You can check your Docker Container Images to use Dockle and Trivy!
These are OSS tools.

If you feel like I missed something, got some details wrong, or just want to say hi, please feel free to leave a comment below or reach out to me on GitHub or Twitter.

Top comments (0)