DevSecOps — how to secure Docker containers using Trivy

·

5 min read

DevSecOps — how to secure Docker containers using Trivy

Making sure that our contenerized architecture is properly protected is not an easy job. This is one of DevSecOps responsibility to make sure that everything is under control when it comes to security and integrate various security scanners in the process of CI/CD.

What is Trivy?

Trivy is an open-source vulnerability scanner specifically designed for containers and container images. It supports various container image formats like Docker, OCI, and others which is making this tool a great choice to increase container security.

Link to project: https://aquasecurity.github.io/trivy/v0.17.2/

Why Trivy?

There is a couple of tools dedicated to container security scanning, but in my case Trivy was the best choice and here is why.

It’s free — project is free, open source and new releases are quite often. Documentation is well-developed and easy to learn, and new features are planned to be delivered.

Integration with Kubernetes — it’s easy to integrate within Kubernetes clusters. I will show an example implementation later in this article.

Results of analysis in multiple formats — results are provided in JSON and HTML files.

Compatible with various container image formats — including Docker and OCI, so I can use it with most container runtime environments.

Also, we can scan different artifacts like Container Images, Filesystem, Git Repositories.

It’s fast — the scanning process is fast, so it’s reducing the impact on continuous integration/continuous deployment processes. As Trivy documentation states: “The first scan will finish within 10 seconds (depending on your network). Consequent scans will finish in single seconds.”

Integration with CI tools — can be integrated with CI tools like Travis CI, CircleCI, Jenkins, GitLab CI.

Integration with AWS solutions — can be easily integrated with AWS Security Hub. Details -> https://aws.amazon.com/blogs/security/how-to-build-ci-cd-pipeline-container-vulnerability-scanning-trivy-and-aws-security-hub/ Also, can be integrated with AWS CodePipeline. Details -> https://aws.amazon.com/blogs/containers/scanning-images-with-trivy-in-an-aws-codepipeline/

Big vulnerabilities database — this database includes vulnerabilities from Common Vulnerabilities and Exposures (CVE) and other sources, ensuring that you have access to the latest threat intelligence.

Supports multiple OS packages — detect comprehensive vulnerabilities for OS packages eg. Alpine, Red Hat Universal Base Image, Red Hat Enterprise Linux, CentOS, Oracle Linux, Debian, Ubuntu, Amazon Linux and more

Supports multiple application dependencies — detect comprehensive vulnerabilities for application dependencies eg. Composer, Pipenv, npm, yarn, Cargo, Maven or Go to name a few.

Setting Up Trivy with Kubernetes

To demonstrate how Trivy can be used for container security scanning with Kubernetes, let’s walk through the setup and configuration steps.

Before we start, you should have a cluster up and running, kubectl configured and Trivy installed on your local machine.

Here is an instruction how to install Trivy: https://aquasecurity.github.io/trivy/v0.18.3/installation/

Deploying Trivy to Kubernetes

You can deploy Trivy as a Kubernetes job or DaemonSet. For this example, let’s use a DaemonSet to ensure that Trivy runs on every node in the cluster.

If you wonder why I chose DaemonSet, here are a couple of reasons:

  • Scalability — to ensure that one instance of Trivy runs on every node within the cluster. This guarantees that all nodes and containers are scanned. Deploying a single pod would only scan containers running on that specific node.

  • High Availability — to automatically reschedule pods to new nodes if a node goes down or experiences issues.

  • Simplicity — to simplify the setup and management of the security scanning infrastructure. We don’t have to keep track of which nodes have Trivy deployed as DaemonSet is doing this job.

  • Node independence —to automatically manage the placement of Trivy pods on nodes, so we don’t have to manually decide which nodes to deploy Trivy on.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: trivy
spec:
  selector:
    matchLabels:
      app: trivy
  template:
    metadata:
      labels:
        app: trivy
    spec:
      containers:
        - name: trivy
          image: aquasec/trivy:latest
          command: ["trivy", "server", "--listen", "0.0.0.0:8000"

Run kubectl apply -f trivy-daemonset.yaml to apply the configuration.

Scanning a Container Image

Let’s assume you have a container image named my-app:latest that you want to scan. Here is how you can run scan for this image:

kubectl run trivy-scan --image=aquasec/trivy:latest --rm -it -- trivy --no-progress my-app:latest

This command deploys a temporary pod, runs Trivy inside it, and scans the my-app:latest image for vulnerabilities.

Here is a short explanation of command we used:

  • kubectl run trivy-scan— it creates a new Kubernetes resource named trivy-scan.

  • --image=aquasec/trivy:latest- it specifies the container image that we want to run as part of the created Kubernetes resource. Kubernetes will pull Trivy image from a container registry aquasec/trivy and use the latest tag.

  • --rm- automatically remove the created resource like our pod once it has completed its task.

  • -it-i stands for interactive, -t stands for terminal. It allocates an interactive terminal session inside the container to run commands inside the container.

  • -- trivy --no-progress my-app:latest— it essentially runs the trivy scanner with specific options and targets the my-app:latest container image for scanning. --no-progresstells Trivy not to display progress information during the scan. It may be useful for scripting or automation purposes when you want to capture the scan results without any additional output.

  • my-app:latest — it specifies the container image to scan.

Scanning a Container Image

Let’s take an example of a vulnerable container image and scan it using Trivy. We will use this one: https://hub.docker.com/r/vulnerables/cve-2017-7494

First, we have to deploy vulnerable container image to Kubernetes cluster and apply it using kubectl apply command.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: bad-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: bad-app
  template:
    metadata:
      labels:
        app: bad-app
    spec:
      containers:
        - name: bad-app
          image: vulnerables/cve-2017-7494
          ports:
            - containerPort: 80

Next, we scan the bad-app container image with Trivy:

kubectl run trivy-scan --image=aquasec/trivy:latest --rm -it -- trivy --no-progress docker.io/vulnerables/cve-2017-7494

Trivy will generate a report of vulnerabilities in JSON and HTML format.

Summary

As you can see Trivy is super simple when it comes to Kubernetes integration. Here you can find more Trivy commands: https://aquasecurity.github.io/trivy/v0.17.2/usage/

You can use it to scan container images, but also filesystems and repositories. It’s a great tool to enhance the security of containerized applications and ensure that they remain resilient against potential threats.