Skip to content
Snippets Groups Projects
Name Last commit Last update
.gitlab-ci.yml
LICENSE
README.md

Utilisation de trivy pour scanner des images de conteneurs

Ce sont des exemples simples de scans d'images sur le hub Docker. On utilise le rapport de type junit qui permet d'avoir les résultats du scan affichés dans le pipeline.

La syntaxe est :

aJob:
  stage: aStage
  image:
    name: aquasec/trivy:latest
    entrypoint: [""]
  script:
    - |
      trivy --quiet image --exit-code 0 --no-progress --format template --template "@/contrib/junit.tpl" URI_IMAGE_DOCKER_HUB > junit-report.xml
  artifacts:
    reports:
      junit: junit-report.xml

URI_IMAGE_DOCKER_HUB prend une valeur comme debian:latest.

Pour scanner des images stockées dans le registre de GitLab-forge, la syntaxe est légèrement moins simple :

aJob:
  stage: aStage
  image:
    name: aquasec/trivy:latest
    entrypoint: [""]
  before_script:
    - |
      export TRIVY_AUTH_URL=$CI_REGISTRY
      export TRIVY_USERNAME=$CI_REGISTRY_USER
      export TRIVY_PASSWORD=$CI_REGISTRY_PASSWORD
  script:
    - |
      trivy --quiet image --exit-code 0 --no-progress --format template --template "@/contrib/junit.tpl" URI_IMAGE_GITLABFORGE > junit-report.xml
  after_script:
    - |
      unset TRIVY_AUTH_URL
      unset TRIVY_USERNAME
      unset TRIVY_PASSWORD
  artifacts:
    reports:
      junit: junit-report.xml

URI_IMAGE_GITLABFORGE prend une valeur comme registry.gitlab-forge.din.developpement-durable.gouv.fr/share/devops/docker/mkdocs-material-plusplus/mkdocs-material-plusplus:7.3.6.

Les résultats de scans dépendent des images de base qui elles-mêmes sont mises à jour par les développeurs !

Il faut donc :

  1. scanner les images construites par CI/CD pour connaître leurs vulnérabilités ;
  2. reconstruire ces images car les images de base peuvent avoir corriger certaines (ou toutes) les vulnérabilités ;
  3. Aller en 1. 😁

La fréquence de reconstruction des images dépend de l'activité du produit (mais au moins une fois par an si le produit est "inactif"), sinon il faut surveiller les alertes !

Intégration de Trivy dans GitLab par GitLab

L'intégration basée sur ce script a été ajoutée pour comparer un usage "à la main" et la consommation intégrée de Trivy par GitLab. Elle permet aussi d'utiliser Grype.

À noter : Clair a été retiré de cette intégration depuis GitLab 13.9.

L'un des résultats issus de l'intégration Trivy est un artefact qui donne les dépendences logicielles trouvées dans l'image de conteneur en format JSON 👍

Cette intégration s'est effectué en fabriquant deux modèles de job :

Appel direct à Trivy

.scan_an_image:
  stage: scan:image

  image:
    name: $TRIVY_IMAGE
    entrypoint: [""]

  script:
    - |
      trivy --quiet image --exit-code 0 --no-progress --format template --template "@/contrib/junit.tpl" $IMAGE_TO_SCAN > junit-report.xml
  allow_failure: true

  artifacts:
    reports:
      junit: junit-report.xml

Il suffit de valoriser la variable IMAGE_TO_SCAN avec l'image à scanner :

scanne_mon_image:
  extends: .scan_an_image
  variables:
    IMAGE_TO_SCAN: "URL_D_ACCESS_A_L_IMAGE"

Appel à Trivy via l'intégration effectuée par GitLab

.container_scanning:
  stage: test

  image: "$CS_ANALYZER_IMAGE$CS_IMAGE_SUFFIX"

  allow_failure: true

  artifacts:
    reports:
      container_scanning: gl-container-scanning-report.json
      dependency_scanning: gl-dependency-scanning-report.json
    paths: [gl-container-scanning-report.json, gl-dependency-scanning-report.json]
  dependencies: []

  script:
    - gtcs scan

  rules:
    - if: $CONTAINER_SCANNING_DISABLED
      when: never

    - if: $CI_COMMIT_BRANCH &&
          $CI_GITLAB_FIPS_MODE == "true" &&
          $CS_ANALYZER_IMAGE !~ /-(fips|ubi)\z/
      variables:
        CS_IMAGE_SUFFIX: -fips
    - if: $CI_COMMIT_BRANCH

Il suffit de valoriser, à minima, la variable DOCKER_IMAGE avec l'image à scanner :

container_scanning_image:
  extends: .container_scanning
  variables:
    DOCKER_IMAGE: "URL_D_ACCESS_A_L_IMAGE"