2.5 · Sécurité de base : non-root, secrets et scan

Niveau 2 · Dockerfile & build

2.5Sécurité de base : non-root, secrets et scan

Objectif : Durcir une image : utilisateur non-root, aucun secret embarqué, vulnérabilités scannées.
Temps estimé : 12 min · lecture autonome · Si vous n'avez que 5 min : lisez « L'essentiel en 30s » + le schéma.

L'essentiel en 30 secondes

  • Non-root systématique : le conteneur tourne en root par défaut — deux lignes (USER dédié) changent tout.
  • Zéro secret dans l'image : COPY ou ENV figé reste lisible dans l'historique et part au push — injecter au run, jamais au build.
  • Bases officielles + scan rythmé : slim à jour, CVE scannées, rebuild régulier — la sécurité est un rythme, pas un état.

Mini-cas filé — Idir et l'image qui tournait en root

Dernier acte : l'image configurable d'Idir (2.4) est prête, mais elle tourne en root, un fichier de variables traînait dans le contexte, et personne n'a jamais scanné les couches. Idir durcit : base slim officielle, utilisateur dédié (celui fourni par l'image officielle), propriété ajustée au build, vérification via exec + whoami — ce n'est plus root. Il exclut les fichiers sensibles du contexte (.dockerignore), injecte la config au run, puis scanne et met la base à jour. Le niveau 2 est livré : emballé, optimisé, versionné, configurable, durci.

Épilogue du fil rouge 2.1-2.4 : l'app d'Idir tourne non-root, sans secret, scannée — prête pour Compose (niveau 3).

1. Ne plus tourner en root

Par défaut, le processus du conteneur est root : en cas de faille, l'impact est maximal. On crée un utilisateur dédié (l'utilisateur fourni par l'image officielle comme node, propriété ajustée au build) et on déclare USER avant le CMD : deux lignes, un monde de différence. On vérifie avec exec … whoami : on doit voir l'utilisateur dédié, pas root. Idir ajoute USER et contrôle : fini le root « pour simplifier ».

2. Zéro secret dans l'image

Un secret COPY ou ENV dans le Dockerfile reste lisible dans l'historique des couches et part au push avec l'image. On l'injecte au run (variable -e, fichier monté, secret managé) et on l'exclut du contexte (.dockerignore). Ce qui n'est jamais commité ni embarqué ne fuitera jamais du registre. Idir retire tout secret du Dockerfile et du contexte : la config sensible voyage hors image.

3. Scanner avant de déployer

docker scout (ou Trivy/Grype) liste les CVE des couches avec leur gravité. Réflexe : partir de bases slim officielles, mettre à jour les tags, reconstruire régulièrement — une image de 6 mois accumule les failles. En production, une variable au run reste visible via inspect : on préfère les secrets managés (fichiers, orchestrateur, coffre). Idir scanne, met à jour, rebuild, rescanne : la sécurité est un rythme.

Erreur d'interprétation fréquente : « USER casse mes permissions, je reviens à root ». Non : on ajuste la propriété au build (chown) ou on aligne l'UID au run, on ne réouvre pas la porte. La règle d'Idir : USER dédié systématique, permissions réparées proprement, vérification whoami — root n'est jamais la solution.
Une image durcie Moindre base, utilisateur dédié, aucun secret, scan régulier Base slim officielle Moindresurface, tags à jourUSER non-root Utilitairedédié, whoami vérifiéScan + rebuild CVEtraitées, rythme régulier
Moindre base, utilisateur dédié, aucun secret, scan régulier
Version texte du schéma (SEO / lecteurs d'écran / traduction) : 1) Idir RÉDUIT : base slim officielle à jour — moindre surface attaquable. 2) Il DÉGRADE : USER dédié déclaré avant CMD, propriété ajustée au build, whoami vérifié via exec — plus de root. 3) Il PROTÈGE : secrets exclus du contexte et injectés au run, image scannée (CVE), rebuild régulier. Leçon : non-root + zéro secret + scan rythmé, c'est le socle avant la prod.

🔎 Exemple concret — 🔎 Exemple concret — Durcir l'app Node

L'app d'Idir, version durcie et vérifiée :

FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
RUN chown -R node:node /app
USER node
EXPOSE 3000
CMD ["node", "server.js"]

docker scout quickview mon-app:1.0
docker exec -it app whoami   # → node, pas root

Lecture : l'appli tourne en « node », les couches sont scannées, le port reste déclaré et publié au run.

Leçon : le .dockerignore a exclu les fichiers sensibles avant même le build — aucun secret embarqué.

Vocabulaire de la section

USER
L'utilisateur d'exécution déclaré dans le Dockerfile (avant CMD) : le conteneur ne tourne plus en root.

Exemple simple : Idir déclare USER node avant de démarrer son app.

Ce que ce n'est pas : le propriétaire du dépôt de code.

Réflexe : USER dédié avant CMD, toujours.

Secret
Mot de passe, clé, token : information sensible qui ne doit JAMAIS entrer dans l'image ni le dépôt.

Exemple simple : Idir injecte la config sensible au run, jamais au build.

Ce que ce n'est pas : un simple réglage comme le port.

Réflexe : sensible = hors image, hors git.

CVE
Une référence publique de vulnérabilité connue, avec sa gravité : ce que les scanners listent couche par couche.

Exemple simple : Idir note les CVE critiques de son scan et met la base à jour.

Ce que ce n'est pas : une erreur de configuration du Dockerfile.

Réflexe : scanner = lister les CVE.

Surface d'attaque
Tout ce qui est embarqué et attaquable dans l'image : on la réduit (slim, multi-stage, rebuild).

Exemple simple : Idir livre en slim sans SDK : moins d'embarqué, moins d'exposition.

Ce que ce n'est pas : le nombre de conteneurs lancés.

Réflexe : moins d'embarqué = moins d'exposition.

En pratique — En pratique — Durcir votre image

  1. Ajoutez un USER non-root à votre Dockerfile (avant CMD) et rebuildez.
  2. Vérifiez avec exec + whoami (utilisateur dédié, pas root).
  3. Scannez l'image et notez les CVE critiques.
  4. Mettez la base à jour, rebuildez, rescannez : comparez.
Vos images tournent en non-root, sans secret, avec un scan à jour.

Script prêt à dire — annoncer une image durcie (30 s)

« L'image tourne en utilisateur dédié, vérifié par whoami — plus de root. Aucun secret dedans : la config sensible est injectée au run et exclue du contexte. Base officielle à jour, scan sans critique, rebuild régulier prévu. On peut la pousser et la déployer sereinement. »

À dire en montrant le whoami non-root d'Idir puis le rapport de scan.

Modèle copier-coller — Dockerfile durci non-root

FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
RUN chown -R node:node /app
USER node
EXPOSE 3000
CMD ["node", "server.js"]

Permission cassée

USER casse l'écriture sur un volume : Idir ajuste la propriété au build au lieu de revenir à root.

Fichier sensible embarqué

Variables poussées avec l'image : Idir les retire, .dockerignore + injection au run.

Scan oublié

Image de 6 mois jamais rescannée : Idir met la base à jour, rebuild, rescanne — rythme repris.

Secret au run visible

Variable sensible lisible via inspect : Idir passe aux secrets managés (fichiers, orchestrateur) en prod.

Prudence : Sécurité de base obligatoire : faites tourner vos conteneurs en utilisateur non-root (USER dédié, jamais root « pour simplifier »), n'embarquez JAMAIS de secret dans l'image (ni COPY ni ENV figé : lisible dans l'historique, poussé au registre — injectez au run via secrets managés), partez d'images officielles à jour (slim) et scannez avant chaque déploiement avec rebuild régulier. Un push public est irréversible : contrôlez la visibilité du dépôt avant de pousser.

✓ Bonnes pratiques

  • USER dédié systématique, vérifié par whoami.
  • Bases slim officielles à jour.
  • Rebuild régulier (CVE = rythme).

✗ Pièges fréquents

  • Rester root « pour simplifier ».
  • Committer un fichier de variables avec secrets.
  • Scanner une fois puis oublier.

Points clés à retenir

  • Non-root : USER dédié avant CMD, deux lignes, énorme effet.
  • Zéro secret commité ou embarqué (injecté au run, exclu du contexte).
  • On scanne (CVE), on met à jour, on reconstruit régulièrement.
  • Moindre base officielle = moindre surface d'attaque.

Défi 48h — appliquez demain

Durcissez votre image 1.0 : USER non-root + whoami vérifié, .dockerignore sans fichiers sensibles, scan + mise à jour + rebuild comparé.

Checklist sortie de section
  • Je peux faire tourner une image en non-root (USER + whoami vérifié).
  • Je sais exclure tout secret de l'image et du contexte (injecté au run).
  • Je scanne, mets à jour et reconstruis à rythme régulier.
Auto-évaluation 1-5 : est-ce que whoami répond autre chose que root ?est-ce que mon historique ne contient aucun secret ?

Questions fréquentes

USER casse mes permissions, que faire ?

Souvent un volume monté en root : ajustez la propriété (chown) au build ou alignez l'UID au run. Ne revenez pas à root par facilité : réparez la permission proprement et revérifiez avec whoami.

ENV avec mot de passe au run, est-ce sûr ?

Mieux que dans l'image, mais visible via inspect : en production on préfère les secrets managés (fichiers montés, orchestrateur, coffre). Le run n'est qu'une étape, pas une protection.

Vérifiez votre compréhension

Quelle image fuitera un secret au push ?

Ressources supplémentaires (optionnel, pour aller plus loin)

Examen du niveau 2Questions inédites et durcies pour valider vos acquis