Sommaire
Beaucoup de services sont utilisés dans une usine logicielle, gestionnaire de sources, orchestrateur CI/CD, gestionnaire d'artefacts, systèmes de mesure de la qualité et de la sécurité.
Ces services sont gérés par les équipes CI/CD, SRE, DevOps, DevSecOps, le cadre opérationnel est donc connu et nous avons une garantie de qualité de service et de sécurité.
Pour les outils utilisés des chaînes de CI/CD, il convient d’être encore plus vigilant, car ils ont un accès direct au code source, mais aussi aux binaires qui seront produits. Ce sont donc des cibles de choix pour faire pénétrer des contenus malveillants.
Pendant longtemps, ces outils étaient sous le contrôle exclusif des équipes CI/CD, mais les choses ont changé avec l’avènement des pipelines CI/CD utilisant des containers Docker pour porter les outils CI/CD.
Si cela permet aux développeurs d’avoir un contrôle précis sur la fabrication, cela introduit aussi de nouveaux risques.
Images Docker dans les Pipelines
Prenons l’exemple de construction d’un projet Java exemple trouvé sur Gitlab :
image: maven:3.9.8
variables:
MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
cache:
paths:
- .m2/repository/
- target/
build:
stage: build
script:
- mvn $MAVEN_CLI_OPTS compile
test:
stage: test
script:
- mvn $MAVEN_CLI_OPTS test
deploy:
stage: deploy
script:
- mvn $MAVEN_CLI_OPTS deploy
only:
- master
Ce fichier décrit les étapes de compilation, test et déploiement, les commandes à effectuer et les conditions.
Le script indique qu’une image Docker appelée Maven 3.9.8 sera utilisée pour l’ensemble des étapes.
Analyses des images Docker CI/CD
Quand nous utilisons une image Docker, nous devons nous intéresser à sa provenance et vérifier si elle n’embarque pas des vulnérabilités.
Regardons plus attentivement l’image maven:3.9.8
Vulnérabilités d’une image
Commençons par voir si elle n’embarque pas de vulnérabilités sérieuses avec l’outil Trivy.
$ trivy --severity HIGH,CRITICAL image maven:3.9.8
2024-07-30T11:42:18+02:00 INFO Vulnerability scanning is enabled
2024-07-30T11:42:18+02:00 INFO Secret scanning is enabled
2024-07-30T11:42:18+02:00 INFO If your scanning is slow, please try '--scanners vuln' to disable secret scanning
2024-07-30T11:42:18+02:00 INFO Please see also https://aquasecurity.github.io/trivy/v0.52/docs/scanner/secret/#recommendation for faster secret detection
2024-07-30T11:42:18+02:00 INFO Detected OS family="ubuntu" version="24.04"
2024-07-30T11:42:18+02:00 INFO [ubuntu] Detecting vulnerabilities... os_version="24.04" pkg_num=139
2024-07-30T11:42:18+02:00 INFO Number of language-specific files num=1
2024-07-30T11:42:18+02:00 INFO [jar] Detecting vulnerabilities...
maven:3.9.8 (ubuntu 24.04)
Total: 0 (HIGH: 0, CRITICAL: 0)
Aucune vulnérabilité majeure (filtre HIGH,CRITICAL) remontée, c’est bon signe.
La même analyse sans le filtrage aurait indiqué 55 vulnérabilités, 40 basses et 15 modérées, nous pouvons raisonnablement nous limiter aux majeures pour avoir un bon niveau de sécurité.
$ trivy image maven:3.9.8
…
Total: 55 (UNKNOWN: 0, LOW: 40, MEDIUM: 15, HIGH: 0, CRITICAL: 0)
Si des vulnérabilités majeures (HIGH ou CRITICAL) sont remontées, il faut faire une analyse plus approfondie pour s’assurer qu’elles ne sont pas exploitables.
Si elles sont exploitables, nous ne devons plus utiliser l’image jusqu’à la résolution, que ça soit par retour arrière, par suppression du composant critique ou par l’utilisation d’une autre image équivalente et viable.
Carte d’identité d’une image
Après les vulnérabilités de l’image, il faut être attentif à l’image en elle-même.
- D’où provient-elle ?
- Qui la produit ?
En premier lieu, il faut vérifier qu’elle fait partie des images de confiance de Docker Hub, image officielle ou image d’éditeur certifié.
Si nous reprenons l’exemple de maven:3.9.8, nous voyons qu’il s’agit d’une image officielle, le mainteneur Carlos Sanchez est une personne connue de la communauté Docker et nous avons accès aux sources des images Maven.
Avoir accès aux sources permet de s’assurer que rien d’anormal n’a été introduit dans l’image et que nous pouvons reconstruire l’image soit même si des contraintes réglementaires l'imposent.
Il est fortement recommandé de ne jamais utiliser d’images Docker qui ne proviennent pas de sources sûres, comme Docker Hub Official / Verified Editor ou d’un éditeur avec qui nous n’avons pas un contrat de support.
De même, utiliser une image opaque, sans les sources correspondantes, ne permet pas d’être en confiance sur le contenu.
Idempotence
Comment garantir que la même action effectuée à des moments différents du temps donnera le même résultat, typiquement si vous cherchez à recréer un binaire depuis une base source vieille de 12 mois pour des questions d’audit et d'investigation ?
Un coup d’oeil sur le projet Docker de maven montre beaucoup de noms d’images mais rien sur maven:3.9.8. C’est ce qui s’appelle un alias, une image qui du coup ne donne pas d’informations sur ce qui la compose hors c’est indispensable pour trouver le source correspondant. Allons examiner l’image.
docker run -it --entrypoint sh maven:3.9.8
# java -version
openjdk version "21.0.4" 2024-07-16 LTS
OpenJDK Runtime Environment Temurin-21.0.4+7 (build 21.0.4+7-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.4+7 (build 21.0.4+7-LTS, mixed mode, sharing)
# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=24.04
DISTRIB_CODENAME=noble
DISTRIB_DESCRIPTION="Ubuntu 24.04 LTS"
La distribution de l’image est une Ubuntu 24.04 (noble) avec un Java Eclipse Temurin 21.0.4+7.
L’image est en fait maven/3.9.8-eclipse-temurin-21
Nous retrouvons sur le source du Dockerfile et les signatures concordent
Pour garantir la reproductibilité des opérations CI/CD, il serait judicieux de renommer l’image utilisée comme maven/3.9.8-eclipse-temurin-21
image: maven:3.9.8-eclipse-temurin-21
variables:
MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
Vos images CI/CD, votre distribution
Si nous ne trouvons pas d’image de confiance pour un outil, il est recommandé de les produire soi-même, toujours dans une approche de contrôle et de transparence.
Cela peut se faire très simplement :
- Nous créons une image de référence (base image) en partant d’une image Docker officielle
- Cette base image suivra le rythme de l’image d’origine
- Pour profiter des correctifs
- Avec un numéro de version qui identifie celui de l’image d’origine
- Nous créons ensuite une image par outil
- Chaque image outil part de la dernière base image
- Avec un numéro de version qui identifie celui du produit
- Les images outils suivent le rythme de la base image et des produits
- Pour profiter des correctifs
- Avec un numéro de version qui identifie la version de l’outil
Cette activité n’est pas très différente des mainteneurs de distributions, car vous aurez à suivre les évolutions des outils et produire les nouvelles images en conséquence. Ceci demandera une approche produit car vous allez construire votre distribution CI/CD.
Prenons l’exemple de la société NousScalons qui utilise Debian 12.
Ses équipes OPS/SRE/DevSecOps connaissent parfaitement cette distribution et effectuent régulièrement des analyses sur les vulnérabilités.
Le choix a été fait de construire l’image de base à partir d’une image Officielle Debian, appelée bookworm-slim, car c’est une image proche de la production, avec peu de packages, donc d’une taille restreinte et moins de vulnérabilités.
Nous nommeront cette image de base nouscalons:base-YYYYMMDD.
À la sortie de la dernière version de l’image officielle, 202407022, aucune vulnérabilité exploitable n’ayant été détectée, une nouvelle version de l’image de base est créée, elle remplacera l’image de base précédente, nouscalons:base-20240701
Les images CI/CD sont mises à jour dans la semaine pour repartir de cette nouvelle base, nouscalons:base-20240722.
Conclusion
Il faut être attentif à toutes les images qui tournent sur vos chaînes de CI/CD.
Vous devez pouvoir remonter aux sources et dans certains cas pourrez être amené à produire vos propres images de confiance, une activité de ‘Distribution’ interne qui peut être consommatrice en temps, mais qui vous garantira que tous les exécutables qui ont accès à vos sources et binaires sont parfaitement identifiables et identifiés.
La confiance n’exclut pas le contrôle.