“Anything that can go wrong, will—at the worst possible moment." Finagle’s Law of dynamic negatives
It’s a horror scenario, when a previously stable build of a Docker image decides to stop working.
Imagine this scenario: I created the following Dockerfile where I am requiring some rust capabilities in combination with Kubernetes:
FROM bitnami/kubect
USER root
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
And it all ran fine for a while, but suddenly, when I was trying to build the latest version, the system returns an error. I started looking terminal output for `docker build` (or ‘kubectl build` commands), I discovered the following error:
/bin/bash: line 1: curl: command not found
As it turns out, in an effort to reduce their image size, Bitnami has removed unnecessary libraries and executables from their base-image in version 1.23.12, which included curl, and your Dockerfile above is always pulling the latest image.
No matter what you do: fix versions
It is imperative that you ensure that the image has a version, and not just latest. This can be accomplished with the FROM command. For example, to fix the bitnami/kubectl image before the removal of unnecessary libraries and executables, specifying FROM bitnami/kubectl:1.22.15-debian-11-r7 would fix the image before the removal.
Static Analysis for Configuration Files
At CoGuard, we recognize the need to automate the checks of infrastructure as code and configuration files. The CoGuard configuration scanner catches fixing the version for containers in the default scan.
The above example generates the following error:
X Severity 3: dockerfile_specify_image_version (affected files: ./Dockerfile for service dockerfile)
Documentation: When using `FROM` directives in Docker files, it is important to specify the version directly and not just use latest (since this is a changing tag). Alternatively, define a
specific digest of the image you aim to use. Remediation: For any `FROM` command, ensure that the image has a version or a digest specified and that the version does not
contain `latest`. Source: https://docs.docker.com/engine/reference/builder/
Locking External Dependencies
Anywhere you are using an external dependency, you need to lock down the version. In this way, everything behaves as expected, and version changes are not something that hits you suddenly.
Running apt/pip/yum/rpm
inside the Dockerfile? Make sure to set the exact versions of the packages you install.
Running Terraform using external providers? You guessed it: put the version inside the provider.tf
.
NodeJS has done a good job encouraging people to keep a fixed package-lock.json
, in order to avoid exactly this issue. This is the only way the large dependency trees inside node are handled.
Add code scanning to your IaC and configurations
CoGuard provides static analysis and security testing for IaC and configuration files. The CoGuard ruleset includes policies for fixing external dependencies at the container level. It includes additional security best practices and misconfiguration identification for networks, devices/containers, operating systems and applications used in your IaC repositories, cloud configurations, or file system.
Get started for free today »