Docker users

De wiki.nexiat.fr
Aller à la navigation Aller à la recherche
Fiche express
Type Gestion des identités (UID) entre hôte et conteneurs
Risque principal Exécution par défaut en root (UID 0) dans le conteneur
Mitigation Directive USER dans l'image, ou option -u au lancement
Voir aussi Docker pratiques · Docker rhel7

Un conteneur Docker partage le noyau de l'hôte : un processus qui tourne en root dans le conteneur correspond, sans remappage d'espace de noms utilisateur, à l'UID 0 sur l'hôte. Comprendre comment les UID se propagent entre image, conteneur et hôte est donc une base de la sécurisation des déploiements Docker.

Constat : UID partagé entre hôte et conteneur

Sans configuration particulière, un utilisateur créé dans une image porte le même UID côté hôte et côté conteneur. Deux utilisateurs créés séparément avec le même UID sur l'hôte et dans une image seront donc traités comme le même utilisateur du point de vue du système de fichiers (propriétaire des fichiers, permissions).

useradd -u 1111 user1
useradd -u 1112 user2

Créer une image avec des utilisateurs dédiés

FROM debian:latest

RUN useradd -u 1111 user1
RUN useradd -u 1113 user3
docker build -t myimage:v1.0 .
docker images

Ici, user1 dans l'image partage le même UID (1111) que user1 sur l'hôte : un fichier créé par l'un sera vu comme appartenant à l'autre. En revanche, user3 (UID 1113, présent uniquement dans l'image) n'a pas de correspondance directe côté hôte.

Volumes et propriété des fichiers

Lorsqu'un volume hôte est monté dans un conteneur, les fichiers qui y sont créés héritent de l'UID du processus qui les a écrits — c'est ce comportement qui rend la correspondance d'UID importante en pratique.

mkdir /myvolumes

# Conteneur interactif, exécuté par défaut en root
docker run -d -it --name c1 -v /myvolumes/:/data myimage:v1.0 bash

# Processus de fond, toujours en root
docker run -d --name c1 -v /myvolumes/:/data myimage:v1.0 sleep infinity

# Forcer l'exécution avec un utilisateur non privilégié de l'image
docker run -d --name c1 -v /myvolumes/:/data -u user1 myimage:v1.0 sleep infinity

L'option -u (ou --user) impose l'identité d'exécution du processus principal du conteneur, indépendamment de ce que prévoit l'image. C'est le complément pratique de la directive USER d'un Dockerfile, utile notamment quand on ne maîtrise pas l'image source et qu'on veut malgré tout éviter une exécution en root.

Bonnes pratiques

  • Préférer une directive USER explicite en fin de Dockerfile plutôt que de compter sur l'option -u au lancement (le comportement par défaut de l'image reste alors sûr même si personne ne pense à ajouter -u).
  • Aligner les UID entre hôte et conteneur uniquement quand c'est un besoin réel (partage de volume) : dans le cas contraire, laisser Docker choisir un UID arbitraire limite la surface de correspondance accidentelle avec un compte privilégié de l'hôte.
  • Ne jamais monter un volume sensible de l'hôte (par exemple un répertoire système) dans un conteneur qui tourne en root sans espace de noms utilisateur dédié : voir la section sécurisation des espaces de noms dans Docker pratiques.