Les Bonnes Pratiques Docker

Les Bonnes Pratiques Docker

 Docker est un outil formidable qui permet de faire beaucoup de choses de manière plus ordonnée et plus sécurisée. Mais c’est aussi une grosse usine à gaz et si l’on ne fait pas attention il peut très vite devenir une véritable passoire ou un danger pour notre système. Voici quelque pratique à mettre en œuvre pour limiter les risques. 

1.           Créer une partition séparée pour Docker

Vu que l’on manipule plusieurs images téléchargées depuis internet il est possible que cela occupe très rapidement un trop grand espace. Le dossier par défaut ou docker stocke l’ensemble de ces données (images et containers) est le répertoire /var/lib/docker. Le souci majeur est que se répertoire est situé sous la racine / et que si nos images et nos containers venaient à occuper trop d’espace ils pourraient saturer le disque dur système ce qui rendrais le système hôte inutilisable donc par ricochet les Containers inutilisables. Une image malveillante, mal configurée ou même toute simple trop gourmande pourrait rapidement saturer le disque dur. 

Pour se prémunir de ce problème, il faut créer une partition physique séparée pour le répertoire  /var/lib/docker  dès l’installation de votre système hôte. Si votre Système est déjà installé, créer une partition logique avec LVM (Logical Volume Manager) ou alors utiliser un second disque pour docker.

Ces 2 solutions permet de définir un quota a ne pas dépasser par docker et donc vous évite de mettre votre racine / en péril.

2.           Maintenir Votre Système hôte à jour      

Cela peut paraître évident, mais que ce soit votre système hôte, le kernel ou docker engine, assurez-vous que votre système soit bien à jour. Les mises à jour permettent généralement de corriger des bugs des versions précédentes ou d’ajouter des fonctionnalités. Bien évidement il faut au préalable se rassurer que la mise à jour sera compatible avec les configurations effectuez. Pensez aussi à n’installer que des versions stables des logiciels ou même des mises à jour système pour éviter des bugs ou des effets dominos qui pourraient mettre à mal votre système.

Assurer vous donc de mettre régulièrement à jour Docker dès qu’une version stable est sortie. Il est recommandé pour docker d’avoir un noyau Linux minimum en version 3.10

interdire les communications entre les containers.

Par défaut, la communication entre tous les containers est possible sans forcément utiliser la fonction de link qui remet de lié 2 conteneurs. Une mauvaise image pourrait donc faire un sniffing et voir tout ce qui se passe sur le sous-réseau Docker de votre système hôte. C’est particulièrement dangereux, car la plupart du temps il n’y a pas de communications sécurisé entre vos containers que vous considérez comme «isolés » sur votre sous-réseau docker0.

Donc il faudrait déjà commencer par éviter d’installer s’importe qu’elle image sur votre Stack Docker et penser à vérifier le fichier dockerfile à chaque fois avant d’installer une image.

À moins d’en avoir absolument besoin et d’être sûr de tous les containers installés sur votre stack, la bonne pratique serait donc d’interdire se comportement par défaut qui permet la communication entre les conteneurs. Seuls les containers liés par link pourront  communiquer entre eux. Cela est possible nativement il suffit de passer le paramètre –icc=false au daemon. Sous debian et Ubuntu, cette opération se fait dans le fichier  /etc/default/docker en modifiant la variable DOCKER_OPTS.

[pastacode lang= »markup » manual= »DOCKER_OPTS%3D%22-icc%3Dfalse%22″ message= » » highlight= » » provider= »manual »/]

3.           N’utilisez pas privileged pour n’importe quelle image

Quand vous lancez un container avec le mot clé –privileged, docker vas lui accorder tous les droits y compris celui de lancer un nouveau container sur la machine hôte (Docker in Docker).

 C’est par exemple le cas de l’image dockerui qui a besoin de lister les images et les containers pour éventuellement les démarrer et les arrêter.  Cette image étant fournie par un développeur de docker, nous pouvons à priori lui faire confiance, mais ce n’est pas le cas de toutes les images disponibles sur le hub ou sur d’autres registry.

Si une image demande à être privileged, demandez-vous pourquoi elle a besoin de ce droit. Même si l’utilisation de privileged est justifiée, il n’est pas forcement obligatoire de lui accorder la totalité des droits. C’est ce que permet les options –cap-add  et –cap-drop. Selon votre demande ces commandes permettent à un container privileged de lui retirer un ou plusieurs droits, ou alors à un container normal de lui rajouter les droits nécessaires.   

Exemple : ntpd (Network Time Protocol Deamon) est un serveur de temps, il ne parait donc pas absurde de lui donner la capacité de modifier l’heure de l’hôte. 

[pastacode lang= »bash » manual= »docker%20run%20-d%20–cap-add%20SYS_TIME%20ntpd » message= » » highlight= » » provider= »manual »/]

4.           N’utilisez pas n’importe quel registry

La plupart des images sont téléchargeables depuis le registry Docker Hub. En général et par mesure de sécurité maximale, utiliser uniquement les images «Official » proposées et validées par la société Docker. Si vous n’en trouvez pas pour une image qui vous intéresse, assurez-vous que l’image et été suffisamment téléchargés et à priori « testés » par les autres utilisateurs. N’hésitez pas non plus à getter un coup d’œil dans le Dockerfile sous GitHub afin de vous assurer que l’image correspond bien à ce qu’elle est censée faire. Pensez aussi à vérifier les images intermédiaires utilisées pour cette image. Remontez les images intermédiaires jusqu’à atteindre une image officielle ou une image from scratch. 

Si vous ne trouver pas votre compte sur le docker hub et que vous utilisiez un autre registry vérifier tous d’abord la réputation du registry que vous allez utiliser.  Mais également que la communication établie avec ce nouveau registry  se fera de manière sécurisée.  De toutes les façons par défaut docker bloque les commandes pull si elles ne sont pas sécurisées.

5.           Créer un utilisateur dans votre Dockerfile

La plupart de vos applications ne nécessitent pas d’être lancé en root, c’est même très rarement le cas. Par conséquent, il n’est pas nécessaire d’utiliser le user root dans vos containers a tous les coups. La  création d’un utilisateur dans votre image peut se faire directement depuis le dockerfile avec les 2 instructions suivantes :

[pastacode lang= »bash » manual= »RUN%20useradd%20-d%20%2Fhome%2Fmyappuser%20-m%20-s%20%2Fbin%2Fbash%20myappuser%0A%0AUSER%20myappuser » message= » » highlight= » » provider= »manual »/]

Pour vérifier l’utilisateur utilisé par vos containers lancés, vous pouvez utiliser la commande :

[pastacode lang= »bash » manual= »docker%20ps%20-q%20%7C%20xargs%20docker%20inspect%20–format%20’%7B%7B%20.Id%20%7D%7D%3A%20User%3D%7B%7B.Config.User%7D%7D' » message= » » highlight= » » provider= »manual »/]

Si user est vide, c’est que vos containers sont lancés en root.

Pour une image téléchargée, pensez à vérifier la présence de l’instruction USER dans le Dockerfile et éventuellement à surcharger l’image si ce n’est pas le cas. 

Exemple :

[pastacode lang= »apacheconf » manual= »FROM%20apacheOnlyRoot%0A%0AUSER%20www-data » message= » » highlight= » » provider= »manual »/]

 

6.           Ne mapper que les ports utiles

Docker permet un mapping entre les ports déclarés par le Dockerfile et ceux ouverts sur votre système hôte via l’option –P (en Majuscule). Cela va lancer le conteneur en exposant tous les ports déclarés dans le dockerfile.

N’utilise cette option que lors des tests. Préférer toujours l’option –p (minuscule) pour vous permet de spécifier quel port de l’hôte vous souhaitez mâché avec un port spécifique du conteneur. 

[pastacode lang= »bash » manual= »docker%20run%20-p%2080%3A80%20apache » message= » » highlight= » » provider= »manual »/]

De plus, si vous n’avez pas besoin de rendre publique l’adresse IP, vous pouvez spécifier sur quelle interface réseau vous souhaitez écouter.

[pastacode lang= »bash » manual= »docker%20run%20-p%20192.168.0.1%3A9200%3A9200%20elasticsearch » message= » » highlight= » » provider= »manual »/]

Cette commande permet de n’ouvrir le port 9200 que pour votre réseau local. Une connexion depuis une machine hors réseau local (internet) sera refusée.

Mieux encore si vous n’avez pas besoin que le port soit exposé  à l’extérieur, mais uniquement accessible à partir de la machine hôte ou bien d’autres conteneurs.

Exemple un conteneur MySQL sur le qu’elle se connecte notre conteneur web et  administré via un conteneur PhpMyAdmin n’a pas absolument besoin d’être visible de l’extérieur un link entre le conteneur MySQL et les 2 conteneurs Web et PhpMyAdmin est suffisant donc vous n’utilisez aucune des options qui permet de maché les ports (pas de P majuscule ou minuscule) cela fera en sort que votre conteneur soit accessible uniquement depuis la machine hôte via son IP privé.

7.           Permission sur les fichiers

Vérifier que les permissions sont attribuées correctement aux fichiers manipulés par les conteneurs. Tous comme on fait des vérifications du répertoire utiliser par nos serveurs web. Pensez donc à n’attribuer que les droits nécessaires et de restreindre que maximum les fichiers accessibles sur l’hôte par les conteneurs. 

8.           Veille technologique

Pensez également à vous tenir informé des différentes avancées technologiques dans le domaine afin de toujours garder votre serveur sécurisé et d’utiliser les bonnes pratiques.

Docker est un outil formidable qui promet encore de nombreuses améliorations en termes de fonctionnalité et de sécurité. Mais la configuration par défaut de docker n’est malheureusement pas suffisante en termes de sécurité, mais représente tristement plus de 90% des installations de docker. À mon sens, beaucoup d’options devraient être activées par défaut pour réduire au maximum les risques.

   Webographie :

INOVIA

joel

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.