Sécuriser les conteneurs Windows

S’applique à : Windows Server 2022, Windows Server 2019, Windows Server 2016

Les conteneurs ont une taille d’image réduite qui se justifie par le fait qu’ils peuvent compter sur l’hôte pour fournir un accès limité à différentes ressources. Si le conteneur sait que l’hôte est capable de fournir les fonctionnalités nécessaires à l’exécution d’un ensemble spécifique d’actions, il n’a nul besoin d’inclure les logiciels appropriés dans son image de base. L’étendue du partage des ressources qui en résulte peut toutefois avoir un impact significatif sur les performances et la sécurité du conteneur. Si un trop grand nombre de ressources sont partagées, l’application peut tout aussi bien s’exécuter simplement en tant que processus sur l’hôte. Si les ressources ne sont pas partagées en nombre suffisant, le conteneur s’apparente davantage à une machine virtuelle. Les deux configurations sont applicables à beaucoup de scénarios, mais la plupart des utilisateurs de conteneurs optent généralement pour une solution intermédiaire.

La sécurité d’un conteneur Windows découle du degré de partage entre le conteneur et son hôte. La limite de sécurité d’un conteneur est constituée par les mécanismes d’isolation qui séparent le conteneur de l’hôte. Ces mécanismes d’isolation ont un rôle capital, car ils définissent quels processus dans le conteneur sont autorisés à interagir avec l’hôte. Quand la conception d’un conteneur permet à un processus avec des privilèges élevés (administrateur) d’interagir avec l’hôte, Microsoft considère que ce conteneur n’a pas une limite de sécurité robuste.

Comparaison des conteneurs Windows Server et des conteneurs Linux

Les conteneurs Windows Server et les conteneurs Linux isolés par processus présentent des degrés d’isolation similaires. Pour ces deux types de conteneurs, le développeur doit partir du principe que des attaques réalisables sur l’hôte par le biais d’un processus avec des privilèges élevés peuvent également être effectuées dans le conteneur via un processus avec des privilèges élevés. Dans les deux cas, ce sont les fonctionnalités primitives fournies par leurs noyaux hôtes respectifs qui sont utilisées. Les images conteneur générées contiennent des fichiers binaires en mode utilisateur qui font appel aux API fournies par le noyau hôte. Le noyau hôte fournit les mêmes fonctionnalités d’isolation et de gestion des ressources à chacun des conteneurs exécutés dans l’espace utilisateur. Si le noyau est compromis, chaque conteneur partageant ce noyau l’est aussi.

La sécurité des conteneurs Linux et Windows Server est fondamentalement conçue dans une optique de flexibilité. Les conteneurs Windows Server et Linux sont basés sur les composants primitifs fournis par le système d’exploitation. Cette conception offre la flexibilité nécessaire au partage des ressources et des espaces de noms entre les conteneurs, mais en introduisant davantage de complexité, elle ouvre la voie à l’exploitation des vulnérabilités. De façon générale, nous ne considérons pas le noyau comme une limite de sécurité suffisante pour les charges de travail multilocataires hostiles.

Isolation du noyau avec des conteneurs isolés par hyperviseur

Les conteneurs isolés par hyperviseur fournissent un degré d’isolation plus élevé que les conteneurs Windows Server ou Linux isolés par processus ; ils sont considérés comme constituant une limite de sécurité robuste. Un conteneur isolé par hyperviseur consiste en un conteneur Windows Server wrappé dans une machine virtuelle ultralight, et il est exécuté parallèlement au système d’exploitation hôte via l’hyperviseur de Microsoft. L’hyperviseur fournit une isolation matérielle qui instaure une limite de sécurité très robuste entre l’hôte et les autres conteneurs. Même si une exploitation se produisait par évasion à partir du conteneur Windows Server, elle resterait contenue au sein de la machine virtuelle isolée par hyperviseur.

Ni les conteneurs Windows Server ni les conteneurs Linux ne fournissent une limite de sécurité considérée comme robuste par Microsoft. Ils ne doivent donc pas être utilisés dans des scénarios multilocataires hostiles. Un conteneur doit être isolé sur une machine virtuelle dédiée pour empêcher tout processus non autorisé du conteneur d’interagir avec l’hôte ou d’autres locataires. L’isolation par hyperviseur offre ce degré de séparation tout en améliorant les performances à différents niveaux par rapport aux machines virtuelles traditionnelles. C’est pourquoi il est fortement recommandé de choisir des conteneurs isolés par hyperviseur dans des scénarios multilocataires hostiles.

Critères de maintenance de la sécurité des conteneurs

Microsoft s’engage à appliquer les mises à jour correctives nécessaires pour toutes les exploitations et évasions qui enfreignent la limite d’isolation établie des types de conteneurs Windows. Notez que seules les exploitations qui enfreignent une limite de sécurité font l’objet d’une maintenance par le Centre de réponse aux problèmes de sécurité Microsoft (MSRC). Seuls les conteneurs isolés par hyperviseur fournissent une limite de sécurité robuste ; les conteneurs isolés par processus ne le font pas. La seule façon de générer un bogue par évasion d’un conteneur isolé par processus est si un processus non-administrateur peut accéder à l’hôte. Si une exploitation utilise un processus administrateur pour s’évader du conteneur, Microsoft considère qu’il s’agit d’un bogue non lié à la sécurité et il le corrige selon le processus de maintenance normal. Si une exploitation utilise un processus non-administrateur pour effectuer une action qui enfreint une limite de sécurité, Microsoft investigue à son sujet conformément aux critères de maintenance de la sécurité établis.

Qu’est-ce qui rend hostile une charge de travail multilocataire ?

On parle d’environnements multilocataires quand plusieurs charges de travail opèrent sur une infrastructure et des ressources partagées. Si une ou plusieurs charges de travail s’exécutant sur une infrastructure ne peuvent pas être approuvées comme fiables, l’environnement multilocataire est considéré comme hostile. Les conteneurs Windows Server et Linux partagent le noyau hôte. De ce fait, l’exploitation d’une vulnérabilité sur un conteneur donné peut impacter toutes les autres charges de travail exécutées sur l’infrastructure partagée.

Vous pouvez prendre certaines mesures pour réduire le risque d’exploitation d’une vulnérabilité, notamment en utilisant des stratégies de sécurité des pods, le logiciel AppArmor et le contrôle d’accès en fonction du rôle (RBAC), mais ces mesures ne garantissent pas une protection totale contre les attaquants. Nous vous recommandons de suivre nos bonnes pratiques d’isolation des clusters dans les scénarios multilocataires.

Contexte d’utilisation des comptes d’utilisateur ContainerAdministrator et ContainerUser

Les conteneurs Windows Server fournissent deux comptes d’utilisateur par défaut, ContainerUser et ContainerAdministrator, chacun ayant une finalité qui lui est propre. Avec le compte ContainerAdministrator, vous utilisez le conteneur pour des tâches d’administration, par exemple, l’installation des services et logiciels (comme l’activation d’IIS dans un conteneur), la modification de la configuration et la création de comptes supplémentaires. Ces tâches sont importantes pour certains scénarios informatiques susceptibles de s’exécuter dans des environnements de déploiement locaux personnalisés.

Le compte ContainerUser s’utilise pour tous les autres scénarios où il n’est pas nécessaire d’avoir des privilèges administrateur dans Windows. Par exemple, dans Kubernetes, si l’utilisateur a un compte ContainerAdministrator et que les volumes hôtes sont autorisés à être montés dans le pod, l’utilisateur peut monter le dossier .ssh et ajouter une clé publique. Cet exemple ne serait pas possible si l’utilisateur avait un compte ContainerUser. Il s’agit d’un compte d’utilisateur restreint, conçu exclusivement pour les applications qui n’ont pas besoin d’interagir avec l’hôte. Nous vous recommandons fortement, si vous déployez un conteneur Windows Server dans un environnement multilocataire, d’exécuter votre application avec le compte ContainerUser. Dans un environnement multilocataire, il est toujours préférable de suivre le principe du privilège minimum ; en effet, en cas de compromission de votre charge de travail par un attaquant, la ressource partagée et les charges de travail voisines risquent moins d’être impactées. L’exécution de conteneurs avec le compte ContainerUser réduit considérablement les risques de compromission de l’ensemble de l’environnement. Cependant, cette solution ne suffit pas à fournir une limite de sécurité robuste. Si la sécurité est votre priorité, vous devez absolument utiliser des conteneurs isolés par hyperviseur.

Pour changer le compte d’utilisateur, vous pouvez utiliser l’instruction USER sur votre fichier Dockerfile :

USER ContainerUser

Vous pouvez aussi créer un utilisateur :

RUN net user username ‘<password>’ /ADD
USER username

Services Windows

Les services Microsoft Windows, anciennement « services NT », vous permettent de créer des applications exécutables longue durée qui s’exécutent au sein de leurs propres sessions Windows. Vous pouvez démarrer automatiquement ces services au démarrage du système d’exploitation, les suspendre et les redémarrer et ne pas afficher les interfaces utilisateur. Vous pouvez également exécuter des services dans le contexte de sécurité d’un compte d’utilisateur spécifique (différent de l’utilisateur connecté ou du compte d’ordinateur par défaut).

Lors de la conteneurisation et de la sécurisation d’une charge de travail qui s’exécute en tant que service Windows, il existe quelques considérations supplémentaires à prendre en compte. Tout d’abord, le ENTRYPOINT du conteneur ne va pas être la charge de travail, car le service s’exécute comme processus en arrière-plan, généralement le ENTRYPOINT est un outil tel qu’un moniteur de service) ou un moniteur de journal). Ensuite, le compte de sécurité, sous lequel la charge de travail fonctionne, est configuré par le service, et non selon l’instruction USER dans le dockerfile. Vous pouvez vérifier le compte sous lequel le service fonctionne en exécutant Get-WmiObject win32_service -filter "name='<servicename>'" | Format-List StartName.

Par exemple, lors de l’hébergement d’une application web IIS en utilisant l’image ASP.NET (Registre des artefacts Microsoft), le ENTRYPOINT du conteneur est "C:\\ServiceMonitor.exe", "w3svc". Vous pouvez utiliser cet outil qui configure le service IIS, le surveille ensuite pour veiller à ce qu’il continue à s’exécuter, et effectue une sortie en provoquant l’arrêt du conteneur si le service s’arrête pour une raison quelconque. Par défaut, le service IIS, et par conséquent l’application web, s’exécutent sous un compte à faibles privilèges au sein du conteneur, mais l’outil de surveillance du service nécessite des privilèges administratifs pour configurer et monitorer le service.