Find Vulnerabilities in Container Images with Docker Scan
As you continue to shift your development process to cloud native computing, you’ll find yourself working with more and more container images. Those images might be officially vetted by the company that produced them (such as those from Red Hat, Canonical, Rocky Linux, NGINX, and AlmaLinux), or they might come from third-party sources that might not hold the same level of trust those larger companies have. When that is the case, what do you do? Do you blindly trust the images you are about to use are sans vulnerability? Or do you use a measure of caution to ensure that the very foundation of your container deployment doesn’t include deal-breaking or dangerous vulnerabilities?
The answer is always to use a measure of caution. Always. Even if you’re using official images from reputable companies, you should take the same precautions, because you never know when something might slip through the cracks.
But how do you scan those images for vulnerabilities? There are a lot of tools available for this task, some of them are costly services, while others are free alternatives that are pretty simple and safe to use.
One such tool is Docker Desktop. Now, recently it was revealed the Docker Desktop was no longer going to be free to use for large companies. But if you’re an individual developer or small business (with fewer than 250 employees), you can continue using the tool for free. For businesses with over 250 employees or higher than $10 million in annual revenue, you’ll have to have a paid subscription to continue using Docker Desktop.
But I’m focusing on individual cloud native developers who still need to ensure the containers they deploy are based on images free from vulnerabilities. To make that possible, Docker Desktop includes a handy scanning tool. Here’s the catch, unlike much of what you can do with Docker Desktop, the scanner is a command-line only tool. Fortunately, however, the command is very easy to use.
This scanning tool isn’t just available in Docker Desktop. You can also add it to Docker on Linux. I’m going to show you how to do just that after I introduce you to how the command is run on the macOS version of Docker Desktop.
Before you attempt this, you’ll first need to download and install Docker Desktop on your macOS machine. Fortunately, the developers have made this as simple as downloading a binary file and installing it as you would any application on your Mac.
After you’ve installed Docker Desktop, start it up and give it the necessary permissions it asks for. When the Docker Engine is running, you’re ready to pull down an image and start scanning.
How to Scan an Image
For the purposes of illustration, I have an older image of NGINX on my Macbook Pro and want to scan it. I pulled down that image some time ago with the command:
docker pull nginx
I can scan that image with:
docker scan nginx
The scan will start and complete fairly quickly (depending on the size of the image, of course). In my case, Docker will report that the base image is out of date and inform me I should pull down a new one. It will also report that it found a whopping 176 vulnerabilities in the image (Figure 1 — because it’s out of date).
What if we update that image? Do so by pulling down the latest version, again with the command:
docker pull nginx:latest
After pulling down the latest version and re-running the scan, Docker reported the same results, which I found odd. Because of this, I tried scanning the image using the image ID instead. To find the image ID, I issued the command:
You should see an ID associated with the nginx image. After running the command docker scan ID (Where ID is the ID of the NGINX image), the new results reported that I was using the most secure version of the image, but still had 110 vulnerabilities associated with 136 dependencies.
For a bit of good news, I pulled down the latest AlmaLinux container image and ran a scan. The end results found 0 vulnerabilities. Huzzah!
How to Use Docker Scan on Linux
To use this command on Linux, we first must remove the old version of Docker with the command:
sudo apt-get remove docker docker-engine docker.io containerd runc -y
Once you’ve removed the older version, install the necessary dependencies with the command:
sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release -y
Add the Docker GPG key with:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
Add the necessary repository with the command:
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Update apt with:
sudo apt-get update
Finally, install Docker Engine with:
sudo apt-get install docker-ce docker-ce-cli containerd.io -y
Start and enable the Docker Engine with the commands:
sudo systemctl start docker
sudo systemctl enable docker
Add your user to the docker group with:
sudo usermod -aG docker $USER
Log out and log back in so the changes will take effect. Before you run a scan, however, you must log in to Docker Hub using an access token. You can generate an access token from the Security section of your DockerHub account. Once you’ve created an access token, log in with the command:
docker login -u USERNAME
Where USERNAME is your DockerHub username.
At this point, you should be able to scan images in Linux in the same method as described above.
And that’s all there is to scanning Docker container images with the docker scan command, from either Docker Desktop or the Docker Engine on Linux. You should put this step into your container development workflow, so you can be sure you’re starting with a solid security foundation.