Vous pouvez faire tourner Docker en production pendant des mois sans le moindre problème visible. Les conteneurs démarrent, les applications répondent, rien ne plante. Puis un port exposé ou une permission mal configurée crée une brèche qu'un attaquant n'a pas eu à forcer. La plupart des erreurs de sécurité Docker ne ressemblent pas à des erreurs, jusqu'au moment où quelque chose tourne mal.
Cet article passe en revue les configurations qui exposent les environnements de conteneurs à des risques, ce qu'elles permettent à un attaquant de faire, et se termine par une liste de vérification que vous pouvez appliquer à votre propre configuration dès aujourd'hui.
Pourquoi la sécurité Docker est plus complexe qu'il n'y paraît
Les conteneurs donnent une impression d'isolation. Vous en démarrez un, il s'exécute dans son propre espace de processus, et de l'intérieur, le conteneur voisin n'existe pas. Vous bénéficiez bien d'une isolation, mais elle reste partielle. Les conteneurs partagent le noyau de l'hôte, ce qui signifie qu'un processus à l'intérieur d'un conteneur peut, dans certaines conditions, accéder entièrement au système hôte.
Docker est configuré par défaut pour la commodité des développeurs, pas pour un durcissement en production. Accès root activé. Tous les ports peuvent être liés à toutes les interfaces. Aucune surveillance à l'exécution. La plupart des développeurs acceptent ces paramètres, déploient le conteneur et passent à autre chose. C'est une approche raisonnable pour démarrer, mais ce n'est pas une posture de sécurité aboutie.
D'après Le rapport 2024 de Red Hat sur la sécurité Kubernetes, 67 % des organisations ont retardé ou ralenti le déploiement d'applications en raison de problèmes de sécurité liés aux conteneurs ou à Kubernetes. Ces frictions ne viennent généralement pas d'attaques réelles. Elles viennent d'équipes qui découvrent que leurs configurations de conteneurs nécessitaient un durcissement qu'elles n'avaient pas prévu.
On observe fréquemment des conteneurs en production avec exactement la même configuration que sur la machine locale d'un développeur. C'est là que les erreurs de sécurité Docker s'accumulent discrètement, sans symptôme visible, jusqu'à ce qu'un audit soit réalisé ou qu'une défaillance survienne.
Les erreurs qui créent ces failles sont précises, prévisibles et largement évitables, à commencer par le niveau de la configuration.
Erreurs de configuration Docker courantes
La plupart des compromissions de conteneurs ne démarrent pas par une faille zero-day. Elles démarrent par une configuration définie au premier jour, sans vraiment réfléchir à l'exposition réseau ou à la portée des privilèges.
Les paramètres par défaut de Docker sont conçus pour fonctionner. L'écart entre fonctionnel et sécurisé, c'est là que s'accumulent les risques de sécurité des conteneurs Docker, en particulier dans les déploiements auto-hébergés qui ne sont jamais reconfigurés après leur mise en service.
Ce schéma revient souvent : des conteneurs sur des serveurs avec IP publique dont les liaisons de ports, les paramètres utilisateur et les configurations réseau sont exactement les mêmes qu'au déploiement initial.
Exécution des conteneurs en tant que root
Par défaut, quand vous démarrez un conteneur Docker sans spécifier d'utilisateur, il s'exécute en tant que root. Cela signifie que tous les processus à l'intérieur du conteneur, y compris votre application, disposent des privilèges root dans le namespace du conteneur.

Être root dans un conteneur n'est pas la même chose qu'être root sur l'hôte, mais la séparation n'est pas absolue. Les exploits d'élévation de privilèges ciblant le runtime — comme le bien documenté runc CVE-2019-5736 et d'autres failles similaires — nécessitent fréquemment un processus root dans le conteneur pour aboutir.
Les conteneurs non-root suppriment cette exigence de processus root dont dépendent ces exploits, ce qui réduit considérablement la surface d'attaque pour cette catégorie de vulnérabilités. Cela ne supprime pas entièrement le risque d'évasion de conteneur pour autant.
L'ajout d'une directive USER dans votre Dockerfile règle ce problème. Certaines images officielles incluent un utilisateur non privilégié que vous pouvez activer avec une directive USER, mais beaucoup utilisent encore root par défaut sans utilisateur applicatif prêt à l'emploi. Dans ces cas, vous créez l'utilisateur dans le Dockerfile avant d'y basculer. Pour la plupart des configurations auto-hébergées, ce simple changement élimine toute une catégorie de risques d'élévation de privilèges.
Exposer trop de ports sur l'internet public
Quand vous publiez un port avec Docker, Docker écrit ses propres règles iptables directement. Ces règles s'appliquent avant les règles du pare-feu de l'hôte. Il s'agit d'un comportement connu et signalé par la communauté et documenté dans le guide de filtrage de paquets de Docker, et non d'une mauvaise configuration. Concrètement, UFW et les outils similaires ne bloquent pas ce que Docker a déjà ouvert.

Docker écrit directement dans iptables, contournant les règles par défaut d'UFW et de firewalld sur de nombreux hôtes Linux. Un port lié à 0.0.0.0 peut donc être accessible publiquement même si votre pare-feu semble correctement configuré. Les groupes de sécurité cloud et les règles de la chaîne DOCKER-USER peuvent néanmoins bloquer ce trafic, donc l'exposition réelle dépend de votre configuration réseau.
Liez vos services à 127.0.0.1 quand c'est possible, faites passer le trafic public par un reverse proxy, et ne publiez que ce qui nécessite véritablement un accès externe. Le reverse proxy reste la méthode la plus fiable pour contrôler ce qui est exposé depuis l'extérieur de l'hôte.
Négliger l'isolation réseau entre les conteneurs
Tout conteneur sur ce réseau peut atteindre n'importe quel autre conteneur sans restriction. Le bridge par défaut n'applique aucun filtrage de trafic entre les conteneurs qui le partagent, et la plupart des configurations ne changent jamais cela.

Si un conteneur est compromis, cette communication ouverte devient un vecteur de déplacement latéral. Un conteneur frontend peut atteindre une base de données, un API interne ou n'importe quoi d'autre sur le même réseau bridge par défaut, même lorsque cet accès n'était pas intentionnel.
Les réseaux définis par l'utilisateur vous donnent un contrôle explicite sur les communications entre conteneurs, mais un réseau personnalisé unique partagé par tous vos services autorise toujours un trafic inter-conteneurs libre. Une vraie isolation exige de placer sur des réseaux séparés les services qui ne devraient pas communiquer entre eux. Désactiver le bridge par défaut est un point de départ, pas une fin en soi.
Ignorer la socket Docker
La socket Docker située à /var/run/docker.sock est l'interface de contrôle de l'ensemble du moteur Docker. La monter dans un conteneur donne à ce conteneur un accès API direct au daemon qui s'exécute sur l'hôte.

Avec cet accès, un conteneur peut démarrer de nouveaux conteneurs, monter des répertoires de l'hôte, inspecter et modifier les conteneurs en cours d'exécution, et contrôler effectivement la machine hôte. La surface d'attaque est équivalente à un accès root sur l'hôte, ce qui explique pourquoi tout outil nécessitant un accès à la socket mérite une évaluation attentive.
Pour la plupart des cas d'usage, il existe des alternatives plus sûres : des API à portée limitée ou des outils de gestion Docker qui ne nécessitent pas d'accès à la socket. Docker-dans-Docker implique ses propres compromis en matière de sécurité et d'exploitation, et ne constitue pas une substitution directe.
Les erreurs de configuration créent la surface d'attaque initiale. Le choix des images et des dépendances détermine comment cette surface s'étend avec le temps.
Erreurs d'images et de secrets qui survivent au conteneur
Quand vous arrêtez un conteneur, les erreurs de configuration qu'il contient s'arrêtent avec lui. Quand vous reconstruisez à partir d'une image qui embarque une vulnérabilité ou un identifiant codé en dur, le problème redémarre avec le conteneur. Les erreurs au niveau de l'image ne se réinitialisent pas entre les déploiements.
Elles voyagent avec l'image dans chaque environnement qui la télécharge, chaque registre qui la stocke et chaque membre de l'équipe qui l'exécute. Cette persistance fait de la gestion des images et des secrets une catégorie de risque à part, qui mérite un audit séparé de celui de la configuration.
Ce schéma revient souvent : une image choisie avec soin au démarrage du projet, jamais reconstruite depuis, qui s'éloigne progressivement du niveau de sécurité qu'elle représentait à l'origine.
Utiliser des images non fiables ou obsolètes
Les registres publics sont ouverts à tous. Des images malveillantes ont été distribuées via Docker Hub, embarquant des cryptomineurs et des backdoors dans l'historique des couches, qui persistent après les redémarrages du conteneur. Vérifier une image avant de la télécharger est essentiel, surtout si elle provient d'un éditeur non officiel ou inconnu.

Le problème distinct, c'est l'obsolescence. Une image officielle téléchargée il y a six mois et jamais reconstruite depuis accumule des vulnérabilités non corrigées à chaque CVE publié contre ses paquets. L'image ne est pas cassée. Elle n'est simplement plus à jour.
Rapport 2024 de Sonatype sur l'état de la chaîne d'approvisionnement logicielle constate que dans 95 % des cas où un composant vulnérable est utilisé, une version corrigée est déjà disponible, et que 80 % des dépendances applicatives restent non mises à jour pendant plus d'un an. Ce constat s'applique aussi aux images de base Docker, qui reposent sur les mêmes paquets open source.
Utilisez des images officielles provenant d'éditeurs vérifiés et épinglez des tags de version précis plutôt que de vous fier à « latest ». Mettez en place un cycle de reconstruction régulier pour garder vos images à jour.
Coder des secrets en dur dans les Dockerfiles et les fichiers Compose
Les identifiants écrits dans une instruction ENV ou ARG d'un Dockerfile, codés en dur dans un bloc d'environnement Compose, passés comme arguments de build ou stockés dans un fichier .env versionné ne disparaissent pas quand vous arrêtez le conteneur. Ils restent dans l'historique des couches de l'image ou dans le dépôt source, accessibles à quiconque peut y accéder.

C'est l'une des erreurs de sécurité Docker les plus souvent négligées, car elle ne provoque aucun problème visible pendant le développement. Une clé API dans une instruction ENV fonctionne correctement. Elle est aussi dans votre dépôt, intégrée à votre image et distribuée partout où cette image circule.
Docker Compose supporte nativement un mécanisme de secrets qui monte les identifiants à l'exécution sans les intégrer à l'image. Les secrets API de Docker et les gestionnaires de secrets externes suivent le même principe. Ce sont ces options qui maintiennent les identifiants totalement hors des artefacts de build et des fichiers versionnés.
Les variables d'environnement à l'exécution sont une amélioration par rapport aux identifiants codés en dur, mais elles restent exposées via la sortie de Docker inspect, les logs et les dumps de crash. C'est un progrès par rapport aux secrets intégrés à l'image, pas une solution définitive.
Ne pas mettre à jour les images régulièrement
Utiliser la même image pendant des mois est une habitude courante. Chaque jour qui passe après la publication d'une vulnérabilité, avant que vous ne reconstruisiez, vos conteneurs accumulent une fenêtre d'exposition qui grandit sans aucun changement visible.
Établissez un calendrier de reconstruction régulier. Automatisez ce processus autant que possible et lancez périodiquement un scanner de vulnérabilités sur vos images actuelles. L'objectif n'est pas la perfection. C'est de réduire le délai entre la publication d'un correctif et son déploiement.
Le contrôle d'accès et la supervision peuvent être relégués au second plan dans les déploiements rapides. Ce sont pourtant les domaines où les incidents passent le plus longtemps inaperçus.
Lacunes dans le contrôle d'accès et la visibilité
Une fois qu'un conteneur tourne avec une configuration solide et des images à jour, il reste deux catégories de défaillances. Toutes deux sont invisibles par nature : un problème de contrôle d'accès trop permissif ne se remarque que quand quelqu'un en abuse, et une lacune dans la supervision ne se révèle que quand vous devez investiguer une activité qui n'a jamais été enregistrée.
Le même Recherche Red Hat 2024 a révélé que 42 % des équipes ne disposaient pas des capacités suffisantes pour traiter la sécurité des conteneurs et les menaces associées.
Dans notre expérience, les lacunes de surveillance apparaissent généralement lors d'investigations après incident, pas avant. Au moment où la visibilité devient une priorité, on est souvent en train de réagir plutôt que de prévenir.
Authentification faible et tableaux de bord d'administration exposés
Un tableau de bord de gestion de conteneurs sur une IP publique sans authentification ne nécessite pas un attaquant sophistiqué. Il suffit qu'il connaisse l'adresse. C'est une barrière bien plus basse que la plupart des équipes ne le pensent.

Les outils de surveillance et de gestion auto-hébergés sont généralement déployés avec une interface web accessible sur toutes les interfaces réseau. Les laisser sur une IP publique sans authentification, c'est l'équivalent conteneur d'un panneau d'administration laissé ouvert à tous.
Authentification, reverse proxy et placement en réseau privé constituent le minimum requis. Le contrôle d'accès est une étape de configuration à ajouter à toute interface d'administration — ce n'est pas quelque chose d'activé par défaut.
Le même principe s'applique à la gestion en ligne de commande et en interface graphique de Docker; un accès de niveau administrateur au daemon présente le même risque quelle que soit l'interface utilisée.
Ne pas surveiller l'activité de vos conteneurs
Si un conteneur est compromis, l'activité de l'attaquant laisse des traces : changements de comportement des processus, connexions réseau inhabituelles et modifications de fichiers inattendues. Sans collecte de journaux en place, ces traces n'existent pas sous une forme exploitable.
La collecte centralisée des journaux, l'audit des conteneurs et les outils de surveillance à l'exécution vous donnent les données nécessaires pour détecter une activité anormale avant qu'elle ne s'aggrave. L'objectif n'est pas d'analyser chaque ligne, mais d'avoir les données disponibles au moment où vous devez enquêter.
Des conteneurs qui tournent silencieusement en production sans pipeline de journaux ni alertes ne sont pas faciles à maintenir. Ils sont simplement non supervisés. Ce sont deux états opérationnels bien distincts.
Pourquoi l'environnement d'infrastructure joue aussi un rôle
La sécurité des conteneurs commence par la configuration, mais cette configuration s'exécute sur une infrastructure. Un hôte avec un réseau mal configuré, des ressources partagées ou aucun filtrage au niveau réseau crée des conditions qui affectent chaque conteneur qui tourne dessus. Bien configurer les conteneurs et bien configurer le serveur sont deux tâches distinctes.
De nombreuses failles de sécurité Docker sont amplifiées par des conditions héritées des conteneurs eux-mêmes :
- Un serveur mutualisé sans isolation matérielle entre les locataires
- Un noyau hôte fonctionnant sans correctifs à jour
- Un hôte sans filtrage réseau intégré
Cela ne supprime pas la nécessité des étapes de configuration ci-dessus, car un durcissement approprié des conteneurs est important quelle que soit la couche d'infrastructure. Démarrer sur une infrastructure isolée élimine simplement un niveau de préoccupation de l'équation.
Chez Cloudzy, nous proposons deux options selon les besoins de votre configuration :
- Linux VPS: un environnement propre pour déployer Docker vous-même et appliquer les étapes de durcissement décrites dans cet article
- Portainer VPS: une option en un clic avec Portainer préinstallé ; le serveur démarre et vous êtes directement dans le tableau de bord
Les deux options reposent sur la même infrastructure : virtualisation KVM, processeurs AMD Ryzen 9 CPU cadencés jusqu'à 5,7 GHz en boost, mémoire DDR5, stockage NVMe SSD, réseau jusqu'à 40 Gbps, et protection DDoS gratuite via le filtrage BuyVM, sur 12 sites dans le monde avec une disponibilité garantie à 99,95 % SLA.
Pour aller plus loin sur l'utilisation de Portainer sur un VPS, nous y consacrons un article dédié.
Liste de contrôle de sécurité pour les déploiements Docker
La plupart des erreurs de sécurité Docker listées ci-dessus résultent de choix de configuration faits une seule fois et jamais réévalués. Passer cette liste en revue sur une installation existante permet de combler ces lacunes. C'est un outil d'audit, pas un guide de déploiement.
Ces bonnes pratiques de sécurité Docker expliquent comment protéger les conteneurs Docker contre les erreurs de configuration les plus courantes décrites ci-dessus.
Récapitulatif : les 9 erreurs
| Erreur | Catégorie | Correction rapide |
| Exécution en tant que root | Paramètres | Ajouter la directive USER à votre fichier Docker |
| Ports liés à 0.0.0.0 | Paramètres | Lier à 127.0.0.1 et router via un reverse proxy |
| Aucune isolation réseau | Paramètres | Répartir les services sur des réseaux distincts définis par l'utilisateur selon les besoins d'accès. |
| Socket Docker monté | Paramètres | Supprimer le montage ; utiliser des API limités ou des alternatives |
| Images non fiables ou obsolètes | Image | Utiliser des images officielles avec des tags de version fixés |
| Secrets codés en dur | Image | Déplacer les identifiants vers des variables d'environnement à l'exécution ou un gestionnaire de secrets |
| Aucun calendrier de reconstruction des images | Image | Définir un calendrier de reconstruction mensuel ; automatiser autant que possible |
| Tableaux de bord non authentifiés | Accès | Ajouter une authentification et déplacer les interfaces de gestion vers des réseaux privés |
| Aucune collecte des journaux de conteneurs | Accès | Mettre en place une journalisation centralisée et une surveillance des environnements d'exécution |
Nous recommandons de l'exécuter d'abord sur des configurations existantes, car c'est là que les lacunes sont le plus susceptibles d'être déjà présentes.
Conteneurs exécutés en tant que non-root : Vérifiez vos fichiers Docker à la recherche d'une directive USER. En l'absence de celle-ci, le conteneur s'exécute en tant que root.
Liaisons de ports limitées à localhost ou via un proxy : Exécutez docker ps et examinez les liaisons de ports. Une entrée 0.0.0.0:PORT peut être accessible publiquement sur les hôtes où aucun groupe de sécurité en amont, pare-feu externe ou règle de chaîne DOCKER-USER ne la bloque.
Réseaux bridge personnalisés en place : Les conteneurs sur le bridge par défaut de Docker peuvent se joindre librement. Les conteneurs sur le même bridge défini par l'utilisateur peuvent toujours communiquer entre eux : répartissez donc les services sur des réseaux distincts en fonction des niveaux de confiance pour obtenir une isolation réelle.
Socket Docker non monté dans les conteneurs : Vérifiez les fichiers Compose et les arguments d'exécution. Si /var/run/docker.sock apparaît en tant que volume, confirmez que c'est nécessaire et intentionnel.
Images de base issues d'éditeurs vérifiés avec des versions épinglées : Un FROM ubuntu:latest récupère une version non spécifiée, potentiellement obsolète. Épinglez une version précise.
Aucun secret dans les fichiers Docker, les fichiers Compose ou les arguments de build : L'historique des couches d'image conserve les identifiants après la suppression du conteneur. Utilisez les secrets Compose, les secrets Swarm, les montages secrets de build ou un gestionnaire de secrets externe. Les variables d'environnement à l'exécution valent mieux que des valeurs codées en dur, mais elles apparaissent tout de même dans la sortie d'inspection et les journaux.
Calendrier de reconstruction des images défini : Les images obsolètes accumulent des vulnérabilités. Un calendrier de reconstruction mensuel maintient la fenêtre d'exposition à un niveau gérable pour la plupart des configurations.
Interfaces de gestion protégées par authentification : Tout tableau de bord exposé sur une IP publique sans authentification constitue un point d'entrée ouvert. Un placement en réseau privé est préférable dans la mesure du possible.
Journaux des conteneurs collectés : Sans pipeline de journalisation, la détection d'incidents repose sur des impacts système visibles. C'est un signal trop tardif pour agir efficacement.
Conclusion
La configuration par défaut de Docker est pensée pour la commodité, pas pour la sécurité. La plupart des erreurs abordées dans cet article viennent de paramètres qui n'ont jamais été modifiés après le déploiement initial, et non d'attaques sophistiquées.
Les corrections sont pour la plupart des décisions de configuration ponctuelles : une directive USER, un changement de liaison de port, un réseau personnalisé, un calendrier de reconstruction. Aucune d'elles n'exige de nouveaux outils pour la majorité des configurations.
Configurer correctement le conteneur est la première étape. L'infrastructure sur laquelle il tourne est la deuxième. Les deux comptent, et l'une ne remplace pas l'autre.