Les bonnes pratiques sécurité pour votre environnement Docker


En complément des différents articles sur le déploiement d'applications sous forme de conteneurs Docker, parlons un peu de sécurité, et les bonnes pratiques à mettre en place pour faire tourner nos applications conteneurisées dans de bonnes conditions, tout en prenant le moins de risque possible.

Vous pouvez retrouver des grands principes de sécurité à observer dans cet article :

La cybersécurité et quelques principes de précaution
Pour commencer cette nouvelle série d’articles, je vais aborder un sujet qui metient à cœur, la cybersécurité. Il n’est jamais trop tard pour se soucier de sasécurité sur le web, apprendre les bonnes pratiques ou essayer d’oublier lesmauvaises habitudes qu’on peut avoir depuis plusieurs années pa…

Nous allons dans cet article aborder plus précisément la sécurité d'un environnement Linux, de Docker, des conteneurs et stacks que nous y lançons.

En premier lieu, je vous recommande vivement de lire les 2 ouvrages suivants proposés par l'ANSSI (Agence Nationale de la Sécurité des Systèmes d'Information) : Recommandations de sécurité relatives à un système Linux et Recommandations de sécurité relatives au déploiement de conteneurs Docker.

Publication : Recommandations de sécurité relatives à un système GNU/Linux
Les systèmes GNU/Linux offrent un grand nombre de combinaisons possibles. Des règles de configuration incontournables, recommandées par l’ANSSI, permettent d’obtenir un système raisonnablement sûr, tout en conservant les fonctionnalités requises, par le respect et l’application de certains principes…
Publication : Recommandations de sécurité relatives au déploiement de conteneurs Docker
Ce document a pour objectif de présenter les bonnes pratiques de sécurité relatives au déploiement et à l’exécution de conteneur Docker. De ce fait, le Docker daemon et la gestion des images Docker sont hors périmètre de l’étude.

Parmi les recommandations des 2 ouvrages précédents, voici ceux qui sont applicables facilement par tous.
Le système d'exploitation hôte est le premier élément que vous devez sécuriser. Pour cela, je vous déconseille d'utiliser l'utilisateur root pour vos tâches quotidiennes, mais vous invite plutôt à créer un utilisateur dédié au lancement de vos conteneurs.

Sur Debian, vous pouvez créer un nouvel utilisateur avec la commande adduser username. (choisissez un mot de passe sûr, que vous pourrez stocker dans Bitwarden)

root@nuc:~# adduser userdocker
Ajout de l'utilisateur « userdocker » ...
Ajout du nouveau groupe « userdocker » (1002) ...
Ajout du nouvel utilisateur « userdocker » (1002) avec le groupe « userdocker » ...
Création du répertoire personnel « /home/userdocker »...
Copie des fichiers depuis « /etc/skel »...
Nouveau mot de passe :
Retapez le nouveau mot de passe :
passwd: password updated successfully
Changing the user information for userdocker
Enter the new value, or press ENTER for the default
        Full Name []:
        Room Number []:
        Work Phone []:
        Home Phone []:
        Other []:
Cette information est-elle correcte ? [O/n]o
root@nuc:~#

Ensuite, pour autoriser ce nouvel utilisateur à utiliser Docker, nous allons l'ajouter au groupe docker avec la commande suivante :

usermod -aG docker userdocker

Connectez-vous avec cet utilisateur avec la commande su - userdocker et vérifiez que vous pouvez lancer des commandes Docker. La commande suivante va télécharger l'image hello-worldet la lancer.

root@nuc:~# su - userdocker
userdocker@nuc:~$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
b8dfde127a29: Pull complete
Digest: sha256:308866a43596e83578c7dfa15e27a73011bdd402185a84c5cd7f32a88b501a24
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

userdocker@nuc:~$

La prochaine recommandation est de n'exposer à Internet que le strict minimum et nécessaire. Par exemple, je n'ai que le port 443 qui est exposé chez moi, et c'est le reverse proxy qui fait les redirections adéquates en fonction du domaine ou sous-domaine appelé. Attention aussi à ne pas ouvrir de services vers l'extérieur que vous n'utilisez que chez vous, cela les exposerait inutilement. Nous verrons dans un futur article comment mettre en place un service de proxy inversé en tant que conteneur Docker (Nginx, Traefik, ...).

Un système sécurisé est un système maintenu à jour. En effet, en plus d'apporter des évolutions sur vos applications, les mises à jour comprennent souvent des patchs de sécurité pour combler des vulnérabilités, plus ou moins importantes.

Sur ce point, vous pouvez suivre les alertes publiées par CERT-FR, ainsi que les solutions pour remédier aux failles auxquelles vous êtes potentiellement exposé :

CERT-FR – Centre gouvernemental de veille, d’alerte et de réponse aux attaques informatiques

Concernant les conteneurs Docker eux-mêmes, plusieurs points d'attention sont à noter, notamment dans le choix des images que vous ferez. Je vous conseille de prendre vos images sur Docker Hub et si possible d'utiliser les images officielles des éditeurs. Si une image officielle n'existe pas, essayez de vérifier le fichier dockerfile pour voir les commandes utilisées lors de la construction de l'image.

Maintenant que vos conteneurs sont exécutés avec un utilisateur dédié, il est important de ne pas exposer les fichiers systèmes de l'hôte. Pour cela, il n'est pas recommandé de lancer les conteneurs avec l'option --privileged, mais plutôt de monter uniquement les volumes ou périphériques nécessaires avec les options --volumes et --devices et en spécifiant les droits d'accès des conteneurs à ces montages (ro pour des droits en lecture uniquement ou rw pour des droits en lecture et écriture).

Un élément important des conteneurs Docker est le réseau. Par défaut, à la création d'un conteneur, celui-ci est ajouté au réeau docker0, ce qui fait que tous les conteneurs peuvent se joindre entre eux. Pour pallier à ça, il est conseillé de lancer un conteneur avec l'option --bridge=none. Il faut également éviter d'utiliser l'option --network host, car cela expose le conteneur à l'ensemble du réseau local de l'hôte.
La bonne pratique est de créer un réseau dédié à chaque conteneur qui doit exposer un ou plusieurs ports, pour les rendre accessible depuis l'hôte et votre réseau local. Pour cela, il faut utiliser la commande docker network create [OPTIONS] <NETWORK> et ajouter au lancement de votre conteneur l'option --network <NETWORK>. Il est possible de connecter plusieurs conteneurs entre eux en les ajoutant à un même réseau, ou encore d'ajouter plusieurs réseaux à un seul conteneur.

Dans le schéma ci-dessous, le conteneur db fait partie du réseau db, et le conteneur web fait partie des réseaux db et web. Seul le réseau web est ouvert vers l'extérieur de l'hôte, le réseau db n'est pas accessible depuis le réseau local.

Comme pour le système d'exploitation, il est aussi nécessaire de mettre à jour vos conteneurs pour bénéficier des derniers correctifs de sécurité. Attention toutefois à bien lire le journal des modifications pour éviter les mauvaises surprises.

Un dernier point très important, pas directement lié à la sécurité, mais plutôt sur la protection des données : les sauvegardes ! Vous avez certainement entendu parler de l'incident majeur qui a touché OVH et un de ses datacenters la semaine dernière. Je tenais à vous rappeler de procéder à une sauvegarde régulière de vos données, cela pourra vous permettre de remettre en ligne vos services rapidement en cas d'indisponibilité.


J'espère que cet article vous aura appris des astuces et bonnes pratiques de sécurité, et apporté des éléments pour améliorer la sécurité de votre environnement.

N'hésitez pas à laisser un commentaire ou à venir nous retrouver sur notre groupe Telegram si vous avez des questions sur une partie de l'article ou sur un point non abordé ici et qui vous semble important.