Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Images sûres : petites, sans root, sans secret

Après cette leçon: Je peux dire ce qui rend une image sûre à livrer et corriger un Dockerfile peu sûr.

Leçon de 55 min6 commandesLab Docker : apprendre conteneurs, journaux et redémarrages en réparant un service en panne

Un défaut dans le serveur d’une petite boutique

Une image sûre à livrer tourne sous un utilisateur ordinaire, reste petite, fixe sa version et ne contient aucun secret. Chaque point réduit les dégâts d’une attaque.

Quelqu’un trouve un défaut dans le programme qui sert les pages d’une boutique. Il peut maintenant lui faire faire des choses.

Ce qu’il peut atteindre ensuite dépend de l’utilisateur sous lequel tourne le programme. Cela dépend aussi de ce qu’il y a d’autre dans l’image, et de ce qui y est écrit.

À la fin de cette leçon

Remarque

Je peux dire ce qui rend une image sûre à livrer et corriger un Dockerfile peu sûr.

Mots-clés

MotCe que ça veut direExemple
Rootl’utilisateur qui peut tout changer sur le systèmeuid=0
Utilisateur ordinaireun utilisateur aux droits limités
Étiquette fixéeune étiquette d’image qui nomme une seule version exactenginx:1.27-alpine
Secretun mot de passe ou une clé que seul le programme doit connaître
Surface d’attaquetout ce qu’il y a dans une image qu’un attaquant pourrait utiliser

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Tourner sous un utilisateur qui peut peu

Sauf consigne contraire, le programme d’un conteneur tourne en root. Root peut changer tout fichier où le conteneur peut écrire, y compris un volume monté.

Un utilisateur ordinaire ne le peut pas. Si le programme est attaqué, les dégâts restent plus petits. Comparez les deux services principaux de votre labo.

Sous quel utilisateur web tourne-t-il ?

Commande
docker exec web id

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Sous quel utilisateur cache tourne-t-il ?

Commande
docker exec cache id

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Laisser cache essayer d’écrire dans /etc

Commande
docker exec cache touch /etc/probe

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Laisser web essayer la même chose

Commande
docker exec web touch /etc/probe

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Créer un utilisateur dans un Dockerfile

Code: bash
FROM python:3.12-alpine
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
RUN adduser -D -u 10001 shop
USER shop
CMD ["python", "app.py"]

Une erreur fréquente

Attention

On croit souvent que root dans un conteneur n’a pas d’importance, puisque le conteneur est cloisonné. Les cloisons ont des failles, et un volume monté contient de vraies données. Ajoutez un utilisateur et passez à lui avec USER, comme le fait le cache du labo.

Moins dans l’image, moins à attaquer

Chaque programme d’une image est une faille possible de plus. Chaque outil est un outil de plus pour un attaquant.

Une base légère comme une image Alpine en contient bien moins. L’étiquette décide quelle version vous recevez. Une étiquette comme latest bouge : une reconstruction le mois prochain peut donner une autre image.

Exemple travaillé : deux étiquettes d’une même image

ÉtiquetteTaille sur notre machine de testCe que cela veut dire
nginx:1.27284 Moun système complet dessous
nginx:1.27-alpine76,8 Moun petit système dessous
nginx:latestnon mesuréece qui est le plus récent à la construction

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Quelle étiquette cache fixe-t-il ?

Commande
docker inspect --format '{{.Config.Image}}' cache

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Un secret écrit dans une image y reste

Une image se partage. On la pousse vers un registre, on la copie sur des serveurs, on la donne à des collègues. Tout ce qui est dans une couche part avec elle.

Un mot de passe dans un Dockerfile reste dans les couches pour toujours, même si une étape suivante supprime le fichier. Gardez les secrets hors de l’image et donnez-les au conteneur au démarrage.

Un Dockerfile avec un secret, à éviter

Code: bash
FROM alpine:3.20
ENV API_KEY=abc123-not-real
RUN echo hello

Exemple travaillé : où un secret est apparu

Comment il a été régléOù nous l’avons reluCe qui s’est affiché
ENV dans le Dockerfiledocker history --no-truncla ligne ENV API_KEY=abc123-not-real
-e au démarrage du conteneurdocker inspect, Config.EnvDB_PASSWORD=hunter2 dans la liste
Ni l’un ni l’autrerien dans l’image ni les réglagesun secret donné au moment du lancement

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Lire tout ce qu’on a dit à cache

Commande
docker inspect --format '{{json .Config.Env}}' cache

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Pour aller plus loin

Prenez le Dockerfile qui contient un secret. Réécrivez-le pour qu’il fixe son étiquette, tourne sous un utilisateur et ne contienne aucun secret.

Lancez ensuite les trois fonctions du devoir sur l’ancienne version et sur la vôtre. La nouvelle doit sortir propre.

À propos de ce labo et de sa source: Lab Docker : apprendre conteneurs, journaux et redémarrages en réparant un service en panne

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.