Veröffentlicht am

Trivy: Container-Schwachstellen automatisch scannen

Teilen:
Authors

TL;DR

Trivy ist ein Open-Source-Scanner von Aqua Security, der Schwachstellen in Container-Images, Dateisystemen und laufenden Kubernetes-Clustern erkennt. Mit dem Trivy Operator lässt sich das Scanning direkt im Cluster automatisieren — inklusive VulnerabilityReport-CRDs, die sich wie native Kubernetes-Ressourcen abfragen lassen.


Container-Schwachstellen mit Trivy finden

Ein Container-Image ohne Schwachstellen-Scan in Production zu deployen ist wie ein Deployment ohne Health-Checks — es funktioniert, bis es das nicht mehr tut. Trivy macht Vulnerability-Scanning einfach: ein einzelnes Binary, keine externe Datenbank, kein Server-Setup.

Trivy installieren

Die Installation ist auf allen Plattformen unkompliziert:

# macOS
brew install trivy

# Linux (Debian/Ubuntu)
sudo apt-get install wget apt-transport-https gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/trivy.list
sudo apt-get update && sudo apt-get install trivy

# Version prüfen
trivy version

Images scannen mit der CLI

Der häufigste Anwendungsfall: ein Container-Image vor dem Push scannen.

# Einfacher Image-Scan
trivy image nginx:1.27

# Nur kritische und hohe Schwachstellen anzeigen
trivy image --severity HIGH,CRITICAL python:3.12-slim

# Scan mit Exit-Code 1 bei kritischen Findings (für CI/CD)
trivy image --exit-code 1 --severity CRITICAL myapp:latest

# Lokales Image scannen (ohne Pull)
trivy image --input ./myapp-image.tar

Die Ausgabe zeigt gefundene CVEs mit Schweregrad, betroffener Bibliothek und verfügbarem Fix:

SpalteBedeutung
LibraryBetroffenes Paket oder OS-Paket
VulnerabilityCVE-Nummer
SeverityCRITICAL, HIGH, MEDIUM, LOW
Fixed VersionVersion mit dem Fix (leer = kein Fix verfügbar)

Dateisysteme und Repositories scannen

Trivy kann mehr als nur Images — Dateisysteme und Git-Repos werden ebenfalls unterstützt:

# Lokales Projektverzeichnis scannen (Dockerfile, package.json, go.sum etc.)
trivy fs .

# Git-Repository direkt scannen
trivy repo https://github.com/mein-org/meine-app

# Kubernetes-Manifeste auf Fehlkonfigurationen prüfen
trivy config ./k8s-manifests/

Der config-Scan erkennt unsichere Einstellungen wie runAsRoot: true oder fehlende Resource-Limits — praktisch als Pre-Commit-Check.

CI/CD-Integration mit GitHub Actions

Trivy lässt sich in jede CI/CD-Pipeline einbauen. Hier eine GitHub Actions Workflow-Datei, die bei jedem Push das Image scannt:

# .github/workflows/trivy-scan.yml
name: Trivy Container Scan
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build Image
        run: docker build -t myapp:${{ github.sha }} .

      - name: Trivy Vulnerability Scan
        uses: aquasecurity/trivy-action@0.28.0
        with:
          image-ref: 'myapp:${{ github.sha }}'
          format: 'table'
          exit-code: '1'
          severity: 'CRITICAL,HIGH'
          ignore-unfixed: true

      - name: Trivy SARIF Upload (optional)
        uses: aquasecurity/trivy-action@0.28.0
        with:
          image-ref: 'myapp:${{ github.sha }}'
          format: 'sarif'
          output: 'trivy-results.sarif'

      - name: Upload SARIF to GitHub Security
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: 'trivy-results.sarif'

Der exit-code: '1' sorgt dafür, dass der Build fehlschlägt, wenn kritische Schwachstellen gefunden werden. Mit ignore-unfixed: true werden CVEs ohne verfügbaren Fix ignoriert — das reduziert Rauschen.

Trivy Operator: Scanning im Cluster

Einzelne Image-Scans in der Pipeline sind gut, aber was ist mit den Hunderten von Images, die bereits im Cluster laufen? Der Trivy Operator scannt automatisch alle Workloads und speichert Ergebnisse als Kubernetes-CRDs.

Installation per Helm

# Helm-Repo hinzufügen
helm repo add aqua https://aquasecurity.github.io/helm-charts/
helm repo update

# Trivy Operator installieren
helm install trivy-operator aqua/trivy-operator \
  --namespace trivy-system \
  --create-namespace \
  --set trivy.ignoreUnfixed=true

Nach der Installation scannt der Operator automatisch alle Pods im Cluster. Die Ergebnisse erscheinen als VulnerabilityReport-Ressourcen:

# Alle Reports auflisten
kubectl get vulnerabilityreports -A

# Details für ein bestimmtes Workload
kubectl get vulnerabilityreports -n production -l trivy-operator.resource.name=frontend -o yaml

# Nur kritische Findings filtern
kubectl get vulnerabilityreports -A -o json | \
  jq '.items[] | select(.report.summary.criticalCount > 0) | {namespace: .metadata.namespace, name: .metadata.labels["trivy-operator.resource.name"], critical: .report.summary.criticalCount}'

VulnerabilityReports auswerten

Die Reports enthalten strukturierte Daten, die sich gut mit bestehenden Tools kombinieren lassen:

FeldBeschreibung
.report.summaryÜbersicht: criticalCount, highCount, mediumCount, lowCount
.report.vulnerabilities[]Einzelne CVEs mit Details
.metadata.labelsZuordnung zum Workload (Deployment, StatefulSet etc.)

Ein einfaches Alerting-Setup mit kubectl und Slack:

#!/bin/bash
# critical-vuln-alert.sh — als CronJob im Cluster deployen
CRITICAL=$(kubectl get vulnerabilityreports -A -o json | \
  jq '[.items[] | .report.summary.criticalCount] | add')

if [ "$CRITICAL" -gt 0 ]; then
  curl -X POST "$SLACK_WEBHOOK" \
    -H 'Content-Type: application/json' \
    -d "{\"text\": \"⚠️ $CRITICAL kritische Schwachstellen im Cluster gefunden\"}"
fi

Trivy richtig konfigurieren

Für produktive Umgebungen empfehlen sich einige Anpassungen:

# .trivyignore — bekannte False Positives ausschließen
# CVE-2024-1234  # Erklärung warum ignoriert
# CVE-2024-5678  # Nicht relevant für unseren Use-Case

# Trivy mit Cache für schnellere Scans (CI/CD)
trivy image --cache-dir /tmp/trivy-cache --severity HIGH,CRITICAL myapp:latest

Der Operator lässt sich per Helm-Values auf bestimmte Namespaces beschränken oder mit Scan-Intervallen konfigurieren:

helm upgrade trivy-operator aqua/trivy-operator \
  --namespace trivy-system \
  --set operator.scanJobsConcurrentLimit=3 \
  --set operator.scanJobsRetryDelay=30s \
  --set trivyOperator.scanJobPodTemplateLabels="app=trivy-scan"

FAQ

Wie oft aktualisiert Trivy seine Schwachstellen-Datenbank?

Trivy lädt die Datenbank beim ersten Scan automatisch herunter und aktualisiert sie bei jedem weiteren Scan. Im CI/CD-Kontext empfiehlt sich ein vorgelagerter trivy image --download-db-only-Schritt mit Cache.

Was ist der Unterschied zwischen Trivy und Grype?

Beide sind Open-Source-Vulnerability-Scanner. Trivy deckt mehr Bereiche ab (Images, IaC, Secrets, SBOM), während Grype sich auf reine Vulnerability-Detection spezialisiert. Trivy bietet mit dem Operator zudem eine native Kubernetes-Integration.

Verlangsamt der Trivy Operator den Cluster?

Der Operator erstellt Scan-Jobs, die als reguläre Pods laufen. Mit scanJobsConcurrentLimit lässt sich die Parallelität begrenzen. In der Praxis ist der Ressourcenverbrauch minimal — typischerweise unter 200 MB RAM für den Controller.

Kann Trivy auch Secrets in Images finden?

Ja, mit trivy image --scanners secret myapp:latest werden eingebettete Secrets wie API-Keys, Passwörter oder Private Keys erkannt. Das ergänzt die Vulnerability-Detection um einen wichtigen Sicherheitsaspekt.


Nächster Schritt: Kombiniere Trivy mit einer Policy-Engine wie OPA Gatekeeper, um Images mit kritischen Schwachstellen automatisch am Deployment zu hindern.

Kubernetes-Security & Compliance?

Security-Audits, Penetration Tests und Compliance-Beratung für Ihre Container-Infrastruktur. BSI-Grundschutz, DSGVO, ISO 27001.

Kubernetes-Beratung gesucht?

Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.

📖 Verwandte Artikel

Weitere interessante Beiträge zu ähnlichen Themen