Pourquoi êtes-vous ici ?
Vous voulez connaître la vraie réponse à deux questions sur la sécurité Docker :
Docker est-il sécurisé pour une utilisation en production ?
Oui et non. Docker utilise un modèle de sécurité qui repose sur les espaces de noms et l'isolation des ressources, rendant les processus internes plus sécurisés contre certaines attaques que l'exécution de vos applications directement depuis une VM cloud ou un système bare metal. Malgré cette couche, il existe encore de nombreuses façons pour les attaquants d'accéder à votre conteneur, leur permettant de lire des informations confidentielles, de lancer des attaques par déni de service (DoS), ou même d'obtenir un accès root au système hôte.
Comment puis-je améliorer la sécurité de mon Docker (sans que ce soit trop douloureux) ?
Nous vous présenterons les vulnérabilités Docker les plus courantes et les plus critiques, en ignorant les recommandations de base que vous trouverez partout sur Google, comme l'utilisation d'images officielles et la mise à jour de votre hôte. Au lieu de cela, nous vous guiderons directement vers de nouvelles options Docker et des lignes de Dockerfile qui rendront le déploiement par défaut de vos conteneurs Docker bien plus sécurisé que jamais.

La checklist de sécurité Docker sans bla-bla
Rendre les systèmes de fichiers des conteneurs en lecture seule
Qu'y gagnez-vous ?
Vous empêchez un attaquant de modifier l'environnement runtime de votre conteneur Docker, ce qui pourrait lui permettre de collecter des informations utiles sur votre infrastructure, de recueillir des données utilisateur, ou de mener directement une attaque DOS ou par ransomware.
Comment le configurer ?
Deux options s'offrent à vous : soit au runtime, soit au sein de votre configuration Docker Compose.
Au runtime : docker run --read-only your-app:v1.0.1
Dans votre fichier Docker Compose :
services:
webapp:
image: your-app:v1.0.1read_only: true
...Verrouiller l'escalade de privilèges
Qu'y gagnez-vous ?
Vous empêchez votre conteneur Docker – ou un attaquant qui s'y introduirait – d'activer de nouveaux privilèges, même au niveau root, avec setuid ou setgid. Avec un accès plus permissif à votre conteneur, un attaquant pourrait accéder à des identifiants sous forme de mots de passe ou de clés vers des composants connectés de votre déploiement, comme une base de données.
Comment le configurer ?
Encore une fois, au runtime ou au sein de votre configuration Docker Compose.
Au runtime : docker run --security-opt=no-new-privileges your-app:v1.0.1
Dans votre fichier Docker Compose :
services:
webapp:
image: your-app:v1.0.1
security_opt:
- no-new-privileges:true
...Isolez vos réseaux de conteneur à conteneur
Qu'y gagnez-vous ?
Par défaut, Docker permet à tous les conteneurs de communiquer via le réseau docker0, ce qui pourrait permettre à un attaquant de se déplacer latéralement d'un conteneur compromis à un autre. Si vous avez des services discrets A et B dans les conteneurs Y et Z, et ils n'ont pas besoin de communiquer directement, isoler leurs réseaux offre la même expérience utilisateur final tout en empêchant le mouvement latéral pour une meilleure sécurité Docker.
Comment le configurer ?
Vous pouvez spécifier des réseaux Docker à l'exécution ou dans votre configuration Docker Compose. Cependant, vous devez d'abord créer le réseau :
docker network create your-isolated-networkAu runtime, ajoutez le --network option: docker run --network your-isolated-network your-app:v1.0.1
Ou l'option équivalente dans votre fichier Docker Compose :
services:
webapp:
image: your-app:v1.0.1
networks:
- your-isolated-network
...Définir un utilisateur non-root approprié
Qu'y gagnez-vous ?
L'utilisateur par défaut au sein d'un conteneur est root, avec un uid de 0. En spécifiant un utilisateur distinct, vous empêchez un attaquant d'élever ses privilèges vers un autre utilisateur capable d'agir sans restrictions, comme root, ce qui annulerait toutes les autres mesures de sécurité Docker que vous avez mis en place avec diligence.
Comment le configurer ?
Créez votre utilisateur pendant le processus de build ou à l'exécution. À l'exécution, vous pouvez soit créer l'utilisateur pour la première fois, soit écraser le UTILISATEUR que vous avez déjà définis lors du build.
Pendant le processus de build, dans votre Dockerfile:
...
RUN groupadd -r your-user
RUN useradd -r -g your-user your-user
USER myuser
...Au runtime : docker run -u your-user your-app:v1.0.1
Abandonner les capacités du noyau Linux
Qu'y gagnez-vous ?
Par défaut, les conteneurs Docker sont autorisés à utiliser un ensemble restreint de capacités du noyau Linux. Vous pourriez penser que les équipes de Docker ont créé cet ensemble restreint pour être entièrement sécurisé, mais de nombreuses capacités existent pour la compatibilité et la simplicité. Par exemple, les conteneurs par défaut peuvent modifier arbitrairement la propriété des fichiers, changer leur répertoire racine, manipuler les UID de processus et lire les sockets. En abandonnant certaines ou toutes ces capacités, vous minimisez le nombre de vecteurs d'attaque.
Comment le configurer ?
Vous pouvez supprimer des capacités et en définir de nouvelles à l'exécution. Par exemple, vous pourriez supprimer toutes les capacités du noyau et n'autoriser votre conteneur qu'à modifier la propriété des fichiers existants.
docker run --cap-drop ALL --cap-add CHOWN your-app:v1.0.1Ou pour Docker Compose :
services:
webapp:
image: your-app:v1.0.1
cap_drop:
- ALL
cap_add:
- CHOWN
...Prévenir les fork bombs
Qu'y gagnez-vous ?
Les attaques de type fork bomb sont une forme d'attaque DoS qui répliquent à l'infini un processus existant. Elles réduisent d'abord les performances et restreignent les ressources, ce qui augmente inévitablement les coûts et peut finalement faire planter vos conteneurs ou le système hôte. Une fois qu'une fork bomb a démarré, le seul moyen de l'arrêter est de redémarrer le conteneur ou l'hôte.
Comment le configurer ?
Au runtime, vous pouvez limiter le nombre de processus (PIDs) que votre conteneur peut créer.
docker run --pids-limit 99 your-app:v1.0.1Ou avec Docker Compose :
services:
webapp:
image: your-app:v1.0.1
deploy
limits:
pids: 99Améliorer la sécurité de Docker en surveillant vos dépendances open source
Qu'y gagnez-vous ?
Les applications que vous avez conteneurisées pour un déploiement avec Docker ont probablement un vaste arbre de dépendances.
Comment le configurer ?
La manière la plus « sans fioritures » est l'analyse des dépendances open source d'Aikido. Notre surveillance continue analyse les projets écrits dans plus d'une douzaine de langages en se basant sur la présence de lockfiles au sein de votre application et fournit un aperçu instantané des vulnérabilités et des malwares. Grâce à un tri automatique qui filtre les faux positifs, Aikido vous offre des conseils de remédiation que vous pouvez appliquer immédiatement… et non seulement après avoir lu une douzaine d'autres documents de référence et d'issues GitHub.
Chez Aikido, nous apprécions les projets open source établis comme Trivy, Syft et Grype. Nous savons également par expérience que les utiliser de manière isolée n'offre pas une expérience développeur particulièrement bonne. Sous le capot, Aikido améliore ces projets avec des règles personnalisées pour combler les lacunes et révéler des failles de sécurité que vous ne seriez pas en mesure de trouver autrement. Contrairement à l'enchaînement de divers outils open source, Aikido vous libère de la nécessité de construire un script d'analyse ou de créer une tâche personnalisée dans votre CI/CD.

Utiliser uniquement des images fiables pour la sécurité Docker
Qu'y gagnez-vous ?
Docker Content Trust (DCT) est un système pour signer et valider le contenu et l'intégrité des images officielles que vous extrayez des registres Docker comme Docker Hub. Le fait de n'extraire que des images signées par l'auteur vous donne plus d'assurance qu'elles n'ont pas été altérées pour créer des vulnérabilités dans votre déploiement.
Comment le configurer ?
Le moyen le plus simple est de définir la variable d'environnement sur votre shell, ce qui vous empêche, vous ou toute autre personne, de travailler avec des images non fiables.
export DOCKER_CONTENT_TRUST=1
docker run ...Ou, vous pouvez définir la variable d'environnement chaque fois que vous exécutez Docker :
DOCKER_CONTENT_TRUST=1 docker run …Mettre à jour les runtimes en fin de vie (EOL)
Qu'y gagnez-vous ?
Une recommandation courante pour la sécurité des conteneurs Docker est d'épingler les images et les dépendances à une version spécifique au lieu de dernière. En théorie, cela vous empêche d'utiliser à votre insu de nouvelles images, même celles qui ont été altérées, et qui introduiraient de nouvelles vulnérabilités.
Comment le configurer ?
Plusieurs projets open source sont disponibles pour vous aider à identifier les fins de vie (EOL) et à mieux vous préparer. Le projet endoflife.date (dépôt GitHub) surveille plus de 300 produits en agrégeant des données provenant de multiples sources et en les rendant disponibles via une API publique. Vous disposez de plusieurs options avec endoflife.date et les projets similaires :
- Vérifiez manuellement le projet pour les mises à jour des dépendances dont dépendent vos applications et créez des tickets ou des problèmes pour les mises à jour requises.
- Écrivez un script (Bash, Python, etc.) pour obtenir les dates EOL des dépendances depuis l'API et exécutez-le régulièrement, comme une tâche cron.
- Intégrez l'API publique, ou ce script personnalisé, dans votre plateforme CI pour faire échouer les builds qui utilisent un projet approchant ou ayant atteint sa fin de vie (EOL).
En tant que développeur, nous comprenons que votre temps est précieux et souvent limité. C'est là qu'Aikido peut apporter un sentiment de sécurité : notre fonctionnalité d'analyse EOL suit votre code et vos conteneurs, en priorisant les runtimes ayant le plus d'impact et d'exposition, comme Node.js ou un serveur web Nginx. Comme d'habitude, nous ne nous contentons pas d'automatiser la collecte d'informations, mais nous fournissons des alertes avec une gravité appropriée pour vous informer, sans vous submerger.

Limiter l'utilisation des ressources des conteneurs
Qu'y gagnez-vous ?
Par défaut, les conteneurs n'ont pas de contraintes de ressources et utiliseront autant de mémoire ou de CPU que le planificateur de l'hôte. Limiter l'utilisation des ressources d'un conteneur spécifique peut minimiser l'impact d'une attaque DoS. Au lieu de faire planter votre conteneur ou système hôte en raison d'une exception de mémoire insuffisante, l'attaque DoS en cours n'aura “que” un impact négatif sur l'expérience de l'utilisateur final.
Comment le configurer ?
Au runtime, vous pouvez utiliser le --memory et --cpus option pour définir des limites d'utilisation de la mémoire et du CPU, respectivement. L'option de mémoire accepte des nombres avec 'g' pour les gigaoctets et 'm' pour les mégaoctets, tandis que l'option CPU reflète la limite de CPU dédiés disponibles pour le conteneur et ses processus.
docker run --memory="1g" --cpus="2" your-app:v1.0.1Cela fonctionne également avec Docker Compose :
services:
webapp:
image: your-app:v1.0.1
deploy:
limits:
cpus: '2'
memory: 1G
...Votre commande finale et les options Compose pour la sécurité Docker
À présent, vous avez découvert de nombreux conseils de sécurité Docker ainsi que les options CLI ou configurations pertinentes qui les accompagnent, ce qui signifie que vous êtes soit très enthousiaste à l'idée de les mettre en œuvre, soit dépassé par la façon de les assembler. Ci-dessous, nous avons regroupé toutes les recommandations dans une seule commande ou un modèle de configuration, ce qui vous aidera à déployer des conteneurs Docker plus sécurisés immédiatement.
Évidemment, vous voudrez modifier certaines des options – telles que le nom d'utilisateur non-root, les capacités du noyau, les limites de ressources – en fonction des besoins de votre application.
export DOCKER_CONTENT_TRUST=1
docker run \
--read-only \
--security-opt=no-new-privileges \
--network your-isolated-network \
--cap-drop ALL
--cap-add CHOWN \
--pids-limit 99 \
--memory="1g" --cpus="2" \
--user=your-user \
... # OTHER OPTIONS GO HERE
your-app:v1.0.1Vous pourriez même vouloir créer un alias drun avec le shell de votre hôte, que vous pourrez invoquer sans avoir à vous souvenir de tous ces détails.
function drun {
docker run \
--read-only \
--security-opt=no-new-privileges \
--network your-isolated-network \
--cap-drop ALL
--cap-add CHOWN \
--pids-limit 99 \
--memory="1g" --cpus="2" \
--user=your-user \
$1 \
$2
}Ensuite, exécutez votre alias comme suit, avec vos options et le nom de l'image : drun -it your-app:v1.0.1
Si vous êtes adepte de Docker Compose, vous pouvez adapter toutes les mêmes options dans un nouveau modèle de base Docker Compose à partir duquel vous pourrez travailler à l'avenir :
services:
webapp:
image: your-app:v1.0.1
read_only: true
security_opt:
- no-new-privileges:true
networks:
- your-isolated-network
cap_drop:
- ALL
cap_add:
- CHOWN
deploy:
limits:
pids: 9
cpus: '2'
memory: 1G
... # AUTRES OPTIONS ICIBonus : Exécuter Docker avec des conteneurs rootless
Lorsque vous installez Docker sur un système, son démon fonctionne avec des privilèges de niveau root. Même si vous activez toutes les options ci-dessus et empêchez l'escalade de privilèges au sein d'un conteneur Docker, le reste du runtime du conteneur sur votre système hôte conserve des privilèges root. Cela élargit inévitablement votre surface d'attaque.
La solution réside dans les conteneurs rootless, qu'un utilisateur non privilégié peut créer et gérer. L'absence de privilèges root implique beaucoup moins de problèmes de sécurité pour votre système hôte.
Nous aimerions pouvoir vous aider à utiliser les Rootless Containers avec une seule option ou commande, mais ce n'est tout simplement pas si simple. Vous trouverez des instructions détaillées sur le site web Rootless Containers, y compris un guide pratique pour Docker.
Quelle est la prochaine étape pour la sécurité de votre Docker ?
Si vous avez appris quelque chose de cette expérience, c'est que la sécurité des conteneurs est une opération de longue haleine. Il y a toujours plus de checklists de renforcement et d'articles d'approfondissement à lire sur la sécurisation de vos conteneurs dans Docker ou son cousin plus ancien et souvent mal compris, Kubernetes. Vous ne pouvez pas viser une sécurité des conteneurs irréprochable — dégager du temps dans votre emploi du temps de développement chargé pour aborder la sécurité, puis apporter des améliorations progressives basées sur l'impact et la gravité, portera ses fruits à long terme.
Pour vous aider à optimiser ce processus continu et à prioriser les correctifs qui amélioreront significativement la sécurité de vos applications, il y a Aikido. Nous venons de lever 17 millions de dollars en série A pour notre plateforme de sécurité développeur « sans fioritures », et nous serions ravis de vous compter parmi nous.
Sécurisez votre logiciel dès maintenant.




