You develop for a Kubernetes cluster. Or maybe you deploy single container microservices to your cloud-hosted platform. Either way, your work depends on having images that are as free from vulnerabilities as possible. No matter if you develop your own images from the ground up, or if you use pre-rolled images, you need to know where they stand with regards to security.
One way to take care of that is using the Anchore Engine, an open source software for inspection, analysis, and certification of container images. The Anchore CLI provides a developer interface for these capabilities. This piece of command-line magic can pull down images from the official Docker registry (or other registries), store them in a local library, and then run vulnerability scans, policy evaluations, and even list system packages found in the image. In other words, it can ensure the images you depend on are good to go.
But Anchore CLI isn’t exactly the most writ large tool in the developer toolkit. Not only is it yet another container adjacent tool with less-than-ideal installation documentation, but its usage also isn’t exactly obvious. I’m going to clear that up for you, such that you can get Anchore CLI in play with your daily container development workflow.
To make this work, you’ll need a running instance of Linux that supports Docker and a user with
sudo privileges. I’ll be demonstrating with Ubuntu Server 20.04, but the process is similar on most Linux distributions (so long as you modify the installation commands to match your distribution’s package manager).
With that said, let’s get Anchore CLI up and running.
Installing Anchore CLI
The first thing we must do is install Anchore CLI. Before we do that, we’ll make sure we have Docker installed. For that, log into your Ubuntu server and install Docker with the command:
sudo apt-get install docker.io -y
Once installed, add your user to the docker group with the command:
sudo usermod -aG docker $USER
Log out and log back in, so the changes take effect.
Once Docker is installed, we need to install PIP, which is done with the command:
sudo apt-get install python3-pip -y
With the Python package manager added to the system, you can then install Anchore CLI with the command:
pip install anchorecli
When the above command completes, you’ll find the anchore-cli command isn’t available to run. Why? Because Pip installs the executable in ~/.local/bin, which is not a part of your user path. To fix that you need to add the directory to your path with the command:
At this point, if you issue the command anchore-cli, you’ll find it’s unable to connect to the Anchore Engine. That’s because we have to add that to the system. Fortunately, the easiest path to get this subsystem up and running is to deploy it as a container. For that, we’re going to need to add Docker Compose into the mix. This can be done with the following two commands:
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
Next, download the Anchore Engine YAML file with the command:
curl https://engine.anchore.io/docs/quickstart/docker-compose.yaml > docker-compose.yaml
With the YAML stored, deploy the engine with the command:
docker-compose up -d
After Anchore Engine has deployed, you need to give it a few minutes to come up. While it’s working, let’s export some variables (so you don’t have to always add them into the Anchore CLI commands). We’re going to set the URL, user, and password variables. The default credentials for Anchore Engine are admin/foobar.
If you want, you can change the admin password (before you issue the docker-compose up -d command). To do that, open the docker-compose.yaml file you downloaded a moment ago and look for the line:
Change foobar to whatever password you like. Save and close the file. If you’ve already deployed the Anchore Engine contain, before changing the password, issue the command:
When the container shuts down, change the password and then re-deploy the container.
To set the environment variables, issue the following three commands:
Where SERVER is the IP address of your server and PASSWORD is what you set in the YAML file (NOTE: If you didn’t change the password, make sure to use foobar).
Using Anchore CLI
You’re now ready to make use of Anchore CLI. First, let’s download an image, and then we’ll scan it. We’ll download the official openjdk:8-jre-alpine image with the command:
anchore-cli --u admin --p foobar image add docker.io/library/openjdk:8-jre-alpine
After the image is downloaded, Anchore CLI will begin the process of analyzing the image. This will take some time. If you issue the command:
anchore-cli --u admin --p foobar image list
You will see that the openjdk-8-jre-alpine image is still in the process of being analyzed (Figure 1).
If you receive the error “Unauthorized,” it’s because Anchore CLI isn’t recognizing the variables you set. I’ve found this to be far too common than not. To get around that, you must issue the command, including the authorization credentials like so:
anchore-cli --u admin --p foobar image list
Once the image has moved from analyzing to analyzed (you’ll need to keep issuing the image list command to find out), you can then perform a vulnerability scan with the command:
anchore-cli --u admin --p foobar image vuln docker.io/library/openjdk:8-jre-alpine all
The above command will list out all of the known vulnerabilities (Figure 2) associated with the image (if there are any).
If you find an image contains too many unacceptable vulnerabilities, your best choice would be to avoid that image and find another to use for development purposes.
To run a policy check, the command would be:
anchore-cli --u admin --p foobar evaluate check docker.io/library/debian:latest --detail
From that command you should see output like:
Image Digest: sha256:3e24baa60967d085b95a45129f82af4eb9d1e33aff9559173542ebb15c5d9cb5
Full Tag: docker.io/library/debian:latest
Image ID: 4a7a1f4017349067a21bd2de060dcf8b41e49fabf61b0dc3cf86a87e1f6dba9d
Last Eval: 2021-05-28T14:14:21Z
Policy ID: 2c53a13c-1765-11e8-82ef-23527761d060
Final Action: warn
Final Action Reason: policy_evaluation
Gate Trigger Detail Status
dockerfile instruction Dockerfile directive 'HEALTHCHECK' not found, matching condition 'not_exists' check warn
vulnerabilities package MEDIUM Vulnerability found in os package type (dpkg) - libgnutls30 (CVE-2011-3389 - https://security-tracker.debian.org/tracker/CVE-2011-3389) warn
You can even subscribe to receive notifications when new CVEs are added to an update with the command:
anchore-cli --u admin --p foobar subscription activate vuln_update docker.io/library/debian:latest
And that’s all there is to installing and using Anchore CLI, to ensure you’re using container images that are safe from vulnerabilities. Use this tool wisely (and often) and it will serve you well.