Stocker et vérifier ses images de container
Lecture 12 min. âą
Table des matiĂšres

Bonjour Ă toutes et tous
Aujourdâhui je vais ouvrir une boĂźte Pandore đ§
Depuis quelques mois, je me suis plongĂ© profondĂ©ment dans lâĂ©cosystĂšme du cloud native, Docker, images, containers et Kubernetes.
JusquâĂ maintenant je ne mâĂ©tais pas rĂ©ellement prĂ©occupĂ© de la sĂ©curitĂ© de ce que je faisais.
Mes images Ă©taient basĂ©es sur les images officielles que lâon pouvait trouver sur docker hub et je les considĂ©rais comme sĂ©curisĂ©es.
Ce que je nâavais pas compris ou fait semblant de ne pas comprendre, câest que les images sont une reprĂ©sentation figĂ©e de lâĂ©tat dâun systĂšme de fichier. Et donc par consĂ©quent les failles de sĂ©curitĂ© ne sont pas corrigĂ©es, il faut sans cesse vĂ©rifier si de nouvelles images sont crĂ©es et encore on est complĂštement dĂ©pendant du bon vouloir des Ă©diteurs dâimages pour les sĂ©curiser.
Dans cet article, je vais vous proposer deux maniĂšres de vĂ©rifier le niveau de sĂ©curitĂ© de vos images Docker. La premiĂšre mĂ©thode se fera sur le site Gilab.com et la deuxiĂšme via un projet open-source qui peut sâauto-hĂ©berger poussĂ© par VMware.
Pour chacune des deux maniĂšres je vais vous montrer comment les mettre en place, pour bĂ©nĂ©ficier dâune automatisation vĂ©rification des images qui seront poussĂ©s sur le registry Docker.
Câest parti ! :D
Méthode Gitlab.com
Gitlab propose un outil de vĂ©rification de containers et dâimages directement intĂ©grĂ© au sytĂšme de CI.
Pour cela, il vous faut un compte sur gitlab.com, celui ci est gratuit et vous permet de bĂ©nĂ©ficier de fonctionnalitĂ©s avancĂ©es qui ne sont disponibles normalement que dans les paliers payants dâabonnements.
Dans ces fonctionnalitĂ©s nous avons par exemple, la visualisation des failles de sĂ©curitĂ© dans lâinterface de contrĂŽle des merge-requests.
Je considĂšre que vous savez crĂ©er un projet sur Gitlab, dans le cas contraire la documentation est extrĂȘmement fournie.
Dans ce projet à la racine vous aller créer 2 fichiers
Dockerfile
FROM ubuntu:20.04Ce sera celui qui sera utilisĂ© pour construire lâimage que lâon dĂ©sire tester.
.gitlab-ci.yml
variables:
DOCKER_DRIVER: overlay2
stages:
- build
- test
build:
image: docker:stable
stage: build
services:
- docker:19.03.12-dind
variables:
IMAGE: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA
script:
- docker info
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
- docker build -t $IMAGE .
- docker push $IMAGE
include:
- template: Container-Scanning.gitlab-ci.ymlCe pipeline est composé de deux étapes:
- une Ă©tape de build et de push de lâimage dans le registry Docker de Gitlab
- une étape de réalisation des opérations de vérifications
LâĂ©tape de vĂ©rification est entiĂšrement contenue dans la ligne surlignĂ©e.
Elle inclue tout la logique du systÚme de contrÎle de sécurité.
Aujourdâhui celui-ci est basĂ© sur un projet nommĂ© Clair. Mais dans lâavenir si le systĂšme change, votre pipeline nâaura pas besoin dâĂȘtre modifiĂ©.
Pour tester le systÚme, créez une branche peut importe le nom, je vais appeler la mienne dev.
Créez ensuite une merge-request de dev sur master.
Allez sur la branche dev
Modifiez le Dockerfile
FROM ubuntuPuis committez les changements.
AprĂšs un petit moment vous devriez voir apparaĂźtre dans votre merge-request, une nouvelle ligne qui vous indique le nombre de failles.
Ici lâimage busybox:latest ne contient ( et heureusement ) aucune failles de sĂ©curitĂ©s

Il est possible de visualiser le dĂ©tail de ces vulnĂ©rabilitĂ©s en cliquant sur le bouton âView full reportâ.

On peut essayer avec plusieurs images:
ubuntu:21.04

De mĂȘme, occupe vulnĂ©rabilitĂ© Ă dĂ©plorer :D
ubuntu:20.04

On voit déjà quelques vulnérabilités mais elles sont considérées comme modérées.
On peut visualiser le dĂ©tail dâune CVE en particulier en cliquant sur le bouton information (flĂšche rouge)

Une description de lâexploit vous indique lâimpact de la faille sur le systĂšme.
A vous de juger si lâimage doit ĂȘtre ou non corrigĂ©e.
tomcat:10.0-jdk11-openjdk
Commençons par une image particuliÚrement vulnérable

On est sur un nombre trÚs importants de vulnérabiltés (106)!
Il est vivement recommandé de patcher ces vulnérabilités.
Comme pour tout Ă lâheure on peut vĂ©rifier les dĂ©tails.

tomcat:10.0-jdk11-corretto

Modifier lâimage de base permet de diminuer de maniĂšre drastique les failles de sĂ©curitĂ© prĂ©sentes dans lâimage.
Il y en a toujours mais elles sont bien moins nombreuses et bien moins dangeureuses quâavec la version openjdk basĂ©e sur debian 10.
Et câest Ă peu prĂšs tout ce que vous devez faire sur Gitlab.com pour avoir lâassurance de la sĂ©curitĂ© de vos images.
AprĂšs tout systĂšme est imparfait, Clair se base sur une base de donnĂ©es limitĂ© pour vĂ©rifier les diffĂ©rentes CVE et comme celles-ci apparaissent tous les jours câest une course perdue dâavance. Tout ce quâon peut faire câest limitĂ© les risques.
Passons à la seconde méthode. :)
Méthode Harbor
Harbor est un service de registry dâimages de container et de charts helm.
Le projet est opensource, gratuit, permet de pouvoir stocker, vérifier et distribuer ses images.
Il dispose aussi dâun systĂšme dâACL assez poussĂ© et de tout un tas de fonctionnalitĂ© sympas.
Lâune dâelle va nous intĂ©resser tout particuliĂšrement: il sâagit de lâintĂ©gration Trivy.
Comme son github lâindique, le rĂŽle de Trivy est de scanner les vulnĂ©rabilitĂ©s des containers et de rĂ©aliser un rapport dĂ©taillĂ© et lisible afin quâun humain puisse comprendre les problĂšmes et les fixer si besoin est.
Exactement comme pour la méthode gitlab.
Mais vous vous demandez surement pourquoi je vous parle de Harbor alors que le scan des images est trĂšs facile sur Gitlab.
Et bien, il y a une subtilité : en version auto-hébergée, Gitlab gratuit propose bien le scan des images mais pas la jolie interface de rapport.
Tout ce que vous aurez dans lâinterface de votre merge request câest un lien pour tĂ©lĂ©charger le rapport au format JSON.
Mais on doit se lâavouer câest presque inutilisable, surtout lorsque le nombre de vulnĂ©rabilitĂ©s est grand.
On sait dâexpĂ©rience que si un outil nâest pas pratique on ne lâutilise pas. Et ce fichier JSON Ă tĂ©lĂ©charger est lâexemple type !
Câest pour cette raison je propose dâinstaller le service Harbor.
Installer Harbor
Heureusement pour nous Harbor est trĂšs facile Ă installer. Il se prĂ©sente sous une collection dâimages docker rassemblĂ© sous un docker-compose.
Les prĂ©-requis sont donc dâavoir une machine possĂ©dant docker et docker-compose.
Il vous faut aussi un nom de domaine, soit vous avez un enregistrement DNS soit vous modifiez votre /etc/hosts.
Je ferai mon installation sur une ubuntu 20.04.
Vous pouvez récupérer la derniÚre release sur cette page.
La version online est infiniment plus lĂ©gĂšre que la offline et donc je propose de lâutiliser, le rĂ©sultat sera le mĂȘme de toute façon. :)
Avant tout on va récupérer un certificat.
Si vous nâavez pas de nom de domaine rĂ©el, vous pouvez utiliser un certificat auto-signĂ©, mais attention, vous risquez dâavoir des alertes de sĂ©curitĂ© pour plusieurs choses.
Nous allons prĂ©fĂ©rer lâutilisation de Letâs Encrypt qui permet dâobtenir des certificats signĂ©s par une autoritĂ© et donc parfaitement reconnu sans les problĂšmes de sĂ©curitĂ©s dont je vous ai mentionnĂ© lâexistence plus haut.
Pour cela il existe un utilitaire extrĂȘmement pratique nommĂ© certbot.
On lâinstalle.
snap install certbot --classicJâutilise snap car le package apt est Ă une version bien infĂ©rieure.
VĂ©rifiez bien que votre nom de domaine rĂ©sout bien lâIP de votre serveur harbor.
Vous pouvez vous aidez de:
nslookup harbor.example.comEnsuite on génÚre le certificat
certbot certonly -m me@example.com --agree-tos --standalone -d harbor.example.comAprĂšs quelques instants vous devriez
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/harbor.example.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/harbor.example.com/privkey.pem
Your certificate will expire on 2021-07-10. To obtain a new or
tweaked version of this certificate in the future, simply run
certbot again. To non-interactively renew *all* of your
certificates, run "certbot renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-leTéléchargez la release:
wget https://github.com/goharbor/harbor/releases/download/v2.2.1/harbor-online-installer-v2.2.1.tgzModifier la version si besoin est.
DĂ©compressez lâarchive
tar xzvf harbor-online-installer-v2.2.1.tgz -C /optCopiez le fichier de configuration
cp /opt/harbor/harbor.yml.tmpl /opt/harbor/harbor.ymlModifier le fichier /opt/harbor/harbor.yml.
Pour faire correspondre Ă votre nom de domaine et aux chemins des certificats.
hostname: harbor.example.com
https:
port: 443
certificate: /etc/letsencrypt/live/harbor.example.com/fullchain.pem
private_key: /etc/letsencrypt/live/harbor.example.com/privkey.pemVous pouvez aussi modifier les mots de passes, je vais les laisser tel quel mais en production câest Ă©videmment une trĂšs mauvaise idĂ©e !!
Nous allons installer Harbor avec 3 composants supplémentaires:
- chartmuseum : permet de stocker les helm chart de Kubernetes
- notary : signature des layers
- trivy : notre scanner dâimages
cd /opt/harbor
./install.sh --with-notary --with-trivy --with-chartmuseumCe script à pour rÎle de télécharger les images docker de Harbor, de configurer tout ce qui est à configurer et de lancer le tout.
AprĂšs quelques instants, vous pouvez vous rendre sur https://harbor.example.com.
Connectez vous avec les identifiants:
Par défaut:
user: admin
password: Harbor12345
Vous arrivez sur lâinterfaces des projets, dans le jargon de Harbor, le projet est une isolation qui permet de limiter les accĂšs aux images Ă un certain nombre dâutilisateurs.
Par défaut un projet library est déjà présent.
Cliquez sur le lien en bleu library.

Dans configuration coché la case Automatically scan images on push
Ceci va permettre de lancer automatiquement des scan de sécurité des images.

On va créer un utilisateur robot qui nous permettra de pousser nos images sur le repository.
- Cliquez dans la side-bar sur
Robot accounts. - Cliquez sur
New Robot Account - Donnez un nom Ă votre compte. Modifiez lâexpiration du token si besoin
- Donnez les droits au robot sur le projet
library

Le token ne sera plus remontrĂ©. Stockez-le quelque part. Il va ĂȘtre rĂ©utilisĂ© tout de suite.

Et pour la forme je vous montre que trivy tourne bien ^^

Configurer Gitlab
On va modifier notre pipeline Gitlab défini à la partie précédente.
Tout dâabord on se créé une nouvelle branche dĂ©rivĂ©e de master.
puis on modifie ainsi le docker-compose.yml
stages:
- build
build:
stage: build
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
variables:
IMAGE: ubuntu:21.04
REGISTRY: harbor.laforge.works
script:
- cat $HARBOR_ROBOT_AUTH_FILE > /kaniko/.docker/config.json
- |
/kaniko/executor \
--context=$CI_PROJECT_DIR \
--dockerfile=$CI_PROJECT_DIR/Dockerfile \
--destination=$REGISTRY/library/$IMAGE \
--build-arg=IMAGE=$IMAGEOn utilise un projet appelé kaniko, celui ci remplace avantageusement le runtime docker par une solution plus rapide, plus légÚre moins contraignante et plus sécurisée.
En effet, kaniko, ne nécéssite pas de container privilégié pour construire les images puis les pousser dans un registry, ici pour nous notre Harbor.
On modifie aussi notre Dockerfile.
ARG $IMAGE=busybox:latest
FROM $IMAGECette modification permet de ne changer lâimage que dans la variable de lancement du pipeline.
Il nous manque juste lâauthentification de notre robot sur harbor.

Rendez-vous dans lâinterface de gestion des varaibles de CI/CD.
Et ajoutez une nouvelle variable.

Dans le champ
keyindiqué la chaßne de caractÚresHARBOR_ROBOT_AUTH_FILE.Dans
value
Remplissez la avec:
{
"auths":{
"harbor.example.com":{
"username":"robot$$gitlab",
"password":"***********************"
}
}
}Modifiez harbor.example.com par le domaine de votre instance Harbor et le veillez bien Ă doubler le symbole dollar $$ sinon la deuxiĂšme partie sera considĂ©rĂ© comme une variable dâenvironnement.
Modifiez le type par
File.Décochez le
Protect variableAjoutez la variable.
Câest bon on est prĂȘt Ă tester notre pipeline :D
Tests des images

Pour lancer un pipeline de construction et dâupload de notre image, vous devez vous rendre dans la section CI/CD -> Pipelines de notre projet Gitlab.

Puis
- Modifier la branche utiliser comme source
- Ajouter une varible appelée
IMAGE - Ajouter un nom dâimage Ă construire ici par exemple:
busybox:latest - Lancer votre pipeline
AprĂšs quelques instants vous pouvez retourner sur Harbor dans le projet library.

Vous y trouverez une image busybox, et comme vous le constatez 0 vulnérabilté à constater.

ubuntu:21.04
RĂ©itĂ©rez les steps du dessus avec comme lâimage ubuntu:21.04 comme valeur de IMAGE

Comme pour les checks Gitlab, aucune vulnérabilité à signaler.
ubuntu:20.04
On essaie avec une ubuntu:20.04.

Cette fois, pour lâimage ubuntu:20.04 on voit un M jaune. Cela signifie que lâimage possĂšde des vulnĂ©rabilitĂ©s de sĂ©vĂ©ritĂ© modĂ©rĂ©es.
En cliquant sur le sha1 de lâubuntu:20.04 on peut visualiser les dĂ©tails des vulnĂ©rabilitĂ©s.

Comme on peut le voir, chaque vulnérabilité possÚde sa CVE et donc le détail du problÚme de sécurité.

Avec la flĂšche on peut mĂȘme bĂ©nĂ©ficier dâun abstract du problĂšme.
tomcat:10.0-jdk11-openjdk
Allons y pour notre image trouée la tomcat:10.0-jdk11-openjdk
Elle nous donne le résultat suivant

Et les dĂ©tails sont encore plus alarmants⊠đš

Le rĂ©sultat est clair, il ne faut pas utiliser sous aucun prĂ©texte cette image en production! đĄ
tomcat:10.0-jdk11-corretto
Réparons tout ça avec la tomcat:10.0-jdk11-corretto

Ouf :D
Sur Harbor il existe tout un systĂšme de Harbor de webhooks, je planche actuellement sur une intĂ©gration Mattermost pour mâavertir lorsquâune vulnĂ©rabilitĂ© apparaĂźt sur une image.
Je ferai un article sur le sujet quand jâaurai un peu plus avancĂ© ^^
Conclusion
Cet article devait ĂȘtre court et ce ne fut pas le cas đ
Ce que je vous est montrĂ© aujourdâhui je lâutilise dĂ©sormais tous les jours.
Dans un prochain article sur la sĂ©curitĂ©, je vous expliquerai comment crĂ©er des images extrĂȘmement lĂ©gĂšres et donc avec une surface dâattaque extrĂȘmement rĂ©duite.
Cette mĂ©thode sâappelle le multi-stage building et lâutilisation de scratch comme base.
Je vous remercie de mâavoir lu et je vous dis Ă la prochaine :)