🐳 Scan Docker images for vulnerabilities with Trivy

Before releasing applications to production, you need to take very strong security measures and protocols to help protect your assets.

Today we are introducing Trivy.

Trivy is a simple and comprehensive vulnerability scanner for containers and other artifacts.

It helps detect vulnerabilities in operating system packages (Alpine, RHEL, CentOS, etc.) and application dependencies (Bundler, Composer, npm, yarn, etc.).

You can easily scan your local container image and other artifacts before submitting to the container register or deploying your application, giving you confidence that everything is fine with your application.

Features of Trivy

  • Discovery of complex vulnerabilities
  • Simplicity – Specify only the image name or the artifact name.
  • Fast – The first scan will complete within 10 seconds (depending on your network). Follow-up scan will complete in seconds
  • DevSecOps – Suitable for CIs like Travis CI, CircleCI, Jenkins, GitLab CI, etc.
  • Support for multiple formats – including: container image, local file system, remote git repository.
  • Easy installation – it is possible to install apt-get, yum install and brew without prerequisites such as installing the database, libraries, etc.

How to use the Trivy image scanner

Trivy can be installed on a number of Linux distributions as well as macOS.

We’ll cover installing Trivy on CentOS, Ubuntu, Debian, Arch, and MacOS.

Installing Trivy on CentOS

You have two options if you want to install Trivy on your CentOS.

You can use the Trivy repository or install it directly from the RPM.

To install from the repository, add the following repo and then proceed with the Trivy installation.

echo -e "n[trivy]nname=Trivy repositorynbaseurl=https://aquasecurity.github.io/trivy-repo/rpm/releases/$releasever/$basearch/ngpgcheck=0nenabled=1" | sudo tee -a /etc/yum.repos.d/kubernetes.repo

After adding the Trivy repository, update the server and install the trivy package as follows:

sudo yum -y update
sudo yum -y install trivy

To install trivy from RPM, you need to get the latest version of Trivy and then run the following commands:

$ rpm -ivh https://github.com/aquasecurity/trivy/releases/download/v0.12.0/trivy_0.12.0_Linux-64bit.rpm

Installing Trivy on Debian | Ubuntu

Similar to installing Trivy on CentOS, you also have two options that you can use to install it on your Debian | Ubuntu.

You can use the Trivy repository or install it directly from the DEB source.

To install from the repository, add the following repo, then proceed to install Trivy.

sudo apt-get install wget apt-transport-https gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main | sudo tee /etc/apt/sources.list.d/trivy.list

After adding the Trivy repository, update the server and install the trivy package as follows:

sudo apt-get update
sudo apt-get install trivy

Alternatively, if you are a fan of the deb source code, you can install Trivy using its DEB source code. To install Trivy this way, you will need to get the latest version of Trivy and then run the following commands:

sudo apt-get install rpm
wget <deb-package-url>
sudo apt install ./<deb-package>.deb

Installing Trivy on Arch Linux | Manjaro

Well, for all dedicated Arch fans, you can easily install Trivy on your computer using pikaur or yay AUR as shown below.

pikaur -Sy trivy-bin

Or you can use the yay AUR helper like so:

yay  -Sy trivy-bin

Yay – Another reliable AUR helper written in GO

Installing Trivy on macOS

You can install this great tool on MacOS through Homebrew by running the command:

brew install aquasecurity/trivy/trivy

Trivy in action – how to use Trivy

With Trivy installed, we’re ready to get started right away.

Trivy covers many use cases, and we’ll cover some of them in this guide.

File system scan

Trivy can scan a file system (for example, a host machine, a virtual machine image, or the file system of an unpacked container image).

During the scan, it will look for vulnerabilities based on lock files such as Gemfile.lock and package-lock.json.

The syntax looks like this:

$ trivy fs /home/vagrant

2020-11-09T10:35:41.656Z        WARN    OS is not detected and vulnerabilities in OS packages are not detected.
2020-11-09T10:35:41.656Z        INFO    Detecting ruby vulnerabilities...
2020-11-09T10:35:41.656Z        INFO    Detecting nodejs vulnerabilities...

octant/site/Gemfile.lock
========================
Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)


octant/web/package-lock.json
============================
Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)

Scanning your Git repository

Luckily, you can scan a remote git repository with this simple yet powerful tool.

It should be noted, however, that only public repositories are supported here.

Scan your Git repository using the repo switcher like this:

$ trivy repo https://github.com/aquasecurity/trivy

2020-11-09T07:13:25.265Z        INFO    Need to update DB
2020-11-09T07:13:25.265Z        INFO    Downloading DB...
19.13 MiB / 19.13 MiB [-----------------------------------------------------------] 100.00% 512.75 KiB p/s 38sEnumerating objects: 2338, done.
Counting objects: 100% (2338/2338), done.
Compressing objects: 100% (1260/1260), done.


Total 2338 (delta 1229), reused 1943 (delta 933), pack-reused 0
2020-11-09T07:40:29.758Z        WARN    OS is not detected and vulnerabilities in OS packages are not detected.

Scanning images

After developing and building your application into an image (Docker or so), you have the opportunity to spot any security issue you might have missed.

Just provide the image name and tag along with your simple command as shown below.

$ docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              c39a868aad02        3 days ago          133MB
$ trivy image nginx

You should see a long and detailed report in your terminal output.

Inserting Trivy into Dockerfile

Another cool feature of this tool is that you can include it in your Dockerfile and it will scan everything as the image is built.

We’ll be using the Nginx image to demonstrate here as follows:

$ vim Dockerfile
FROM alpine:3.7

RUN apk add curl 
    && curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/master/contrib/install.sh | sh -s -- -b /usr/local/bin 
    && trivy filesystem --exit-code 1 --no-progress /

Then build your image with output similar to the one shown below:

$ docker build -t scanned-image .

Sending build context to Docker daemon 8.704 kB
Step 1/2 : FROM alpine:3.7
Trying to pull repository docker.io/library/alpine ...
3.7: Pulling from docker.io/library/alpine
5d20c808ce19: Pull complete
Digest: sha256:8421d9a84432575381bfabd248f1eb56f3aa21d9d7cd2511583c68c9b7511d10
Status: Downloaded newer image for docker.io/alpine:3.7
 ---> 6d1ef012b567
Step 2/2 : RUN apk add curl     && curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/master/contrib/install.sh | sh -s 
-- -b /usr/local/bin     && trivy filesystem --exit-code 1 --no-progress /
 ---> Running in 445558539f6f

fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
(1/4) Installing ca-certificates (20190108-r0)
(2/4) Installing libssh2 (1.9.0-r1)
(3/4) Installing libcurl (7.61.1-r3)
(4/4) Installing curl (7.61.1-r3)
Executing busybox-1.27.2-r11.trigger
Executing ca-certificates-20190108-r0.trigger
OK: 6 MiB in 17 packages
aquasecurity/trivy info checking GitHub for latest tag
aquasecurity/trivy info found version: 0.12.0 for v0.12.0/Linux/64bit
aquasecurity/trivy info installed /usr/local/bin/trivy
2020-11-09T10:13:02.597Z        INFO    Need to update DB
2020-11-09T10:13:02.597Z        INFO    Downloading DB...
2020-11-09T10:13:27.545Z        INFO    Detecting Alpine vulnerabilities...
2020-11-09T10:13:27.547Z        WARN    This OS version is no longer supported by the distribution: alpine 3.7.3
2020-11-09T10:13:27.547Z        WARN    The vulnerability detection may be insufficient because security updates are not provided   

445558539f6f (alpine 3.7.3)
===========================
Total: 2 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 2)

+------------+------------------+----------+-------------------+---------------+--------------------------------+
|  LIBRARY   | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |             TITLE              |
+------------+------------------+----------+-------------------+---------------+--------------------------------+
| musl       | CVE-2019-14697   | CRITICAL | 1.1.18-r3         | 1.1.18-r4     | musl libc through 1.1.23       |
|            |                  |          |                   |               | has an x87 floating-point      |
|            |                  |          |                   |               | stack adjustment imbalance,    |
|            |                  |          |                   |               | related...                     |
+------------+                  +          +                   +               +                                +
| musl-utils |                  |          |                   |               |                                |
|            |                  |          |                   |               |                                |
|            |                  |          |                   |               |                                |
|            |                  |          |                   |               |                                |
+------------+------------------+----------+-------------------+-----

Filter vulnerabilities by severity

If you have special needs and want the generated report to be filtered so that you can see HIGH, CRITICAL and other fields, Trivy will do it for you right out of the box.

Just run a command similar to the following:

$ trivy image --severity HIGH,CRITICAL nginx:latest

Scan your project with a lock file

If you have a Python project, chances are high it has a lock file.

Therefore, you can scan a project like this with trivy like this:

$ trivy fs ~/src/github.com/aquasecurity/trivy-ci-test

Scanning a container inside a container

To add even more sugar to your sweet tea, it’s worth mentioning that Trivy can scan your running container from within that container.

This is how it can be achieved, and note that you do not need to install Trivy on the host machine.

$ docker run --rm -it nginx 
   && curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/master/contrib/install.sh | sh -s -- -b /usr/local/bin 
   && trivy fs /

Scanning using Harbor

We looked at this tool earlier:

☸️ Installing Harbor – Image Registry in Kubernetes / OpenShift using Helm

🐳 How to use Harbor to scan Docker images for vulnerabilities

Trivy is a built-in scanner along with Clair.

You can scan directly through your browser:

🐳 Scan Docker images for vulnerabilities with Trivy

Sidebar