Sécurité des conteneurs Docker en production : Trivy, Falco et durcissement
Sécuriser vos conteneurs Docker : scan d'images avec Trivy, runtime security avec Falco, Dockerfile best practices, rootless containers, seccomp et AppArmor, et gestion des secrets.
Les menaces spécifiques aux conteneurs
Les conteneurs Docker offrent isolation et reproductibilité, mais leur sécurité présente des défis particuliers. Contrairement aux VM, les conteneurs partagent le kernel du système hôte — une vulnérabilité kernel peut permettre une évasion de conteneur vers l'hôte. En 2024, des centaines de milliers d'images Docker publiques contenaient des vulnérabilités critiques, dont des images de bases populaires non maintenues.
Vecteurs d'attaque courants
- Images vulnérables : des CVE critiques dans les packages de l'image de base (Alpine, Ubuntu, Debian) permettant une escalade de privilèges ou une RCE
- Privilege escalation : conteneurs lancés en root, capabilities Linux excessives, volumes montés sans restriction permettant l'accès au filesystem hôte
- Secrets dans les layers Docker : clés API, mots de passe dans les layers d'image — même supprimés, ils restent dans les layers précédentes et peuvent être extraits
- Docker socket exposé : monter `/var/run/docker.sock` dans un conteneur donne un accès root complet à l'hôte Docker
- Images non vérifiées : images `latest` sans digest SHA, images de registries non officiels pouvant être falsifiées
- Supply chain : des dépendances dans le Dockerfile (apt packages, npm, pip) compromises lors du build
Scanner les images avec Trivy
Trivy (Aqua Security) est l'outil de scan de vulnérabilités pour conteneurs le plus utilisé. Il détecte les CVE dans les packages OS et les dépendances applicatives, les secrets exposés et les mauvaises configurations.
Types de scan Trivy
- Image scan : `trivy image nginx:latest` scanne tous les packages dans l'image et retourne les CVE par sévérité (CRITICAL, HIGH, MEDIUM, LOW)
- Filesystem scan : `trivy fs .` scanne le répertoire courant (package.json, requirements.txt, pom.xml) pour les dépendances vulnérables
- Repository scan : `trivy repo github.com/org/repo` scanne un repo GitHub directement
- SBOM generation : `trivy image --format cyclonedx nginx` génère un Software Bill of Materials en CycloneDX ou SPDX
- Secrets scan : détection de secrets dans les layers Docker (clés AWS, tokens GitHub, etc.)
- Config scan : détection de mauvaises configurations Dockerfile et Kubernetes (ex. conteneur privileged, hostNetwork, etc.)
Intégration CI/CD
- GitHub Action Aqua Security/trivy-action pour scanner automatiquement toutes les images buildées
- Bloquer le push vers le registry si des vulnérabilités CRITICAL sont détectées
- Rapport SARIF pour les annotations GitHub Advanced Security dans les PRs
- Scan périodique des images en production (les CVE nouvelles apparaissent continuellement)
Dockerfile best practices de sécurité
La sécurité commence dans le Dockerfile :
Images de base
- Images minimales : utiliser `scratch` (vide), `distroless` (Google) ou Alpine (3 MB) plutôt que Ubuntu/Debian complet — moins de packages = moins de CVE
- Images officielles uniquement : utiliser des images officielles Docker Hub vérifiées (badge officiel) ou des images de registries de confiance (ECR Public, GHCR)
- Pin par digest : `FROM alpine:3.19.1@sha256:abc123...` au lieu de `FROM alpine:latest` pour une reproductibilité et une sécurité maximale
- Multi-stage builds : builder dans une image complète, copier uniquement les artefacts nécessaires dans l'image finale minimale
Utilisateur non-root
- Ajouter `RUN useradd -r -u 1001 appuser && chown -R appuser /app` dans le Dockerfile
- Terminer le Dockerfile avec `USER 1001` pour lancer l'application en non-root
- Kubernetes : ajouter `runAsNonRoot: true` et `runAsUser: 1001` dans le SecurityContext du Pod
Minimiser les layers et ne pas exposer de secrets
- Ne jamais passer de secrets en argument ARG (ils apparaissent dans `docker history`)
- Utiliser des build secrets Docker (`--mount=type=secret`) pour les tokens de build
- Ne pas inclure de fichiers `.env` ou de credentials dans l'image — utiliser `.dockerignore`
- Combiner les commandes RUN pour minimiser les layers et la surface d'attaque
Runtime security avec Falco
Falco (CNCF) est l'outil de référence pour la détection des comportements anormaux des conteneurs en temps réel. Il utilise les syscalls Linux pour détecter les activités suspectes :
- Règles prédéfinies : détection des shells lancés dans des conteneurs (ex. `bash` dans un conteneur nginx — signe d'un attaquant), écriture dans des répertoires système, lecture de `/etc/shadow`
- Exécution de fichiers binaires : détecter si un conteneur exécute un binaire non présent à l'origine (ex. téléchargement et exécution d'un exploit)
- Connexions réseau inattendues : un conteneur de base de données qui initie une connexion sortante vers Internet est suspect
- Privileges escalation : tentatives de `sudo`, `su`, ou d'exploitation de capabilities Linux
- Alertes en temps réel : Falco peut envoyer des alertes vers Slack, Elasticsearch, Prometheus ou un SIEM via des plugins
Déploiement Falco
- Déployable en DaemonSet Kubernetes (un pod Falco par nœud) ou en mode standalone sur Docker
- eBPF driver (recommandé sur les kernels récents) ou kernel module pour la capture des syscalls
- Falco Sidekick : composant companion qui route les alertes Falco vers de multiples destinations (Slack, Teams, PagerDuty, SIEM)
Seccomp et AppArmor : limiter les syscalls
- Seccomp (Secure Computing Mode) : filtre les syscalls autorisés pour un conteneur. Docker applique un profil par défaut restreignant ~44 syscalls dangereux. Créer des profils personnalisés encore plus restrictifs pour les conteneurs critiques.
- AppArmor : système de contrôle d'accès obligatoire (MAC) limitant les fichiers, capacités et opérations réseau du conteneur. Docker applique le profil `docker-default` par défaut.
- Linux capabilities : utiliser `--cap-drop ALL --cap-add NET_BIND_SERVICE` pour ne garder que les capabilities strictement nécessaires. Ne jamais utiliser `--privileged` en production.
- Read-only filesystem : `docker run --read-only` ou `readOnlyRootFilesystem: true` en Kubernetes pour éviter les modifications du filesystem du conteneur (obligatoire à monter les répertoires variables en tmpfs)
Gestion des secrets en production
- HashiCorp Vault : secrets dynamiques avec rotation automatique, accès via agent sidecar ou Vault Secrets Operator pour Kubernetes
- AWS Secrets Manager / Parameter Store : intégration native avec les pods EKS via IRSA (IAM Roles for Service Accounts)
- Kubernetes Secrets chiffrés : activer le chiffrement des Secrets Kubernetes at rest dans etcd (chiffrement KMS provider)
- External Secrets Operator : synchronise des secrets depuis des sources externes (Vault, AWS SM) vers des Kubernetes Secrets
- Never en variables d'environnement : préférer les fichiers montés en volume plutôt que les variables d'environnement (visibles dans `docker inspect`, `ps` ou les logs de crash)
Conclusion
La sécurité des conteneurs en production est une discipline à part entière qui couvre le build (scan d'images, Dockerfile best practices), le déploiement (seccomp, AppArmor, capabilities) et le runtime (Falco, monitoring). L'approche progressive recommandée : commencer par le scan d'images Trivy dans la CI/CD, puis activer Falco en mode surveillance, puis progressivement durcir les Dockerfiles et les SecurityContext Kubernetes. La sécurité des conteneurs fait partie intégrante d'une démarche DevSecOps mature.
Besoin d'un accompagnement en cybersécurité ?
CloudSecure vous aide à sécuriser votre infrastructure cloud et à protéger vos données.
Contactez-nous