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.
- Create a user for the container
- Use trusted base images for containers
- Do not install unnecessary packages in the container
- Scan and rebuild the images to include security patches
- Enable Content trust for Docker
- Add HEALTHCHECK instruction to the container image
- Do not use update instructions alone in the Dockerfile
- Remove setuid and setgid permissions in the images
- Use COPY instead of ADD in Dockerfile
- Do not store secrets in Dockerfiles
- 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
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
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
You can check installation here.
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>
workflows:
version: 2
release:
jobs:
- build
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
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)