
Container Snitch vérifie les processus en cours d'exécution sous le moteur Docker et alerte si l'un d'eux s'avère tourner en tant que root.
cnitch (snitch ou container snitch) est un framework simple et un outil en ligne de commande pour surveiller les conteneurs Docker et identifier les processus qui s'exécutent en tant que root.
Pourquoi est-ce une mauvaise chose ? Si vous n'êtes pas encore allé sur can I haz non-privileged containers? par mhausenblas, je vous recommande de vous y rendre maintenant pour obtenir toutes les informations.
Lorsque je développais cnitch, je suis tombé sur ce que je pensais être un bug de l'application : cnitch se signalait lui-même comme un processus root dans un conteneur Docker. Je ne comprenais pas comment cela était possible car le Dockerfile indiquait explicitement que je créais un utilisateur sans exécuter en tant que root. Après beaucoup de débogage et de vérification, j'ai décidé de vérifier à nouveau le Dockerfile et j'ai trouvé ceci :
FROM alpine
RUN adduser -h /home/cnitch -D cnitch cnitch
COPY ./cmd/cnitch /home/cnitch/
RUN chmod +x /home/cnitch/cnitch
#USER cnitch
ENTRYPOINT ["/home/cnitch/cnitch"]
Lorsque je testais le conteneur applicatif pour résoudre un problème de permissions sur le socket Docker, j'avais dû commenter la commande USER. Assez méta, cnitch a aidé à trouver un problème avec cnitch, cela va directement dans les tests d'intégration.
cnitch se connecte au moteur Docker via l'API et interroge les conteneurs en cours d'exécution, puis inspecte les processus s'exécutant à l'intérieur de ce conteneur et identifie ceux qui tournent en tant qu'utilisateur root.
Lorsqu'un processus root est trouvé, cette information est envoyée aux modules de rapport configurables, permettant d'auditer ou de prendre des mesures.
2017/07/29 16:04:27 Starting Cnitch: Monitoring Docker Processes at: tcp://172.16.255.128:2376
2017/07/29 16:04:27 Checking for root processes every: 10s
2017/07/29 16:05:08 Checking image: ubuntu, id: 7bd489560a310343c39186500daa680290289c27f7a730524a31355a3aaf0430
2017/07/29 16:05:08 >> WARNING: found process running as root: tail -f /dev/null pid: 365
Actuellement, cnitch peut rapporter les informations vers StatsD et StdOut. Les backend de rapport sont extensibles pour faciliter la prise en charge de n'importe quel backend, par exemple il serait assez simple de construire un backend pour prendre en charge log stash ou un autre outil d'agrégation de fichiers journaux.
Les exceptions sont envoyées au point de terminaison statsD sous forme de compteur avec la métrique cnitch.exception.root_process. Les métriques sont également étiquetées avec le nom d'hôte (host) de l'instance cnitch et le nom du conteneur (container).
Le journal StdOut est un simple journal de sortie qui envoie les exceptions rapportées vers StdOut.
Que vous exécutiez cnitch dans un conteneur Docker ou en tant que binaire, il a besoin d'accéder à l'API Docker en définissant l'URL du serveur ou le chemin du socket via la variable d'environnement DOCKER_HOST
--hostname=[nomd'hôte] le nom ou l'adresse IP à utiliser pour l'agrégation des métriques--statsd-server=[hôte:port] l'URI du collecteur statsd, s'il est omis le rapport statsd sera désactivé--check=[durée ex. 10s (10 secondes), 1m (1 minute)] , la fréquence de vérification à laquelle snitch recherchera les processus rootDéfinissez la variable d'environnement DOCKER_HOST vers l'API de votre moteur Docker, puis exécutez snitch avec les flags requis.
$ cnitch --hostname=myhost --statsd-server=127.0.0.1:8125 --check=10s
cnitch s'exécute dans un conteneur non privilégié et si vous souhaitez utiliser le socket Docker pour accéder à l'API, vous devez ajouter l'utilisateur cnitch au groupe docker. Cela peut être réalisé via le flag --group-add, en définissant l'identifiant de groupe pour le groupe d'utilisateurs Docker.
Par exemple :
--group-add=$(stat -f "%g" /var/run/docker.sock
Exemple d'utilisation du fichier socket Docker pour l'accès à l'API
$ docker run -i -t --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
--group-add=$(stat -f "%g" /var/run/docker.sock) \
-e "DOCKER_HOST:unix:///var/run/docker.sock" \
quay.io/nicholasjackson/cnitch [options]
Si vous êtes sur un Mac et utilisez Docker Machine, le socket Docker se trouve à l'intérieur de la VM, ce qui signifie que vous ne pouvez pas utiliser la commande stat pour découvrir l'identifiant du groupe.
Un exemple de pile Docker Compose se trouve dans le dossier ./example pour montrer comment cnitch exporte des données vers statsd. Pour exécuter cet exemple :
$ cd ./example
$ docker-compose up
Une fois que tout a démarré, ouvrez http://[adresse IP de l'hôte Docker]:3000 dans votre navigateur web et vous devriez voir l'écran de connexion Grafana.

Connectez-vous à Grafana avec les identifiants suivants :
Sélectionnez ensuite le tableau de bord cnitch. Ce tableau de bord montre les processus root en cours d'exécution.

Si vous n'utilisez pas /var/run/docker.sock pour communiquer avec votre hôte Docker, vous devrez modifier certains paramètres dans le fichier ./example/docker-compose.yml pour les adapter à votre configuration.
Implémenter les fonctionnalités du script Docker Bench Security https://github.com/docker/docker-bench-security
[ ] 1.1 S'assurer qu'une partition séparée pour les conteneurs a été créée
[ ] 1.2 S'assurer que l'hôte du conteneur a été durci
[ ] 1.3 S'assurer que Docker est à jour
[ ] 1.4 S'assurer que seuls les utilisateurs de confiance sont autorisés à contrôler le démon Docker
[ ] 1.5 S'assurer que l'audit est configuré pour le démon Docker
[ ] 1.6 S'assurer que l'audit est configuré pour les fichiers et répertoires Docker - /var/lib/docker
[ ] 1.7 S'assurer que l'audit est configuré pour les fichiers et répertoires Docker - /etc/docker
[ ] 1.8 S'assurer que l'audit est configuré pour les fichiers et répertoires Docker - docker.service
[ ] 1.9 S'assurer que l'audit est configuré pour les fichiers et répertoires Docker - docker.socket
[ ] 1.10 S'assurer que l'audit est configuré pour les fichiers et répertoires Docker - /etc/default/docker
[ ] 1.11 S'assurer que l'audit est configuré pour les fichiers et répertoires Docker - /etc/docker/daemon.json
[ ] 1.12 S'assurer que l'audit est configuré pour les fichiers et répertoires Docker - /usr/bin/docker-containerd
[ ] 1.13 S'assurer que l'audit est configuré pour les fichiers et répertoires Docker - /usr/bin/docker-runc
[ ] 2.1 S'assurer que le trafic réseau est restreint entre les conteneurs sur le pont par défaut
[ ] 2.2 S'assurer que le niveau de journalisation est défini sur 'info'
[ ] 2.3 S'assurer que Docker est autorisé à modifier iptables
[ ] 2.4 S'assurer que les registres non sécurisés ne sont pas utilisés
[ ] 2.5 S'assurer que le pilote de stockage aufs n'est pas utilisé
[ ] 2.6 S'assurer que l'authentification TLS pour le démon Docker est configurée
[ ] 2.7 S'assurer que la limite ulimit par défaut est configurée de manière appropriée
[ ] 2.8 Activer le support des espaces de noms utilisateur
[ ] 2.9 S'assurer que l'utilisation du cgroup par défaut a été confirmée
[ ] 2.10 S'assurer que la taille du périphérique de base n'est pas modifiée jusqu'à ce que nécessaire
[ ] 2.11 S'assurer que l'autorisation pour les commandes du client Docker est activée
[ ] 2.12 S'assurer que la journalisation centralisée et à distance est configurée
[ ] 2.13 S'assurer que les opérations sur le registre hérité (v1) sont désactivées
[ ] 2.14 S'assurer que la restauration en direct est activée
[ ] 2.15 S'assurer que le proxy de l'espace utilisateur est désactivé
[ ] 2.16 S'assurer qu'un profil seccomp personnalisé à l'échelle du démon est appliqué, si nécessaire
[ ] 2.17 S'assurer que les fonctionnalités expérimentales sont évitées en production
[ ] 2.18 S'assurer que les conteneurs sont limités dans l'acquisition de nouveaux privilèges
[ ] 3.x ...
[x] 4.1 S'assurer qu'un utilisateur pour le conteneur a été créé
[ ] 4.2 S'assurer que les conteneurs utilisent des images de base de confiance
[ ] 4.3 S'assurer que les paquets inutiles ne sont pas installés dans le conteneur
[ ] 4.4 S'assurer que les images sont scannées et reconstruites pour inclure les correctifs de sécurité
[ ] 4.5 S'assurer que la confiance de contenu pour Docker est activée
[ ] 4.6 S'assurer que les instructions HEALTHCHECK ont été ajoutées à l'image du conteneur
[ ] 4.7 S'assurer que les instructions de mise à jour ne sont pas utilisées seules dans le Dockerfile
[ ] 4.8 S'assurer que les permissions setuid et setgid sont supprimées dans les images
[ ] 4.9 S'assurer que COPY est utilisé à la place de ADD dans le Dockerfile
[ ] 4.10 S'assurer que les secrets ne sont pas stockés dans les Dockerfiles
[ ] 4.11 S'assurer que seuls les paquets vérifiés sont installés
[ ] 5.x ...
[ ] 6.x ...
[ ] 7.x ...