Le scan de sécurité des conteneurs avec Trivy est devenu le standard de facto pour détecter les vulnérabilités dans les images Docker avant qu’elles n’atteignent la production. Si vous vous êtes déjà demandé comment les attaquants exploitent des CVE connus dans des images de base comme ubuntu:20.04 ou node:18, ou si votre Dockerfile expose des secrets, Trivy vous donne la réponse en quelques secondes. Ce guide couvre l’installation, les stratégies de scan, l’intégration CI/CD et comment interpréter et agir sur les découvertes de Trivy sans se noyer dans les faux positifs.
Prérequis
- Docker installé et en cours d’exécution (Docker 20.10+)
- Station de travail Linux, macOS ou Windows (WSL2)
- Familiarité de base avec les images Docker et les Dockerfiles
- Une plateforme CI/CD (GitHub Actions, GitLab CI ou Jenkins) pour l’intégration de pipeline
- Accès root ou sudo pour l’installation de Trivy au niveau système (ou utiliser l’installation du binaire)
Installation de Trivy
Trivy est distribué comme un binaire statique unique sans dépendances externes. Le chemin le plus rapide sur Linux :
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
trivy --version
Sur Ubuntu/Debian, vous pouvez ajouter le dépôt apt d’Aqua Security pour des mises à jour gérées :
sudo apt-get install wget apt-transport-https gnupg lsb-release -y
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 -y
Sur macOS avec Homebrew : brew install trivy
Trivy télécharge sa base de données de vulnérabilités à la première exécution. Forcez une mise à jour de la base à tout moment avec trivy image --download-db-only.
Scanner les Images Docker pour les Vulnérabilités
La commande principale est simple :
trivy image nginx:latest
Trivy télécharge l’image si elle n’est pas dans le cache local, décompresse les couches et vérifie chaque paquet du système installé et chaque dépendance de langage dans sa base de données de vulnérabilités (NVD, GitHub Advisory, Alpine secdb et autres). La sortie affiche les IDs de CVE, la sévérité, la version installée et la version corrigée lorsqu’elle est disponible.
Filtrage par Sévérité
Par défaut, Trivy affiche toutes les sévérités de UNKNOWN à CRITICAL. En pratique, vous souhaitez vous concentrer sur les découvertes actionnables :
trivy image --severity HIGH,CRITICAL nginx:latest
Ignorer les Vulnérabilités Sans Correction
De nombreux CVE n’ont pas encore de correction disponible. Utilisez --ignore-unfixed pour les ignorer et vous concentrer sur ce que vous pouvez réellement remédier :
trivy image --severity HIGH,CRITICAL --ignore-unfixed nginx:latest
Formats de Sortie
Trivy prend en charge plusieurs formats de sortie pour différents consommateurs :
# Tableau lisible par l'humain (par défaut)
trivy image nginx:latest
# JSON pour le traitement programmatique
trivy image --format json --output results.json nginx:latest
# SARIF pour l'intégration avec l'onglet Sécurité de GitHub
trivy image --format sarif --output results.sarif nginx:latest
# SBOM CycloneDX
trivy image --format cyclonedx --output sbom.json nginx:latest
Le format SARIF s’intègre directement avec l’onglet Sécurité de GitHub, affichant des annotations de vulnérabilités en ligne dans les pull requests.
Scanner les Dockerfiles et Mauvaises Configurations IaC
Le scanner config de Trivy vérifie les Dockerfiles, les manifestes Kubernetes, Terraform et les charts Helm pour les mauvaises configurations de sécurité avant leur déploiement :
# Scanner un Dockerfile
trivy config ./Dockerfile
# Scanner un répertoire complet (manifestes Kubernetes, Terraform)
trivy config ./k8s/
# Scanner des charts Helm
trivy config --helm-values values.yaml ./charts/myapp
Les découvertes courantes dans les Dockerfiles incluent : exécution en tant que root, utilisation de ADD au lieu de COPY, absence de HEALTHCHECK, exposition de ports sensibles et non-fixation des digests d’images de base.
Détection des Secrets et Données Sensibles
Trivy peut scanner les couches d’images et les systèmes de fichiers pour détecter des secrets accidentellement intégrés :
# Activer le scan de secrets sur une image
trivy image --scanners secret nginx:latest
# Scanner un répertoire local pour les secrets
trivy fs --scanners secret ./src/
Trivy détecte les clés AWS, les tokens GitHub, les clés SSH privées, les chaînes de connexion de bases de données et des centaines d’autres modèles de secrets. C’est particulièrement précieux pour attraper les secrets commis dans le code source qui se sont retrouvés dans une couche Docker.
Comparaison avec les Alternatives
| Fonctionnalité | Trivy | Grype | Snyk | Clair |
|---|---|---|---|---|
| CVE des paquets du SO | Oui | Oui | Oui | Oui |
| Dépendances de langage | Oui | Oui | Oui | Non |
| Mauvaises configs IaC | Oui | Non | Oui | Non |
| Scan de secrets | Oui | Non | Oui | Non |
| Génération de SBOM | Oui | Oui | Oui | Non |
| Licence | Apache 2.0 | Apache 2.0 | Propriétaire | Apache 2.0 |
| Intégration CI/CD | Native | Native | Native | Limitée |
| Mode hors ligne | Oui | Oui | Non | Partiel |
L’avantage de Trivy est son étendue — il combine le scan de vulnérabilités, la détection de mauvaises configurations, le scan de secrets et la génération de SBOM dans un seul binaire sans nécessiter de serveur en cours d’exécution ni de base de données.
Intégration de Trivy dans les Pipelines CI/CD
GitHub Actions
name: Scan de Sécurité des Conteneurs
on:
push:
branches: [main]
pull_request:
jobs:
trivy-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Construire l'image Docker
run: docker build -t myapp:${{ github.sha }} .
- name: Exécuter le scanner de vulnérabilités Trivy
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
format: sarif
output: trivy-results.sarif
severity: HIGH,CRITICAL
exit-code: 1
ignore-unfixed: true
- name: Téléverser les résultats Trivy vers l'onglet Sécurité GitHub
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: trivy-results.sarif
Le paramètre exit-code: 1 fait échouer le pipeline lorsque des CVE critiques ou élevés sont trouvés. if: always() sur le téléversement SARIF garantit que les résultats sont visibles même lorsque l’étape de scan échoue.
GitLab CI
trivy-scan:
image: aquasec/trivy:latest
stage: test
script:
- trivy image --exit-code 1 --severity CRITICAL --ignore-unfixed $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
allow_failure: false
Scénario Réel
Vous avez une application en production exécutant node:16 comme image de base. Votre équipe de sécurité signale que le pipeline CI/CD ne valide jamais les images de conteneur avant le déploiement. Vous avez 48 heures pour implémenter une porte de scan.
Étape 1 — Auditer l’image actuelle :
trivy image node:16 --severity HIGH,CRITICAL --ignore-unfixed
Cela révèle 47 CVE HIGH et 12 CRITICAL dans l’image de base — la plupart corrigés en passant à node:18-alpine.
Étape 2 — Mettre à jour le Dockerfile :
# Avant
FROM node:16
# Après
FROM node:18-alpine
Étape 3 — Rescanner pour confirmer la correction :
trivy image node:18-alpine --severity HIGH,CRITICAL --ignore-unfixed
La variante alpine réduit le nombre de CVE de 59 à 3 (tous sans correction).
Étape 4 — Ajouter la porte CI :
Ajoutez le workflow GitHub Actions ci-dessus. Toutes les futures PRs seront bloquées si des CVE CRITICAL sont introduits.
Étape 5 — Scanner aussi l’IaC :
trivy config ./k8s/ --severity HIGH,CRITICAL
Cela révèle deux problèmes : un déploiement s’exécutant en tant que root et un paramètre de contexte de sécurité readOnlyRootFilesystem manquant.
Pièges et Cas Particuliers
Obsolescence de la base de données de vulnérabilités : Trivy met sa base de données en cache localement. Dans les environnements CI, exécutez trivy image --download-db-only comme étape de cache séparée pour éviter les téléchargements redondants.
Authentification sur les registres privés : Exportez les credentials en variables d’environnement avant de scanner :
export TRIVY_USERNAME=monutilisateur
export TRIVY_PASSWORD=monmotdepasse
trivy image monregistre.exemple.com/monapp:latest
Faux positifs : Certains CVE sont signalés dans des bibliothèques que votre application n’appelle jamais. Utilisez .trivyignore pour supprimer les faux positifs connus :
# .trivyignore
CVE-2022-12345 # Non exploitable — bibliothèque non appelée à l'exécution
Alpine musl vs glibc : Les images basées sur Alpine signalent moins de CVE car Alpine utilise musl libc et l’équipe de sécurité d’Alpine corrige agressivement. Ce n’est pas une couverture “manquante” — cela reflète de véritables différences dans l’écosystème des bibliothèques.
Images multi-architecture : Spécifiez toujours la plateforme lors du scan d’images multi-arch pour obtenir des résultats corrects : trivy image --platform linux/amd64 myapp:latest.
Trivy vs sécurité à l’exécution : Trivy trouve les vulnérabilités au moment de la construction. Il ne remplace pas les outils de sécurité à l’exécution comme Falco qui détectent les comportements inattendus dans les conteneurs en cours d’exécution.
Résolution de Problèmes
Erreur “No such image” : Trivy ne peut pas trouver l’image localement et ne peut pas la télécharger. Confirmez le nom de l’image, le tag et les credentials du registre.
Échecs de téléchargement de base de données en environnement isolé : Téléchargez le bundle de base de données sur une machine connectée à Internet avec trivy image --download-db-only, puis transférez le répertoire ~/.cache/trivy/ vers l’hôte isolé.
Utilisation mémoire élevée sur de grandes images : Utilisez --parallel 1 pour réduire le traitement simultané des couches : trivy image --parallel 1 myapp:latest.
Code de sortie 1 mais aucun CVE critique affiché : Vérifiez si --ignore-unfixed est omis — les CVE critiques sans correction peuvent déclencher le code de sortie même si vous espériez ne voir que des problèmes corrigeables.
Timeout de scan en CI : Définissez TRIVY_TIMEOUT=10m pour étendre le timeout par défaut de 5 minutes pour les grandes images.
Résumé
- Trivy est un scanner à binaire unique couvrant les CVE, les mauvaises configurations, les secrets et la génération de SBOM
- Exécutez
trivy image --severity HIGH,CRITICAL --ignore-unfixed myapp:latestcomme scan de base - Utilisez
--exit-code 1en CI/CD pour bloquer les déploiements avec des vulnérabilités critiques - Combinez
trivy image(runtime) avectrivy config(Dockerfile/IaC) pour une couverture complète - Les images basées sur Alpine réduisent considérablement la surface CVE
- Utilisez
.trivyignorepour supprimer les faux positifs confirmés et réduire la fatigue aux alertes - Téléversez les résultats SARIF vers l’onglet Sécurité de GitHub pour des annotations inline dans les PRs
- Trivy ne remplace pas la sécurité à l’exécution — associez-le à Falco pour une défense en profondeur