Aller au contenu
Sécurité medium

Auditer la sécurité de vos images Docker avec Dockle

15 min de lecture

logo dockle

Dockle détecte les erreurs de configuration dans vos images Docker en vérifiant leur conformité avec le benchmark CIS Docker et les bonnes pratiques de sécurité. Contrairement à Trivy qui scanne les vulnérabilités des paquets, Dockle se concentre sur la construction de l’image : utilisateur root, secrets exposés, cache non nettoyé, absence de HEALTHCHECK. En 30 secondes, vous savez si votre image respecte les standards de sécurité.

  • Installer Dockle sur Linux ou macOS
  • Analyser une image Docker et comprendre les résultats
  • Interpréter les codes CIS (CIS-DI-0001, DKL-DI-0005, etc.)
  • Personnaliser l’analyse avec les options essentielles
  • Intégrer Dockle dans un pipeline CI/CD (GitLab CI, GitHub Actions)
  • Corriger les problèmes les plus fréquents

Dockle est un linter de sécurité pour images Docker. Il vérifie que votre image respecte les recommandations du CIS Docker Benchmark, un standard reconnu en sécurité des conteneurs.

Analogie : Dockle est à votre image Docker ce qu’un contrôle technique est à une voiture. Il ne vérifie pas si le moteur a des pièces défectueuses (vulnérabilités CVE — c’est le rôle de Trivy), mais si la voiture est bien configurée : ceintures présentes, freins fonctionnels, phares réglés.

CatégorieExemples de contrôles
UtilisateurImage qui tourne en root ?
SecretsVariables d’environnement sensibles (PASSWORD, TOKEN) ?
FichiersClés SSH, certificats privés dans l’image ?
CacheCache apt/yum non nettoyé ?
Bonnes pratiquesHEALTHCHECK présent ? Tag latest utilisé ?
OutilAnalyseQuand l’utiliser
DockleConfiguration de l’image finaleAprès le build, avant le push
TrivyVulnérabilités des paquets (CVE)Après le build, avant le push
HadolintSyntaxe du DockerfilePendant l’écriture du Dockerfile
Fenêtre de terminal
VERSION=$(
curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \
grep '"tag_name":' | \
sed -E 's/.*"v([^"]+)".*/\1/'
)
curl -L -o dockle.deb \
"https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Linux-64bit.deb"
sudo dpkg -i dockle.deb && rm dockle.deb

Vérification :

Fenêtre de terminal
dockle --version
# dockle version 0.4.15

La commande de base est simple :

Fenêtre de terminal
dockle NOM_IMAGE:TAG

Exemple avec une image problématique :

Voici un Dockerfile volontairement mal configuré :

FROM ubuntu:latest
ENV ADMIN_PASSWORD=secret123
RUN apt-get update && apt-get install -y curl
EXPOSE 8080
CMD ["echo", "Hello"]

Après construction (docker build -t test-bad:v1 .), le scan Dockle révèle :

Fenêtre de terminal
dockle test-bad:v1
FATAL - CIS-DI-0010: Do not store credential in environment variables/files
* Suspicious ENV key found : ADMIN_PASSWORD on ENV ADMIN_PASSWORD=*******
FATAL - DKL-DI-0005: Clear apt-get caches
* Use 'rm -rf /var/lib/apt/lists' after 'apt-get install|update'
WARN - CIS-DI-0001: Create a user for the container
* Last user should not be root
INFO - CIS-DI-0005: Enable Content trust for Docker
* export DOCKER_CONTENT_TRUST=1 before docker pull/build
INFO - CIS-DI-0006: Add HEALTHCHECK instruction to the container image
* not found HEALTHCHECK statement
INFO - CIS-DI-0008: Confirm safety of setuid/setgid files
* setuid file: urwxr-xr-x usr/bin/passwd
* setuid file: urwxr-xr-x usr/bin/su
[...] # Fichiers système normaux
NiveauSignificationAction
FATALFaille de sécurité critiqueCorriger obligatoirement
WARNConfiguration risquéeCorriger fortement recommandé
INFOAmélioration possibleÉvaluer selon le contexte
PASSContrôle réussiRien à faire
Fenêtre de terminal
dockle --format json test-bad:v1
{
"image": "test-bad:v1",
"summary": {
"fatal": 2,
"warn": 1,
"info": 3,
"skip": 0,
"pass": 10
},
"details": [
{
"code": "CIS-DI-0010",
"title": "Do not store credential in environment variables/files",
"level": "FATAL",
"alerts": [
"Suspicious ENV key found : ADMIN_PASSWORD on ENV ADMIN_PASSWORD=*******"
]
}
]
}

Dockle utilise deux familles de codes :

  • CIS-DI-XXXX : Règles du CIS Docker Benchmark (standard industriel)
  • DKL-DI-XXXX : Règles spécifiques à Dockle (bonnes pratiques)
CodeRègleComment corriger
CIS-DI-0001Ne pas utiliser rootAjouter USER appuser
CIS-DI-0005Activer Content Trustexport DOCKER_CONTENT_TRUST=1
CIS-DI-0006Ajouter HEALTHCHECKHEALTHCHECK CMD curl -f http://localhost/
CIS-DI-0008Vérifier setuid/setgidSupprimer les bits avec chmod
CIS-DI-0010Pas de secrets en clairUtiliser des secrets Docker ou variables d’exécution
CodeRègleComment corriger
DKL-DI-0001Éviter sudoUtiliser USER root puis USER appuser
DKL-DI-0002Éviter fichiers sensiblesAjouter au .dockerignore
DKL-DI-0003Éviter latestUtiliser un tag versionné
DKL-DI-0004Utiliser --no-cache (apk)apk add --no-cache pkg
DKL-DI-0005Nettoyer le cache aptrm -rf /var/lib/apt/lists/*
DKL-DI-0006Utiliser COPY plutôt que ADDRemplacer ADD par COPY

Par défaut, Dockle retourne toujours 0. Pour échouer en CI/CD :

Fenêtre de terminal
# Échoue si WARN ou FATAL détecté
dockle --exit-code 1 mon-image:v1
# Échoue uniquement sur FATAL
dockle --exit-code 1 --exit-level FATAL mon-image:v1

Certaines règles peuvent ne pas s’appliquer à votre contexte :

Fenêtre de terminal
# Ignorer une règle spécifique
dockle --ignore CIS-DI-0005 mon-image:v1
# Ignorer plusieurs règles
dockle -i CIS-DI-0005 -i CIS-DI-0008 mon-image:v1

Dockle détecte automatiquement les variables sensibles (PASSWORD, TOKEN, KEY…). Vous pouvez personnaliser cette détection :

Fenêtre de terminal
# Accepter une variable normalement suspecte
dockle --accept-key GPG_KEY --accept-key CACHE_KEY mon-image:v1
# Ajouter des mots sensibles personnalisés
dockle --sensitive-word api_secret --sensitive-word db_pass mon-image:v1
# Ajouter des fichiers sensibles personnalisés
dockle --sensitive-file .git --sensitive-file .env mon-image:v1
# Ajouter des extensions sensibles personnalisées
dockle --sensitive-file-extension pfx --sensitive-file-extension p12 mon-image:v1
Fenêtre de terminal
# Sortie par défaut (texte coloré)
dockle mon-image:v1
# JSON pour parsing automatisé
dockle --format json mon-image:v1
# SARIF pour outils de sécurité (GitHub Security, SonarQube...)
dockle --format sarif mon-image:v1 > dockle-results.sarif
Fenêtre de terminal
# Depuis un registre (nécessite authentification)
dockle --username user --password pass registry.example.com/mon-image:v1
# Connexion non sécurisée (pour registres internes)
dockle --insecure registry.internal:5000/mon-image:v1
dockle_scan:
stage: test
image: docker:27.5
services:
- docker:27.5-dind
variables:
DOCKLE_VERSION: "0.4.15"
before_script:
- apk add --no-cache curl
- |
curl -L -o /usr/local/bin/dockle \
"https://github.com/goodwithtech/dockle/releases/download/v${DOCKLE_VERSION}/dockle_${DOCKLE_VERSION}_Linux-64bit"
- chmod +x /usr/local/bin/dockle
script:
- docker build -t $CI_PROJECT_NAME:$CI_COMMIT_SHA .
- dockle --exit-code 1 --exit-level WARN $CI_PROJECT_NAME:$CI_COMMIT_SHA
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
name: Dockle Security Scan
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
dockle:
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build image
run: docker build -t app:${{ github.sha }} .
- name: Install Dockle
env:
DOCKLE_VERSION: "0.4.15"
run: |
curl -L -o dockle.deb \
"https://github.com/goodwithtech/dockle/releases/download/v${DOCKLE_VERSION}/dockle_${DOCKLE_VERSION}_Linux-64bit.deb"
sudo dpkg -i dockle.deb
- name: Run Dockle
run: dockle --exit-code 1 --format sarif -o dockle-results.sarif app:${{ github.sha }}
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: dockle-results.sarif

Voici un Dockerfile qui passe tous les contrôles Dockle :

FROM ubuntu:24.04
# Installer les dépendances et nettoyer le cache
RUN apt-get update && \
apt-get install -y --no-install-recommends curl && \
rm -rf /var/lib/apt/lists/*
# Créer un utilisateur non-root
RUN useradd -m -s /bin/bash appuser
WORKDIR /app
# Changer vers l'utilisateur non-root
USER appuser
# Ajouter un healthcheck
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:8080/health || exit 1
EXPOSE 8080
CMD ["./app"]

Résultat Dockle :

Fenêtre de terminal
dockle app-conforme:v1
INFO - CIS-DI-0005: Enable Content trust for Docker
* export DOCKER_CONTENT_TRUST=1 before docker pull/build
INFO - CIS-DI-0008: Confirm safety of setuid/setgid files
* setuid file: urwxr-xr-x usr/bin/passwd
[...] # Fichiers système normaux de l'image de base

Seuls des INFO restent, liés à l’image de base Ubuntu. Aucun FATAL ni WARN.

SymptômeCause probableSolution
FATAL CIS-DI-0010Variable sensible détectéeUtiliser --accept-key ou supprimer la variable
FATAL DKL-DI-0005Cache apt non nettoyéAjouter rm -rf /var/lib/apt/lists/*
WARN CIS-DI-0001Image tourne en rootAjouter USER nonroot
timeout exceededImage trop volumineuseUtiliser --timeout 5m
permission deniedSocket Docker inaccessibleVérifier les droits sur /var/run/docker.sock

Toutes les options peuvent être passées via variables d’environnement :

VariableÉquivalent option
DOCKLE_IGNORES--ignore
DOCKLE_ACCEPT_KEYS--accept-key
DOCKLE_EXIT_CODE--exit-code
DOCKLE_EXIT_LEVEL--exit-level
DOCKLE_OUTPUT_FORMAT--format
DOCKLE_TIMEOUT--timeout
Fenêtre de terminal
export DOCKLE_IGNORES="CIS-DI-0005,CIS-DI-0008"
export DOCKLE_EXIT_CODE=1
dockle mon-image:v1
  1. Dockle analyse la configuration, pas les vulnérabilités — utilisez-le avec Trivy

  2. FATAL et WARN doivent être corrigés avant mise en production

  3. Toujours spécifier --exit-code 1 en CI/CD pour bloquer les images non conformes

  4. Pinnez la version de Dockle dans vos pipelines pour la reproductibilité

  5. Utilisez .dockleignore pour ignorer les règles non applicables à votre contexte

  6. Les codes CIS-DI sont des standards reconnus — leur respect facilite les audits de sécurité

  7. Combinez Hadolint + Dockle + Trivy pour une couverture complète