Vous pouvez exécuter Docker en production pendant des mois sans problème visible. Les conteneurs démarrent, les applications répondent, rien ne se casse. Un port exposé ou une autorisation mal configurée crée alors une position qu’un attaquant n’avait pas besoin de gagner. La plupart des erreurs de sécurité Docker ne ressemblent pas à des erreurs jusqu'à ce que quelque chose se passe mal.
Cet article couvre les configurations spécifiques qui mettent les environnements de conteneurs en danger, ce que chacune permet à un attaquant, et se termine par une liste de contrôle que vous pouvez exécuter sur votre propre configuration aujourd'hui.
Pourquoi la sécurité Docker est plus difficile qu'il n'y paraît
Les conteneurs semblent isolés. Vous en démarrez un, il exécute son propre espace de processus et, de l’intérieur, le conteneur suivant n’existe pas. Vous bénéficiez d’un isolement, mais ce n’est que partiel. Les conteneurs partagent le noyau de l’hôte, ce qui signifie qu’un processus à l’intérieur d’un conteneur peut, dans des conditions spécifiques, atteindre entièrement le système hôte.
Les navires Docker sont configurés pour la commodité des développeurs et non pour le renforcement de la production. Accès root activé. Tous les ports peuvent être liés à toutes les interfaces. Aucune surveillance d'exécution. La plupart des développeurs acceptent ces paramètres, expédient le conteneur et passent à autre chose. C’est une approche raisonnable pour commencer ; ce n’est pas une posture de sécurité terminée.
Selon Rapport Red Hat sur l'état de la sécurité de Kubernetes en 2024, 67 % des organisations ont retardé ou ralenti le déploiement d'applications en raison de problèmes de sécurité des conteneurs ou de Kubernetes. Ces frictions ne proviennent généralement pas d’attaques. Cela vient du fait que les équipes ont découvert que leurs configurations de conteneurs avaient besoin d’être renforcées et qu’elles n’avaient pas intégré.
Nous voyons souvent des conteneurs s’exécuter en production avec la même configuration que celle dont ils disposaient sur la machine locale d’un développeur. C’est là que les erreurs de sécurité de Docker ont tendance à s’aggraver discrètement, sans aucun symptôme visible jusqu’à ce que quelque chose soit audité ou échoue.
Les erreurs qui créent ces lacunes sont spécifiques, prévisibles et pour la plupart évitables, dès le niveau de la configuration.
Erreurs courantes de configuration de Docker
La plupart des violations de conteneurs ne commencent pas par un exploit zero-day. Ils commencent par une configuration définie dès le premier jour, sans trop réfléchir à l’exposition du réseau ou à l’étendue des privilèges.
Les paramètres Docker par défaut sont conçus pour fonctionner. C'est dans l'écart entre fonctionnel et sécurisé que les risques de sécurité des conteneurs Docker s'accumulent, en particulier dans les configurations auto-hébergées qui sont déployées et jamais revisitées.
Nous voyons souvent ce modèle : des conteneurs sur des serveurs IP publics avec des liaisons de port, des paramètres utilisateur et des configurations réseau exactement tels qu'ils étaient lors du déploiement initial.
Exécuter des conteneurs en tant que root
Lorsque vous démarrez un conteneur Docker sans spécifier d'utilisateur, il s'exécute en tant que root. Cela signifie que tout processus à l’intérieur du conteneur, y compris votre application, dispose de privilèges de niveau racine dans l’espace de noms du conteneur.

La racine à l’intérieur d’un conteneur n’est pas la même chose que la racine 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 runc CVE-2019-5736 bien documenté et les failles d'exécution similaires, nécessitent souvent un processus de conteneur racine pour réussir.
Les conteneurs non root suppriment l'exigence de processus racine dont dépendent ces exploits, réduisant considérablement la surface d'attaque pour cette classe de vulnérabilité, bien qu'ils n'éliminent pas complètement le risque d'évasion des conteneurs.
L'ajout d'une directive USER à votre Dockerfile résout ce problème. Certaines images officielles sont livrées avec un utilisateur non privilégié que vous pouvez activer avec une directive USER, mais beaucoup sont toujours par défaut root sans utilisateur d'application prêt à l'emploi. Dans ces cas, vous créez l'utilisateur dans le Dockerfile avant d'y accéder. Pour la plupart des configurations auto-hébergées, cette seule modification supprime toute une catégorie de risque d’escalade.
Exposer trop de ports à l'Internet public
Lorsque vous publiez un port avec Docker, Docker écrit directement ses propres règles iptables. Ces règles s'exécutent avant les règles de pare-feu au niveau de l'hôte. C'est un comportement bien connu rapporté par la communauté et documenté dans le guide de filtrage de paquets de Docker, il ne s'agit pas d'une mauvaise configuration, et cela signifie qu'UFW et les outils similaires ne bloquent pas ce que Docker a déjà ouvert.

Docker écrit directement sur iptables, en contournant les valeurs par défaut d'UFW et de firewalld sur de nombreux hôtes Linux. Cela signifie qu'un port lié à 0.0.0.0 peut être accessible publiquement même lorsque votre pare-feu semble configuré. Les groupes de sécurité cloud et les règles de la chaîne DOCKER-USER peuvent toujours bloquer ce trafic, l'exposition réelle dépend donc de la configuration spécifique de votre réseau.
Liez les services à 127.0.0.1 lorsque cela est possible, acheminez le trafic public via un proxy inverse et publiez uniquement ce qui nécessite réellement un accès externe. Un proxy inverse est le moyen le plus fiable de contrôler ce qui est exposé depuis l’extérieur de l’hôte.
Ignorer l'isolation du réseau entre les conteneurs
N'importe quel conteneur sur ce réseau peut atteindre n'importe quel autre conteneur sans restriction. Le pont par défaut n'applique aucun filtrage du trafic entre les conteneurs qui le partagent, et la plupart des configurations ne modifient jamais cette configuration.

Si un conteneur est compromis, cette communication ouverte devient une voie de mouvement latérale. Un conteneur frontal peut atteindre une base de données, une API interne ou tout autre élément sur le même réseau de pont par défaut, même lorsque cet accès n'a jamais été prévu.
Les réseaux définis par l'utilisateur vous donnent un contrôle explicite sur les conteneurs qui peuvent communiquer, mais un seul réseau personnalisé partagé par tous vos services permet toujours un trafic gratuit entre conteneurs. Une véritable isolation nécessite de placer des services qui ne devraient pas communiquer entre eux sur des réseaux distincts. La désactivation du pont par défaut est le point de départ et non la ligne d'arrivée.
Surplombant le Docker Socket
Le socket Docker dans /var/run/docker.sock est l'interface de contrôle de l'ensemble du moteur Docker. Le monter dans un conteneur donne à ce conteneur un accès API direct au démon exécuté sur l'hôte.

Avec cet accès, un conteneur peut démarrer de nouveaux conteneurs, monter des répertoires hôtes, inspecter et modifier les conteneurs en cours d'exécution et contrôler efficacement la machine hôte. La surface d'attaque est équivalente à celle du root sur l'hôte, c'est pourquoi tout outil nécessitant un accès socket mérite une évaluation minutieuse.
Pour la plupart des cas d'utilisation, il existe des alternatives plus sûres : des API limitées ou Outils de gestion Docker qui ne nécessitent pas d’accès au socket. Docker-in-Docker comporte ses propres compromis en matière de sécurité et de fonctionnement et ne constitue pas un simple substitut.
Les erreurs de configuration créent l’exposition initiale. Les choix d’image et de dépendance déterminent la façon dont cette exposition se compose au fil du temps.
Des erreurs d’image et de secrets qui durent plus longtemps que le conteneur
Lorsque vous arrêtez un conteneur, les erreurs de configuration qu'il contient s'arrêtent avec lui. Lorsque vous reconstruisez à partir d'une image comportant une vulnérabilité ou des informations d'identification codées en dur, le problème redémarre avec le conteneur. Les erreurs au niveau de l’image ne sont pas réinitialisées entre les déploiements.
Ils voyagent avec l'image dans chaque environnement qui l'extrait, dans chaque registre qui la stocke et dans 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 distincte, qui mérite d'être auditée séparément de la configuration.
Nous voyons souvent ce schéma : une image choisie avec soin au début du projet et jamais reconstruite depuis, s’éloignant lentement de la base de sécurité qu’elle représentait initialement.
Utilisation d'images non fiables ou obsolètes
Les registres publics sont ouverts à tous. Des images malveillantes ont été distribuées via Docker Hub contenant des crypto-mineurs et des portes dérobées intégrées dans l'historique des couches qui persistent lors des redémarrages des conteneurs. Vérification avant retrait, notamment pour les images provenant d'éditeurs non officiels ou inconnus.

Le problème distinct est l’obsolescence. Une image officielle que vous avez extraite il y a six mois et que vous n'avez jamais reconstruite depuis accumule des vulnérabilités Docker non corrigées avec chaque CVE divulguée par rapport à ses packages. L’image n’est pas cassée. Ce n’est tout simplement plus d’actualité.
Rapport 2024 sur l'état de la chaîne d'approvisionnement logicielle de Sonatype a constaté que 95 % du temps, un composant vulnérable est utilisé, une version corrigée est déjà disponible et 80 % des dépendances des applications ne sont pas mises à niveau pendant plus d'un an. Ce modèle est également pertinent pour les images de base Docker, car elles reposent sur les mêmes packages open source.
Utilisez des images officielles provenant d'éditeurs vérifiés et épinglez des balises de version spécifiques plutôt que de vous fier à la « dernière ». Créez une cadence de reconstruction régulière pour garder vos images à jour.
Secrets de codage en dur dans les fichiers Dockerfiles et les fichiers Compose
Les informations d'identification écrites dans une instruction Dockerfile ENV ou ARG, codées en dur dans un bloc d'environnement Compose, transmises en tant qu'arguments de construction ou stockées dans un fichier .env validé pour le contrôle de version ne disparaissent pas lorsque vous arrêtez le conteneur. Ils restent dans l’historique de la couche d’image ou dans le contrôle de source, accessibles à toute personne pouvant accéder à l’un ou l’autre.

Il s’agit de l’une des erreurs de sécurité Docker les plus négligées, car elle ne provoque pas de problèmes visibles lors du développement. Une clé API dans une instruction ENV fonctionne correctement. Il est également dans votre référentiel, intégré à votre image et distribué partout où cette image voyage.
Modern Docker Compose prend en charge un mécanisme de secrets natif qui monte les informations d'identification au moment de l'exécution sans les intégrer dans l'image. L'API de secrets de Docker et les gestionnaires de secrets externes suivent le même principe. Ce sont les options qui maintiennent les informations d'identification totalement à l'écart des artefacts de construction et des fichiers validés.
Les variables d'environnement d'exécution constituent une amélioration par rapport aux informations d'identification codées en dur, mais elles sont toujours exposées via la sortie d'inspection Docker, les journaux et les vidages sur incident. Il s’agit d’une avancée par rapport aux secrets bien ancrés, et non d’une solution finie.
Ne pas mettre à jour régulièrement les images des conteneurs
Utiliser la même image pendant des mois est une habitude courante. Chaque jour qui s'écoule après la découverte d'une nouvelle vulnérabilité, mais avant la reconstruction, vos conteneurs comportent une fenêtre d'exposition qui s'agrandit sans aucun changement visible.
Établissez un calendrier de reconstruction cohérent. Automatisez ce processus dans la mesure du possible et exécutez périodiquement un scanner de vulnérabilités sur vos images actuelles. Le but n’est pas la perfection. Cela réduit le délai entre la publication d’un correctif et son déploiement.
Le contrôle d’accès et la surveillance peuvent perdre la priorité lors de déploiements rapides. Ce sont également les catégories dans lesquelles les incidents restent le plus longtemps non détectés.
Contrôle d’accès et lacunes de visibilité
Une fois qu'un conteneur s'exécute avec une configuration solide et des images actuelles, deux catégories d'échec subsistent. Les deux sont invisibles par nature : vous ne remarquerez pas un problème de contrôle d’accès faible jusqu’à ce que quelqu’un l’utilise, et vous ne remarquerez pas d’écart de surveillance jusqu’à ce que vous ayez besoin d’enquêter sur une activité qui n’a jamais été enregistrée.
Le même Recherche Red Hat 2024 a constaté que 42 % des équipes ne disposaient pas de capacités suffisantes pour gérer la sécurité des conteneurs et les menaces associées.
Nous constatons que les lacunes en matière de surveillance apparaissent généralement lors des enquêtes sur les incidents, pas avant. Lorsque la visibilité devient une priorité, il s’agit souvent de réagir à quelque chose plutôt que de l’empêcher.
Authentification faible et tableaux de bord de gestion exposés
Un tableau de bord de gestion de conteneurs sur une IP publique sans authentification ne nécessite pas un attaquant sophistiqué. Cela nécessite qu’ils connaissent l’adresse. C’est une barre plus basse que ce que la plupart des équipes pensent.

Les outils de surveillance et de gestion auto-hébergés sont généralement livrés avec une interface Web accessible sur toutes les interfaces réseau. Laisser ceux sur une adresse IP publique sans authentification devant eux équivaut à laisser un panneau d'administration déverrouillé.
L'authentification, un proxy inverse et le placement sur un réseau privé constituent la base. Le contrôle d'accès est une étape de configuration que vous ajoutez à n'importe quelle interface de gestion, et non quelque chose qui est activé.
Le même principe s'applique à Gestion de Docker CLI et GUI; L'accès au niveau administrateur au démon comporte le même risque quelle que soit l'interface.
Ne pas surveiller ce que font vos conteneurs
Si un conteneur est compromis, l’activité de l’attaquant crée une trace : changements de comportement des processus, connexions réseau inhabituelles et modifications de fichiers inattendues. Sans collecte de journaux en place, cette piste n’existe pas sous une forme sur laquelle vous pouvez agir.
La collecte centralisée des journaux, la journalisation d'audit des conteneurs et les outils de surveillance de l'exécution vous fournissent les données nécessaires pour détecter les activités anormales avant qu'elles ne s'aggravent. Le but n’est pas d’analyser chaque ligne. Il s’agit d’avoir les données disponibles lorsque vous avez besoin d’enquêter.
Les configurations de conteneurs qui s'exécutent silencieusement en production, sans pipeline de journaux et sans alertes, ne nécessitent pas peu de maintenance. Ils ne sont pas inspectés. Ce sont deux états opérationnels différents.
Pourquoi l’environnement des infrastructures est également important
La sécurité des conteneurs commence par la configuration, mais celle-ci s'exécute au-dessus de l'infrastructure. Un hôte avec un réseau mal configuré, des ressources partagées ou aucun filtrage au niveau du réseau crée des conditions qui affectent chaque conteneur situé au-dessus de lui. Obtenir la bonne configuration du conteneur et la bonne configuration du serveur sont deux tâches distinctes.
De nombreuses failles de sécurité de Docker sont amplifiées par les conditions dont les conteneurs eux-mêmes héritent :
- Un serveur en location partagée sans isolation matérielle entre les locataires
- Un noyau hôte exécuté sans correctif
- Un hôte sans filtrage intégré au niveau du réseau
Cela ne supprime pas la nécessité des étapes de configuration ci-dessus, car un renforcement approprié des conteneurs est important quelle que soit la couche d'infrastructure. Commencer sur une infrastructure isolée élimine une couche de préoccupation de l’équation.
Chez Cloudzy, nous proposons deux chemins en fonction des besoins de votre configuration :
- Serveur virtuel Linux: un environnement propre pour déployer Docker vous-même et appliquer les étapes de renforcement de cet article
- Portainer VPS: une option en un clic avec Portainer préinstallé ; le serveur démarre, et vous êtes déjà dans le tableau de bord
Les deux options fonctionnent sur la même infrastructure : virtualisation KVM, processeurs AMD Ryzen 9 avec une horloge boost jusqu'à 5,7 GHz, mémoire DDR5, stockage SSD NVMe, réseau jusqu'à 40 Gbit/s et protection DDoS gratuite via le filtrage BuyVM, sur plus de 12 emplacements dans le monde avec un SLA de disponibilité de 99,95 %.
Pour un aperçu plus approfondi de l'exécution de Portainer sur un VPS, nous en parlons dans un article dédié.
Une liste de contrôle de sécurité pratique pour les déploiements Docker
Les erreurs de sécurité Docker ci-dessus proviennent pour la plupart de décisions de configuration uniques prises une seule fois et jamais revisitées. L’exécution de cette liste de contrôle sur une configuration existante permet de combler ces lacunes. Il fonctionne comme un audit et non comme un guide de déploiement.
Ces bonnes pratiques de sécurité Docker expliquent comment sécuriser les conteneurs Docker contre les échecs de configuration les plus courants décrits ci-dessus.
Référence rapide : les 9 erreurs
| Erreur | Catégorie | Correction sur une seule ligne |
| Exécuter en tant que root | Configuration | Ajouter UTILISATEUR directive à votre Dockerfile |
| Ports liés à 0.0.0.0 | Configuration | Liez-vous à 127.0.0.1 et acheminez via un proxy inverse |
| Pas d'isolation du réseau | Configuration | Répartissez les services sur des réseaux distincts définis par l'utilisateur en fonction des besoins d'accès. |
| Prise Docker montée | Configuration | Retirez le support ; utiliser des API ou des alternatives ciblées |
| Images non fiables ou obsolètes | Image | Utilisez des images officielles avec des balises de version épinglées |
| Secrets codés en dur | Image | Déplacer les informations d'identification vers des variables d'environnement d'exécution ou un gestionnaire de secrets |
| Aucun calendrier de reconstruction d'image | Image | Définir une cadence de reconstruction mensuelle ; automatiser si possible |
| Tableaux de bord non authentifiés | Accéder | Ajoutez l'authentification et déplacez les interfaces utilisateur de gestion vers des réseaux privés |
| Aucune collecte de journaux de conteneur | Accéder | Configurer une journalisation centralisée et une surveillance de l'exécution |
Nous vous recommandons de l’exécuter d’abord sur les configurations existantes, car c’est là que les lacunes sont les plus susceptibles d’être déjà présentes.
Conteneurs exécutés en tant que non-root : Vérifiez vos Dockerfiles pour une directive USER. S'il n'en existe pas, le conteneur s'exécute en tant que root.
Liaisons de port limitées à localhost ou proxy : Exécutez Docker PS et examinez les liaisons de port. Une entrée 0.0.0.0:PORT peut être accessible publiquement sur les hôtes où aucun groupe de sécurité en amont, aucun pare-feu externe ou règle de chaîne DOCKER-USER ne la bloque.
Réseaux de ponts personnalisés utilisés : Les conteneurs sur le pont par défaut de Docker peuvent s'atteindre librement. Les conteneurs sur le même pont défini par l'utilisateur peuvent toujours communiquer entre eux, donc répartissez les services sur des réseaux distincts par limite de confiance pour une isolation réelle.
Socket Docker non monté dans des conteneurs : Vérifiez Composer les fichiers et exécutez les arguments. Si /var/run/docker.sock apparaît comme un volume, confirmez que c'est obligatoire et intentionnel.
Images de base provenant d'éditeurs vérifiés avec des versions épinglées : Un FROM ubuntu:latest extrait une version non spécifiée et potentiellement obsolète. Épinglez sur une version spécifique.
Aucun secret dans les Dockerfiles, les fichiers Compose ou les arguments de build : L'historique de la couche d'image conserve les informations d'identification après la suppression du conteneur. Utilisez Compose secrets, Swarm secrets, créez des montages secrets ou un gestionnaire de secrets externe. Les variables d'environnement d'exécution sont meilleures que les valeurs codées en dur, mais apparaissent toujours dans la sortie d'inspection et les journaux.
Calendrier de reconstruction d'image défini : Les anciennes images accumulent des vulnérabilités. Une cadence de reconstruction mensuelle maintient la fenêtre d'exposition gérable pour la plupart des configurations.
Interfaces de gestion derrière l'authentification : Tout tableau de bord sur une IP publique sans authentification est un point d'entrée ouvert. Le placement sur un réseau privé est préférable lorsque cela est possible.
Journaux de conteneur en cours de collecte : Sans pipeline de journaux, la détection des incidents dépend de l’impact visible sur le système. C’est un signal tardif pour agir.
Conclusion
La configuration par défaut de Docker est conçue pour des raisons de commodité et non de sécurité. La plupart des erreurs abordées dans cet article remontent à des paramètres qui n'ont jamais été modifiés après le déploiement initial, et non à des attaques sophistiquées.
Les correctifs 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. Aucun d'entre eux ne nécessite de nouveaux outils pour la plupart des configurations.
Obtenir la bonne configuration du conteneur est la première tâche. L'infrastructure sur laquelle il fonctionne est la deuxième. Les deux comptent et aucun ne remplace l’autre.