Limites fondamentales de l'isolation des conteneurs
La conteneurisation est devenue la méthode dominante pour conditionner et fournir des applications dans les architectures cloud et microservices. Les conteneurs permettent de regrouper le code, les bibliothèques et les dépendances, ce qui garantit une portabilité et une efficacité opérationnelle élevées.
Cependant, la migration massive des charges de travail critiques vers les conteneurs fait de la résilience des mécanismes d'isolation une préoccupation fondamentale. Les recherches et les enquêtes menées auprès des équipes DevOps et de sécurité montrent régulièrement que la sécurité des conteneurs reste l'une des principales préoccupations : les vulnérabilités du noyau et du temps d'exécution, ainsi que les erreurs de configuration, conduisent régulièrement à des brèches d'isolation dans le monde réel.
La question clé est la suivante : l'isolation des conteneurs est-elle absolue ?
La réponse est non, et la raison réside dans leur architecture. Dans cet article, nous allons approfondir cette question et explorer les mesures disponibles pour atténuer les risques de vulnérabilité.
Conteneurs et machines virtuelles : le noyau partagé
Machine virtuelle (VM) :
-
Chaque VM exécute son propre noyau d'OS, complètement séparé de l'hôte.
-
L'isolation est assurée par un hyperviseur (KVM, Xen, ESXi, etc.).
-
Une attaque doit généralement cibler l'hyperviseur, ce qui réduit considérablement les vecteurs d'attaque.
Conteneurs :
-
Un conteneur est un processus isolé à l'aide des primitives du noyau Linux (espaces de noms, cgroups, etc.).
-
Un conteneur ne contient que l'espace utilisateur (bibliothèques, moteur d'exécution, application) mais partage un noyau avec l'hôte et les autres conteneurs.
-
Toute vulnérabilité critique du noyau devient automatiquement un vecteur d'attaque potentiel pour tous les conteneurs du nœud.
Le choix architectural d'un noyau partagé est ce qui rend l'isolation des conteneurs fondamentalement non absolue : l'exploitation réussie d'une vulnérabilité du noyau permet à un attaquant de contourner les limites de n'importe quel espace de noms.

Le rôle des espaces de noms et des Cgroups dans la création de l'isolation
Le fondement de l'isolation des conteneurs sous Linux repose sur les espaces de noms et les groupes de noms.
-
Espaces de noms - Isolation de la vue du système : PID, Mount, Network, User, IPC, UTS et autres. Les processus ne "voient" que leur propre espace : leur système de fichiers, leur PID, leur nom d'hôte et leur réseau.
-
Cgroups - Contrôle et limitation des ressources : CPU, mémoire, E/S, nombre de processus, etc.
Les espaces de noms créent l'illusion d'un système séparé, et les Сgroups empêchent un conteneur d'accaparer les ressources de l'hôte. Cependant, il est essentiel de noter que les espaces de noms sont un mécanisme d'isolation, et non un mécanisme de sécurité à part entière contre le contournement délibéré des barrières. Ils n'empêchent pas l'exploitation des vulnérabilités du noyau, ne résolvent pas les problèmes liés aux privilèges root excessifs ou aux conteneurs privilégiés, ne filtrent pas les appels système et ne gèrent pas les politiques d'accès.
Par conséquent, les espaces de noms et les Сgroups ne sont qu'une couche de base qui doit être renforcée :
-
le filtrage des appels système (Seccomp)
-
des politiques MAC (AppArmor/SELinux)
-
Restrictions de capacité
-
Idéalement, espaces de noms d'utilisateurs + mode sans racine
Sécurité des plateformes de conteneurs : menaces critiques et vecteurs d'attaque
La surface d'attaque d'une plateforme de conteneurs est multicouche. Les principales surfaces suivantes peuvent être identifiées :
-
Exécution et noyau (runc, containerd, CRI-O, noyau Linux).
-
Chaîne d'approvisionnement en images.
-
Configuration des conteneurs et des orchestrateurs.
-
Cloud et infrastructure (IAM, API, stockage, réseau).
Aperçu des vecteurs d'attaque et des vulnérabilités critiques : Évasion de conteneurs

Les vecteurs typiques dans un environnement de conteneur comprennent : l'exploitation d'un CVE dans le noyau Linux ou le runtime du conteneur ; l'utilisation d'images non sécurisées (paquets périmés, kits d'exploitation) ; les erreurs de configuration dans Kubernetes/Docker (privilèges excessifs, montage du système de fichiers de l'hôte, pile réseau de l'hôte) ; et la compromission du registre et de la CI/CD.
Il est important de comprendre qu'une évasion de conteneur est souvent une combinaison de facteurs :
Vulnérabilité du noyau/du runtime + mauvaise configuration (exécution en tant que root, --privilège, montage du système de fichiers de l'hôte, MAC/Seccomp manquant).
Vulnérabilités de la chaîne d'approvisionnement
La chaîne d'approvisionnement des images de conteneurs est l'un des principaux risques, car les images de base provenant de registres publics contiennent souvent des CVE connus. Les dépendances (modules pip/npm/gem/go) sont tirées de manière transitoire et ne sont pas toujours contrôlées. Plus dangereux encore, les logiciels malveillants peuvent être "dormants" et ne se manifester qu'au moment de l'exécution.
Par conséquent, les meilleures pratiques suivantes sont obligatoires en production :
-
Analyse d'images pour les CVE, à l'aide d'outils tels que Trivy, Clair, Grype, etc.
-
Utilisation de registres avec application de politiques, tels que Harbor, Quay ou GHCR.
-
Signature et vérification de l'image avant le déploiement.
Erreurs de configuration et conteneurs privilégiés
L'erreur la plus commune qui ouvre largement la porte aux vulnérabilités est l'exécution de processus à l'intérieur du conteneur en tant que root ! Si l'application dans le conteneur est lancée avec des droits de superutilisateur, lors de la compromission du conteneur, l'attaquant obtient le statut de superutilisateur à l'intérieur du conteneur. Une évasion réussie à l'extérieur du conteneur simplifie alors considérablement l'escalade vers la racine de l'hôte.
Interdire le lancement d'applications en tant que superutilisateur et utiliser des UID/GID non privilégiés est la règle de base d'un durcissement adéquat.
Les conteneurs privilégiés utilisant l'option --privileged désactivent pratiquement les principaux mécanismes d'isolation, en particulier certains Cgroups, AppArmor/SELinux et les restrictions Seccomp. Cela donne au conteneur un accès direct aux périphériques de l'hôte et aux pseudo-systèmes de fichiers (/proc, /sys, /dev, etc.). À partir d'un conteneur privilégié, il est facile de monter les disques de l'hôte et de modifier le système de fichiers et les configurations.
Par essence, un conteneur privilégié équivaut à une escalade intentionnelle des privilèges. N'oubliez pas que cela n'est acceptable que dans des scénarios rares et bien isolés, et certainement pas dans un environnement multi-tenant.
Il existe également des erreurs de configuration "silencieuses" qui peuvent rendre l'environnement du conteneur extrêmement vulnérable, même sans utiliser l'option --privileged. Les plus dangereuses sont les suivantes :
-
Monter hostPath dans des répertoires sensibles de l'hôte, tels que /etc ou /var/run/docker.sock.
-
Accorder des capacités inutiles, par exemple CAP_SYS_ADMIN, qui accorde virtuellement les droits root sur l'hôte.
-
Utilisation injustifiée des modes hostNetwork ou hostPID.
Ces paramètres apparemment mineurs peuvent permettre à un attaquant d'échapper au conteneur et de prendre le contrôle du noyau ou de l'ensemble du système hôte.
Comparaison d'architecture : Docker et Podman
Les différences architecturales entre Docker et Podman influencent directement le modèle de menace. Docker, avec son démon à privilèges élevés, présente le risque principal : un point de défaillance unique.
Docker et le mode "rootful
Dans l'architecture classique, ou standard, de Docker, la CLI de Docker communique avec le démon dockerd via le socket /var/run/docker.sock ou TCP. Le démon dockerd s'exécute en tant qu'utilisateur root et effectue les opérations de base :
-
Création/suppression de conteneurs
-
Construction d'images
-
Gestion des réseaux/volumes
-
Interaction avec les registres
Il s'ensuit qu'un accès direct à l'API Docker équivaut à un accès root presque complet à l'hôte - ce qui permet à un attaquant de monter le système de fichiers, de lancer des conteneurs privilégiés, etc. Dans ce scénario, le démon devient un point de défaillance unique - s'il est compromis, l'attaquant obtient l'accès à l'hôte.
C'est pourquoi Docker exige un contrôle d'accès strict au socket, l'activation obligatoire de MAC et Seccomp, et la restriction des capacités. Il est essentiel de réduire au minimum le nombre d'utilisateurs et de services ayant accès à l'API Docker.
Podman sans démon : l'approche native de Linux
Podman a été développé par Red Hat et la communauté en tant qu'alternative Linux "native" plus sûre. Il a été conçu à l'origine avec une architecture sans démon, ce qui signifie qu'il n'y a pas de démon persistant et centralisé. Au lieu de cela, les conteneurs sont des processus enfants de l'utilisateur qui a exécuté la commande. La base est une intégration profonde avec systemd, où les unités et les services sont créés directement.
Cela élimine le point de défaillance unique présenté par le démon racine et s'aligne mieux sur le modèle Unix traditionnel : "Le processus appartient à celui qui l'a lancé.
Mode sans racine : Les espaces de noms d'utilisateurs comme principale barrière de sécurité
Le mode sans racine est essentiellement la réponse logique au danger fondamental : "Que se passe-t-il si le conteneur s'échappe ?".
Le rôle des espaces de noms d'utilisateurs et l'atténuation des dommages
Les espaces de noms d'utilisateurs isolent l'UID/GID et permettent le remappage de l'UID. Par exemple, si un processus à l'intérieur d'un conteneur a l'UID 0 (root), ce même processus est mappé à un UID non privilégié de la gamme subuid/subgid sur l'hôte.
Par conséquent, même si un attaquant à l'intérieur d'un conteneur a les privilèges de l'utilisateur root et réussit à exploiter une vulnérabilité du runtime/kernel pour s'échapper au niveau de l'hôte, il continue d'opérer en tant qu'utilisateur non privilégié sur l'hôte.
De nombreuses chaînes d'exploitation, y compris runc-escape, sont ainsi interrompues ou ont un impact considérablement réduit. En effet, l'attaquant ne peut pas écraser les binaires/configurations appartenant à l'utilisateur root, ni monter des systèmes de fichiers, ni gérer des périphériques sans capacités, et les politiques MAC continuent également à fonctionner sur l'hôte.
Podman sans racine : Limites et pile réseau
Podman a été conçu dès le départ en mettant l'accent sur les opérations sans racine. Les conteneurs sont créés et gérés par un utilisateur non privilégié, les espaces de noms des utilisateurs sont activés par défaut, et SELinux/AppArmor et Cgroups sont utilisés dans la mesure du possible sans accès root.
Toutefois, ce schéma présente quelques inconvénients. Lorsqu'un conteneur sans racine fonctionne dans la plage subuid/subgid, des erreurs de mappage sont possibles si l'image contient des fichiers dont les valeurs UID/GID se situent en dehors de cette plage.
Un autre inconvénient indirect est qu'un utilisateur non privilégié ne peut pas configurer librement les espaces de noms du réseau. Depuis le début de l'année 2025, Podman utilise les pâtes de pile de l'espace utilisateur pour remplacer slirp4netns. Ce plugin fonctionne entièrement dans l'espace utilisateur, mais grâce à l'interface tap et à l'épissage sans copie, il offre des performances réseau quasi natives. Néanmoins, des ralentissements de performance sont toujours possibles, et sont définitivement garantis si les utilisateurs continuent à utiliser slirp4netns.
Docker sans racine : mise en œuvre et exigences
Docker prend également en charge un mode sans racine à part entière, dans lequel le démon dockerd et les conteneurs sont lancés à l'intérieur d'un espace de noms d'utilisateurs sans les privilèges de l'utilisateur racine de l'hôte. Il est important de noter que ce mode diffère de l'ancienne fonctionnalité userns-remap, dans laquelle le démon lui-même conservait ses privilèges.
Du point de vue de la sécurité, cela garantit qu'une violation du conteneur n'entraînera pas une escalade automatique au niveau de l'utilisateur racine de l'hôte. En cas d'attaque réussie sur dockerd en mode sans racine, seules les ressources de l'utilisateur non privilégié seront accessibles, et non l'ensemble du système.

Le choix entre les modes rootful et rootless est principalement un équilibre entre l'optimisation des performances et la limitation maximale des dommages potentiels en cas de violation.
Conclusions et recommandations en matière de renforcement
L'analyse confirme que l'isolation des conteneurs n'est pas absolue en raison de leur architecture. Comme les conteneurs partagent le noyau du système hôte, les vulnérabilités au niveau du noyau ou de l'exécution peuvent, par définition, "voir" à travers les espaces de noms, violant ainsi les limites de sécurité attendues.
Dans la pratique, la plupart des attaques réussies sont liées à la combinaison d'une vulnérabilité connue (kernel/runc) et d'une configuration faible (root, --privileged, hostPath).
Un modèle de sécurité fiable pour les conteneurs doit être construit comme un système multicouche :
Couche 1 - Segmentation : (namespaces, cgroups)
Couche 2 - Politiques et filtrage : (Seccomp, MAC, capacités)
Couche 3 - Restriction des privilèges architecturaux : (via le mode sans racine et les espaces de noms d'utilisateurs)
Liste de contrôle : renforcement de l'hôte pour les conteneurs Docker et Podman
Sans racine par défaut
Considérer Podman ou Docker en mode sans racine comme le modèle par défaut pour les charges de travail internes et multi-locataires.
Durcissement du noyau et correctifs
Mettez rapidement à jour le noyau (Dirty COW, Dirty Pipe et autres CVE similaires sont presque toujours déjà corrigés par des correctifs). Utiliser des distributions ayant un bon historique de correctifs de sécurité (RHEL, OpenSUSE, Ubuntu LTS, etc.).
Adopter des distributions spécialisées de systèmes d'exploitation immuables
Pour renforcer la sécurité de l'environnement des conteneurs, utilisez des distributions de systèmes d'exploitation immuables telles qu'openSUSE MicroOS ou Flatcar Linux. Leur système de fichiers racine est en lecture seule par défaut, ce qui réduit considérablement la surface d'attaque. Le mécanisme clé est celui des mises à jour atomiques : une nouvelle image du système d'exploitation est créée, et la mise à jour est soit appliquée intégralement, soit annulée, ce qui permet d'éviter la corruption du système et d'accélérer la récupération.
Principe du moindre privilège
N'utilisez jamais l'option --privileged en production, sauf dans des environnements hautement spécialisés et isolés. Évitez d'exécuter des applications dans des conteneurs en tant qu'utilisateur root et utilisez un système de fichiers en lecture seule, l'ensemble minimal de capacités et des profils Seccomp stricts.
Politiques MAC et Seccomp
Activez et configurez SELinux\AppArmor pour les conteneurs. Utilisez les profils Seccomp, idéalement des profils personnalisés basés sur les appels système réels de l'application, et pas seulement les valeurs par défaut de Docker.
Sécurité de la chaîne d'approvisionnement
Mettre en œuvre l'analyse des images de conteneurs. Limiter les sources d'images de base aux registres officiels ou internes et activer la signature et la vérification des images avant le déploiement.
Surveillance de l'exécution
Employer des outils de détection des anomalies et des IDS/EDR de conteneurs (Falco, Sysdig Secure ou Aqua Security) qui peuvent détecter les tentatives d'évasion de conteneurs et surveiller l'exécution de commandes malveillantes. Suivre le trafic réseau atypique, les appels système inattendus et l'accès aux fichiers sensibles.
L'avenir de l'isolation : Kata Containers, gVisor et Micro-VMs
Le mode sans racine réduit considérablement le risque de compromission totale de l'hôte, mais il ne résout pas tout, car des dépendances sur le noyau de l'hôte subsistent et certaines classes d'attaques ne sont pas éliminées.
C'est pourquoi les approches hybrides gagnent en popularité pour les charges de travail critiques :
- Kata Containers: Chaque pod ou conteneur est lancé à l'intérieur d'une micro-VM légère avec un noyau séparé, combinant les avantages des VM et des conteneurs.
- gVisor: Un noyau bac à sable écrit en Go qui agit comme une couche intermédiaire entre l'application et le véritable noyau Linux.
Ces solutions réduisent la dépendance à l'égard du noyau partagé et nous rapprochent du modèle d'isolation des VM tout en préservant la nature déclarative et la commodité des orchestrateurs de conteneurs.
Transformez les conseils de cet article en sécurité réelle lors de votre prochain déploiement.
Obtenez un VPS ou un serveur dédié et commencez à mettre en place une plateforme de conteneurs sécurisée dès aujourd'hui.
Passez à la sélection de la configuration.

Nouveaux articles :
Docker vs. Podman : Un guide complet de la conteneurisation sans démon