Blog

Atteindre une véritable isolation multi-locataire dans Docker

Le modèle de noyau partagé de Docker présente des risques pour les environnements multi-locataires. Ce guide fournit des étapes concrètes pour renforcer l'isolation à l'aide des espaces de noms utilisateur, seccomp, AppArmor, des outils de sandboxing et des bonnes pratiques d'orchestration.

Résumé

Les conteneurs Docker partagent le noyau hôte, ce qui peut être un problème de sécurité dans les environnements multi-locataires où les locataires ne se font pas nécessairement confiance. Cet article explique les lacunes d'isolation dans les configurations Docker par défaut et fournit des étapes concrètes pour renforcer l'isolation à l'aide des espaces de noms Linux, cgroups, espaces de noms utilisateur, seccomp, AppArmor et virtualisation matérielle. Vous apprendrez à configurer des démons Docker par locataire, à utiliser des outils de sandboxing comme gVisor ou Firecracker pour une isolation plus forte, et à orchestrer avec Kubernetes pour le multi-locataire. Nous aborderons également le choix du bon fournisseur d'infrastructure offrant une virtualisation basée sur KVM pour une couche de séparation supplémentaire. À la fin, vous aurez un plan pour exécuter des charges de travail multi-locataires sécurisées avec Docker.

Lorsque vous hébergez plusieurs locataires sur un seul hôte Docker, l'isolation par défaut des conteneurs, construite sur les espaces de noms Linux et les cgroups, n'est souvent pas suffisante. Une fuite de conteneur chez un locataire pourrait compromettre l'ensemble de l'hôte et tous les autres conteneurs. Ce problème est particulièrement aigu dans l'hébergement partagé, les plateformes SaaS ou tout scénario où du code non fiable s'exécute à côté du vôtre. La bonne nouvelle : vous pouvez empiler plusieurs techniques d'isolation pour construire un environnement multi-locataire renforcé. Ce guide vous présente six étapes pratiques, des solutions simples comme les espaces de noms utilisateur aux mesures avancées comme les environnements d'exécution en sandbox et les choix d'infrastructure.

Comprendre l'isolation par défaut de Docker

Docker utilise les espaces de noms Linux pour isoler les processus, le réseau, le système de fichiers et d'autres ressources. Les cgroups limitent le CPU, la mémoire et les E/S. Mais ils partagent un seul noyau : une vulnérabilité dans le noyau peut affecter tous les conteneurs. Pour un véritable multi-locataire, surtout avec des locataires non fiables, vous avez besoin d'une défense en profondeur. Comme discuté dans Conception d'une architecture Docker multi-locataire : choisir le bon niveau d'isolation, les niveaux d'isolation vont de faible (espaces de noms uniquement) à fort (virtualisation matérielle). Construisons à partir du plus faible.

Étape 1 : Activer les espaces de noms utilisateur

Par défaut, root à l'intérieur d'un conteneur correspond à root sur l'hôte. Une fuite de conteneur donne un accès complet à l'hôte. Les espaces de noms utilisateur remappent le root du conteneur vers un utilisateur non root à l'extérieur. Activez-le globalement avec dockerd --userns-remap=default ou par conteneur avec --userns=host. Cette simple étape élimine de nombreuses attaques d'escalade de privilèges. Testez vos applications : certaines nécessitant des privilèges au niveau hôte (par exemple, montage de systèmes de fichiers) peuvent échouer. Pour les sites Drupal ou WordPress, c'est généralement sans danger.

Étape 2 : Appliquer les profils Seccomp et AppArmor

Seccomp limite les appels système qu'un conteneur peut effectuer. Docker est livré avec un profil seccomp par défaut qui bloque les appels système dangereux comme mount et reboot. Pour le multi-locataire, resserrez-le davantage en bloquant les appels système rares utilisés par les outils de fuite. De même, AppArmor peut confiner les processus des conteneurs. Créez un profil AppArmor personnalisé qui refuse l'accès en écriture aux interfaces du noyau et restreint les chemins de fichiers. Les deux sont définis via les drapeaux --security-opt. Combinez-les pour une défense en couches.

Étape 3 : Utiliser des démons Docker par locataire

Exécuter un seul démon Docker pour tous les locataires est risqué : toute fuite de conteneur pourrait accéder au socket du démon. Isolez les démons par locataire en utilisant Docker-in-Docker (DinD) ou des points de terminaison de démon distants. Par exemple, lancez un démon Docker à l'intérieur d'un conteneur avec --privileged (mais cela affaiblit l'isolation). Une meilleure approche : exécutez des démons séparés sur des VM séparées ou utilisez la fonctionnalité expérimentale --group de Docker avec les espaces de noms utilisateur. Pour l'orchestration, l'isolation basée sur les espaces de noms Kubernetes est plus pratique, comme expliqué dans Se défendre contre les fuites de conteneurs : un guide pratique de l'isolation Docker pour l'hébergement multi-locataire.

Étape 4 : Envisager des environnements d'exécution en sandbox

Lorsque le noyau Linux lui-même n'est pas fiable, utilisez un environnement d'exécution en sandbox qui ajoute une couche de VM légère. gVisor (runsc) intercepte les appels système et implémente son propre noyau, tandis que Firecracker utilise des micro-VM avec virtualisation matérielle. Les deux s'intègrent à Docker via les environnements d'exécution containerd. Par exemple, ajoutez "runtimes": {"runsc": {}} à la configuration du démon Docker et exécutez les conteneurs avec --runtime=runsc. Le surcoût de performance est de 5 à 15 %, mais l'isolation est nettement plus forte. Idéal pour les configurations multi-locataires à haute sécurité.

Étape 5 : Orchestrer avec Kubernetes et les politiques de sécurité

Kubernetes offre une multi-location native via les espaces de noms, les normes de sécurité des pods et les NetworkPolicies. Définissez des espaces de noms par locataire avec des quotas de ressources et appliquez des contextes de sécurité de pods restreints (supprimez toutes les capacités, système de fichiers racine en lecture seule). Des contrôleurs d'admission comme OPA/Gatekeeper peuvent bloquer les mauvaises configurations. Si vous gérez de nombreux locataires, Kubernetes automatise l'application de l'isolation. Pour une orchestration à l'échelle de la production, référez-vous à Au-delà de Docker Compose : orchestrer des applications conteneurisées prêtes pour la production.

Étape 6 : Choisir le bon fournisseur d'hébergement

L'hyperviseur de votre fournisseur d'infrastructure compte. Docker sur un hébergement partagé (OpenVZ) offre une faible isolation : un locataire peut voir les autres processus. Préférez les fournisseurs utilisant KVM ou VMware, qui offrent une séparation au niveau matériel. Des fournisseurs comme DigitalOcean, Kamatera ou AWS proposent des VPS basés sur KVM avec des ressources dédiées. Pour le bare-metal, assurez-vous que la virtualisation au niveau BIOS est activée pour les conteneurs imbriqués. Un fournisseur qui isole les locataires au niveau de l'hyperviseur complète votre isolation des conteneurs. Comme détaillé dans Maîtriser l'isolation Docker pour un hébergement web sécurisé et efficace, le système d'exploitation hôte doit également être durci avec une surface d'attaque minimale.

Mises en garde et compromis

Chaque couche supplémentaire ajoute de la complexité et un coût en performance. Les espaces de noms utilisateur peuvent casser les volumes montés sur l'hôte. Les profils Seccomp nécessitent un réglage par application. Les environnements d'exécution en sandbox comme gVisor ne prennent pas en charge tous les appels système : votre application pourrait ne pas fonctionner. Les démons Docker par locataire augmentent la surcharge mémoire. Choisissez le niveau d'isolation qui correspond à votre modèle de menace : pour des locataires de confiance, les espaces de noms par défaut peuvent suffire ; pour un SaaS public, investissez dans des sandbox d'exécution et des politiques Kubernetes. Testez minutieusement avant la production.

Conclusion

Une véritable isolation multi-locataire dans Docker est réalisable en superposant plusieurs fonctionnalités du noyau, des sandbox d'exécution et des contrôles d'orchestration. Commencez par les espaces de noms utilisateur et seccomp, puis passez aux démons par locataire ou aux environnements d'exécution en sandbox. Pour une grande échelle, Kubernetes offre une isolation basée sur des politiques. Associez toujours à un hôte séparé au niveau hyperviseur provenant d'un fournisseur réputé. Aucune technique unique n'est infaillible, mais leur combinaison crée une défense robuste. Vos locataires vous remercieront – et votre audit de sécurité aussi.

Sources (5)