# Sécurité de Docker

La sécurité de Docker est relative aux menaces et attaques qui remettraient en question la sécurité informatique basée sur les services de confidentialité, d’intégrité et de disponibilité. L'article traite des différents types d'attaques, des risques et des solutions apportées afin de sécuriser Docker.

## Sécurité des données

La sécurité informatique consiste à garantir que les ressources matérielles ou logicielles d'une organisation sont uniquement utilisées dans le cadre prévu.

### Confidentialité

Seules les personnes autorisées peuvent avoir accès aux informations qui leur sont destinées. Tout accès indésirable doit être empêché. Les seuls utilisateurs pouvant accéder au daemon docker sont les personnes faisant partie du groupe Docker ou les administrateurs de la machine, ce qui empêche en théorie une utilisation indésirable$^,$.

### Intégrité

Les données doivent être celles que l'on attend, et ne doivent pas être altérées de façon fortuite, illicite ou malveillante. En clair, les éléments considérés doivent être exacts et complets. Dans docker l'intégrité vient de la confiance, c'est-à-dire que l'utilisateur décide de récupérer une image docker sur le hub de docker qui est un ensemble d'images communautaires. Afin d'être sûr du choix d'image, docker a mis en place un système de certification qui garantit une image de qualité et non malveillante.

### Disponibilité

Le système doit fonctionner sans faille durant les plages d'utilisation prévues et garantir l'accès aux services et ressources installées avec le temps de réponse attendu. De base docker fournit une fonctionnalité afin d'avoir de la haute disponibilité, Docker Swarm, un orchestrateur qui permet de gérer son cluster de conteneurs. Il existe un autre orchestrateur qui est beaucoup plus performant et domine le marché : Kubernetes.

## Attaques

Docker est la cible d'attaques depuis sa création, on peut distinguer trois sources d'attaques, le conteneur (en)Docker, la machine hôte, et le réseau. De plus, le niveau de risque est affecté par la façon dont l’utilisateur interagit avec Docker.

### Par le conteneur

Les attaques par le conteneur (en) sont la source principale d'attaques. En effet, une étude réalisée sur 356 216 images a montré qu'en moyenne, il y a 180 vulnérabilités sur les images officielles ainsi que les non officielles. De plus, une grande partie des images présentes sur les recueils d'images ne sont jamais supprimées ou mises à jour. Les anciennes images peuvent toujours être téléchargées, mais la plupart n'ont pas été mises à jour depuis une centaine de jours et introduisent plusieurs vulnérabilités.
Une attaque par le conteneur est principalement conduite par l'application présente dans l'image. Les conteneurs Linux n'ont pas été conçus comme un mécanisme de sécurité permettant d'isoler les conteneurs non fiables et potentiellement malveillants. De plus, les conteneurs sont beaucoup plus sensibles aux attaques en comparaison aux machines virtuelles, qui doivent contourner le noyau de l'ordinateur virtuel et l'hyperviseur avant d'attaquer le noyau hôte$^,$.
Les conteneurs compromis sont également susceptible de compromettre le bon fonctionnement des autres conteneurs présents sur la même machine hôte. De ce fait, une application détournée pouvant obtenir des droits privilégiées du noyau, est susceptible de compromettre tous les conteneurs en cours d'exécution ainsi que la plate-forme hôte.

### Par la machine hôte

Étant donné que les conteneurs (en) fonctionnent sur le même noyau de l'hôte, ils sont vulnérables aux exploits du noyau. Un exploit donnant des privilèges root complets à un conteneur peut permettre à un attaquant de percer ce conteneur et de compromettre l'hôte.
Docker est basé sur la bibliothèque libcontainer, cependant cette bibliothèque possède plusieurs failles d'isolations : l'évasion de chroot, la traversée de répertoire, l'accès au système de fichier de l'hôte, l'élévation de privilège ainsi que l'élévation de container. Depuis que les processus des conteneurs sont souvent utilisés avec le PID 0, ils ont la possibilité de lire et d'écrire sur le système de fichier. Ils sont même autorisés à écraser les binaires de l'hôte et de les remplacer par celui de l'attaquant, l'exécution de code arbitraire avec les privilèges root sont donc possibles$^,$.

### Par le réseau

Par défaut, la connectivité entre les conteneurs (en) et la machine hôte est fournie via un pont ethernet virtuel. Les attaques par ARP poisoning et saturation de la table d'apprentissage entre conteneurs sur le même hôte est donc possible$^,$.
Le démon Docker est contrôlé à distance via une socket appartenant à root:docker. L'accès à cette socket permet aux attaquants d'extraire et d'exécuter n'importe quel conteneur en mode privilégié, leur donnant ainsi un accès root à l'hôte. À partir d'un système d'exploitation hôte compromis, les attaquants peuvent analyser, bloquer, injecter ou rediriger les communications réseau et système$^,$. L'attaquant peut effectuer diverses attaques telles que le déni de service et l'élévation des privilèges.
La distribution d'images par le biais du Docker Hub et d'autres registres de l'écosystème Docker est une source de vulnérabilités. Parce que ces vulnérabilités sont similaires aux gestionnaires de paquets classiques. Le traitement, le stockage et la décompression du code potentiellement non fiable, sont effectués par le démon Docker avec les privilèges root$^,$.

## Risques

Depuis le lancement de docker, plusieurs mises à jour et modifications ont été apportées pour améliorer sa sécurité, cependant les risques sont toujours présents. Selon une CVE les risques de docker sont l'exécution de code, l'accès à une ressource non désirée, le gain de privilège, le gain d'information et le déni de service.

### Extension de l'attaque

Si un conteneur (en) a été attaqué, il y a de grandes chances que l'attaque s'étende jusqu'à l'hôte. Cela peut compromettre le système tout entier en sortant du conteneur et en obtenant les droits d'administrateur. L'attaquant pourra alors exécuter du code et propager l'attaque aux autres composants du même réseau. Ces attaques sont conduites via les exploits du kernel ou par les ressources partagées entre les conteneurs et l'hôte (système de fichiers, mémoire, réseaux et volumes)$^,$.

### Répercussion sur les autres services

Dans une architecture basée sur les conteneurs (en), ils partagent tous les mêmes ressources kernel. Il y a une condition de déni de service qui se crée si un conteneur est exploité, les autres seront impactés.

## Contre mesures

La seule solution afin d'améliorer la sécurité de docker est de se prévenir des différents types d'attaques. Afin de s'en protéger un minimum, des bonnes pratiques sont à utiliser ainsi que choisir du contenu de confiance. Il existe néanmoins certains outils améliorant la sécurité comme SElinux, Apparmor et les Cgroups.

### Bonnes pratiques

Adopter de bonnes pratiques est une façon simple d'augmenter la sécurité d'une infrastructure docker. La meilleure protection des systèmes en termes d'isolation est celui qui ne partage aucune ressource physique avec les autres. La protection physique est souvent le meilleur moyen de se protéger des attaques. C'est-à-dire si le conteneur ne nécessite pas d'accès, il ne faut pas lui en donner.
Une autre façon de sécuriser des conteneurs (en) Docker est de limiter le mode privilégié à certains conteneurs. Les conteneurs Docker sont assez sûrs si nous prenons assez de précautions pour exécuter des charges de travail à l'intérieur des conteneurs en mode non privilégié. De ce fait, seuls les utilisateurs de confiance doivent être autorisés à contrôler le démon Docker.
Les conteneurs partagent le même noyau que la machine hôte, les noyaux n'étant plus mis à jour sont plus enclins à être exposés à des vulnérabilités publiques. Mettre régulièrement à jour le noyau avec les outils proposés par le système d'exploitation permet de réduire ce risque.

### Contenu de confiance

Une des possibilités afin de limiter les risques d'attaques est d'utiliser seulement du contenu de confiance. Docker propose d'utiliser des images certifiées, c'est-à-dire que nous sommes sûr que ces images sont fiables et possèdent seulement le contenu qu'elles proposent. Afin d'être certifiée, une image doit passer une série de tests sur l'API de docker grâce à l'outil inspectDockerImage fourni par docker. Il existe aussi des images avec des étiquettes spéciales "éditeur vérifié" et "image officielle", cela ne garantit pas la qualité de l'image mais au moins la provenance d'un éditeur reconnu$^,$. Docker propose une option afin d'utiliser seulement les images de confiances :
Le versionnage de l'image est aussi un facteur important, quand une image est envoyée sur le Docker Hub on peut lui préciser une version. Il est souvent préférable de choisir de récupérer une version connue et stable, par défaut, la dernière version est choisie pour le téléchargement de l'image$^,$.
Au sein d'une entreprise, l'utilisation de docker avec une registry privée est recommandée. Une registry Docker est une application serveur de type conteneur qui permet de stocker et distribuer des images Docker avec un système d'authentification. Cela permet de limiter l'accès de nos conteneurs (en) internes, qu'ils ne se retrouvent pas sur le hub docker à la vue de tous$^,$.

### SELinux

SELinux permet de définir une politique de contrôle d'accès obligatoire aux éléments d'un système. Docker utilise trois politiques de fortification de SELinux : le mécanisme de Type renforcement (en), sécurité multi-catégories (en) et la sécurité multi-niveau. Docker attribue une étiquette SELinux avec un ensemble réduit de privilèges à tous les processus exécutés dans les conteneurs (en). Le type renforcement est utilisé pour protéger le moteur Docker et l'hôte des conteneurs, qui peuvent provenir de sources non fiables. La méthode d'accès de contrôle de sécurité multi-catégories protège un conteneur des autres conteneur ayant le même type de renforcement. Actuellement, tous les conteneurs s'exécutent avec le même type SELinux, svirt_lxc_net_t, tel que défini dans le fichier de configuration de règles lxc_contexts. Ces conteneurs ne sont donc pas isolés les uns des autres.
L'application des étiquettes SELinux se fait avec le paramètre --security-opt au lancement du conteneur.
Les éditeurs publient leur politique SELinux liée à leurs images sur la plate-forme hôte. Les politiques sont déclarées dans le Dockerfile et sont placées dans les métadonnées de l'image au moment de sa construction.

### AppArmor

AppArmor est également un modèle d’amélioration de la sécurité pour Linux basé sur le contrôle d’accès obligatoire, comme SELinux, mais en limitant aux programmes individuels. Docker supprime les capacités du système et fait des restrictions sur les points de montage. Le contrôle d’accès obligatoire peut imposer des contraintes si le flux d’exécution normal n’est pas respecté. Par défaut, Docker autorise les accès complet au réseau et au système de fichier avec toutes les capacités système.

### Cgroups

Les Cgroups, ou groupes de contrôles offrent la possibilité de calculer et de limiter les ressources utilisées par les conteneurs (en). De ce fait, les Cgroups offrent la possibilité de limiter les attaques par déni de service en limitant les ressources système.
Les Cgroups sont un composant clé qui permet à docker de réguler le nombre de ressources utilisées, comme l'utilisation du CPU, de la mémoire, des entrées et sorties disques pour chaque conteneur. En s'assurant que chaque conteneur obtient une part équitable de ressources et qu'un conteneur ne consomme pas toutes celles disponibles. Ils permettent également à docker de déterminer les limites et les contraintes liées aux ressources allouées à chaque conteneur. Par exemple, une telle contrainte est de limiter le nombre de cœurs CPU disponibles à un conteneur spécifique$^,$$^,$.