Docker Bench for Security
Docker Bench for Security est un script qui vérifie des douzaines de bonnes pratiques courantes concernant le déploiement des conteneurs Docker en production. Les tests sont tous automatisés et s'inspirent du CIS Docker Benchmark.
Celui-ci est à disposition en open-source afin que la communauté Docker puisse avoir un moyen facile d'auto-évaluer ses hôtes et ses conteneurs Docker par rapport à ce benchmark.
Lancement de DSB
Une fois le scan de sécuritée lancé, nous allons maintenant analyser la liste des erreurs que nous retourne le script et essayer de les corriger afin d’améliorer la sécurité de notre infrastructure.
Il faut donc commencer par repérer les messages en rouge puis lire la signification de cette potentielle faille.
# docker run --rm --net host --pid host --userns host --cap-add audit_control \ > -e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \ > -v /etc:/etc:ro \ > -v /usr/bin/containerd:/usr/bin/containerd:ro \ > -v /usr/bin/runc:/usr/bin/runc:ro \ > -v /usr/lib/systemd:/usr/lib/systemd:ro \ > -v /var/lib:/var/lib:ro \ > -v /var/run/docker.sock:/var/run/docker.sock:ro \ > --label docker_bench_security \ > docker/docker-bench-security
Le lancement de la commande va télécharger le conteuneur si celui-ci n'est pas disponible sur l'hôte et opérer les scans de sécurités.
# docker run --rm --net host --pid host --userns host --cap-add audit_control \ > -e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \ > -v /etc:/etc:ro \ > -v /usr/bin/containerd:/usr/bin/containerd:ro \ > -v /usr/bin/runc:/usr/bin/runc:ro \ > -v /usr/lib/systemd:/usr/lib/systemd:ro \ > -v /var/lib:/var/lib:ro \ > -v /var/run/docker.sock:/var/run/docker.sock:ro \ > --label docker_bench_security \ > docker/docker-bench-security Unable to find image 'docker/docker-bench-security:latest' locally latest: Pulling from docker/docker-bench-security cd784148e348: Pull complete 48fe0d48816d: Pull complete 164e5e0f48c5: Pull complete 378ed37ea5ff: Pull complete Digest: sha256:ddbdf4f86af4405da4a8a7b7cc62bb63bfeb75e85bf22d2ece70c204d7cfabb8 Status: Downloaded newer image for docker/docker-bench-security:latest # ------------------------------------------------------------------------------ # Docker Bench for Security v1.3.4 # # Docker, Inc. (c) 2015- # # Checks for dozens of common best-practices around deploying Docker containers in production. # Inspired by the CIS Docker Community Edition Benchmark v1.1.0. # ------------------------------------------------------------------------------ Initializing Sat Jan 16 18:16:21 UTC 2021 [INFO] 1 - Host Configuration [WARN] 1.1 - Ensure a separate partition for containers has been created [NOTE] 1.2 - Ensure the container host has been Hardened [INFO] 1.3 - Ensure Docker is up to date [INFO] * Using 20.10.2, verify is it up to date as deemed necessary [INFO] * Your operating system vendor may provide support and security maintenance for Docker [INFO] 1.4 - Ensure only trusted users are allowed to control Docker daemon [INFO] * docker:x:985:gitlab-runner [WARN] 1.5 - Ensure auditing is configured for the Docker daemon [WARN] 1.6 - Ensure auditing is configured for Docker files and directories - /var/lib/docker [WARN] 1.7 - Ensure auditing is configured for Docker files and directories - /etc/docker [WARN] 1.8 - Ensure auditing is configured for Docker files and directories - docker.service [WARN] 1.9 - Ensure auditing is configured for Docker files and directories - docker.socket [INFO] 1.10 - Ensure auditing is configured for Docker files and directories - /etc/default/docker [INFO] * File not found [INFO] 1.11 - Ensure auditing is configured for Docker files and directories - /etc/docker/daemon.json [INFO] * File not found [INFO] 1.12 - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-containerd [INFO] * File not found [INFO] 1.13 - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-runc [INFO] * File not found [INFO] 2 - Docker daemon configuration [WARN] 2.1 - Ensure network traffic is restricted between containers on the default bridge [PASS] 2.2 - Ensure the logging level is set to 'info' [PASS] 2.3 - Ensure Docker is allowed to make changes to iptables [PASS] 2.4 - Ensure insecure registries are not used [PASS] 2.5 - Ensure aufs storage driver is not used [INFO] 2.6 - Ensure TLS authentication for Docker daemon is configured [INFO] * Docker daemon not listening on TCP [INFO] 2.7 - Ensure the default ulimit is configured appropriately [INFO] * Default ulimit doesn't appear to be set [WARN] 2.8 - Enable user namespace support [PASS] 2.9 - Ensure the default cgroup usage has been confirmed [PASS] 2.10 - Ensure base device size is not changed until needed [WARN] 2.11 - Ensure that authorization for Docker client commands is enabled [WARN] 2.12 - Ensure centralized and remote logging is configured [INFO] 2.13 - Ensure operations on legacy registry (v1) are Disabled (Deprecated) [WARN] 2.14 - Ensure live restore is Enabled [WARN] 2.15 - Ensure Userland Proxy is Disabled [PASS] 2.16 - Ensure daemon-wide custom seccomp profile is applied, if needed [PASS] 2.17 - Ensure experimental features are avoided in production [WARN] 2.18 - Ensure containers are restricted from acquiring new privileges [INFO] 3 - Docker daemon configuration files [PASS] 3.1 - Ensure that docker.service file ownership is set to root:root [PASS] 3.2 - Ensure that docker.service file permissions are set to 644 or more restrictive [PASS] 3.3 - Ensure that docker.socket file ownership is set to root:root [PASS] 3.4 - Ensure that docker.socket file permissions are set to 644 or more restrictive [PASS] 3.5 - Ensure that /etc/docker directory ownership is set to root:root [PASS] 3.6 - Ensure that /etc/docker directory permissions are set to 755 or more restrictive [INFO] 3.7 - Ensure that registry certificate file ownership is set to root:root [INFO] * Directory not found [INFO] 3.8 - Ensure that registry certificate file permissions are set to 444 or more restrictive [INFO] * Directory not found [INFO] 3.9 - Ensure that TLS CA certificate file ownership is set to root:root [INFO] * No TLS CA certificate found [INFO] 3.10 - Ensure that TLS CA certificate file permissions are set to 444 or more restrictive [INFO] * No TLS CA certificate found [INFO] 3.11 - Ensure that Docker server certificate file ownership is set to root:root [INFO] * No TLS Server certificate found [INFO] 3.12 - Ensure that Docker server certificate file permissions are set to 444 or more restrictive [INFO] * No TLS Server certificate found [INFO] 3.13 - Ensure that Docker server certificate key file ownership is set to root:root [INFO] * No TLS Key found [INFO] 3.14 - Ensure that Docker server certificate key file permissions are set to 400 [INFO] * No TLS Key found [PASS] 3.15 - Ensure that Docker socket file ownership is set to root:docker [PASS] 3.16 - Ensure that Docker socket file permissions are set to 660 or more restrictive [INFO] 3.17 - Ensure that daemon.json file ownership is set to root:root [INFO] * File not found [INFO] 3.18 - Ensure that daemon.json file permissions are set to 644 or more restrictive [INFO] * File not found [INFO] 3.19 - Ensure that /etc/default/docker file ownership is set to root:root [INFO] * File not found [INFO] 3.20 - Ensure that /etc/default/docker file permissions are set to 644 or more restrictive [INFO] * File not found [INFO] 4 - Container Images and Build File [INFO] 4.1 - Ensure a user for the container has been created [INFO] * No containers running [NOTE] 4.2 - Ensure that containers use trusted base images [NOTE] 4.3 - Ensure unnecessary packages are not installed in the container [NOTE] 4.4 - Ensure images are scanned and rebuilt to include security patches [WARN] 4.5 - Ensure Content trust for Docker is Enabled [PASS] 4.6 - Ensure HEALTHCHECK instructions have been added to the container image [PASS] 4.7 - Ensure update instructions are not use alone in the Dockerfile [NOTE] 4.8 - Ensure setuid and setgid permissions are removed in the images [INFO] 4.9 - Ensure COPY is used instead of ADD in Dockerfile [INFO] * ADD in image history: [docker/docker-bench-security:latest] [NOTE] 4.10 - Ensure secrets are not stored in Dockerfiles [NOTE] 4.11 - Ensure verified packages are only Installed [INFO] 5 - Container Runtime [INFO] * No containers running, skipping Section 5 [INFO] 6 - Docker Security Operations [INFO] 6.1 - Avoid image sprawl [INFO] * There are currently: 1 images [INFO] 6.2 - Avoid container sprawl [INFO] * There are currently a total of 1 containers, with 1 of them currently running [INFO] 7 - Docker Swarm Configuration [PASS] 7.1 - Ensure swarm mode is not Enabled, if not needed [PASS] 7.2 - Ensure the minimum number of manager nodes have been created in a swarm (Swarm mode not enabled) [PASS] 7.3 - Ensure swarm services are binded to a specific host interface (Swarm mode not enabled) [PASS] 7.4 - Ensure data exchanged between containers are encrypted on different nodes on the overlay network [PASS] 7.5 - Ensure Docker's secret management commands are used for managing secrets in a Swarm cluster (Swarm mode not enabled) [PASS] 7.6 - Ensure swarm manager is run in auto-lock mode (Swarm mode not enabled) [PASS] 7.7 - Ensure swarm manager auto-lock key is rotated periodically (Swarm mode not enabled) [PASS] 7.8 - Ensure node certificates are rotated as appropriate (Swarm mode not enabled) [PASS] 7.9 - Ensure CA certificates are rotated as appropriate (Swarm mode not enabled) [PASS] 7.10 - Ensure management plane traffic has been separated from data plane traffic (Swarm mode not enabled) [INFO] Checks: 74 [INFO] Score: 13
Renforcer la sécurité
Auditd
Nous allons mettre en place les règles auditd concernant notre hôte docker.
#!/bin/bash sudo apt update sudo apt-get install -y auditd # 1.5 - Ensure auditing is configured for the Docker daemon echo "-w /usr/bin/docker -p wa" | sudo tee -a /etc/audit/rules.d/audit.rules # 1.6 - Ensure auditing is configured for Docker files and directories - /var/lib/docker echo "-w /var/lib/docker -p wa" | sudo tee -a /etc/audit/rules.d/audit.rules # 1.7 - Ensure auditing is configured for Docker files and directories - /etc/docker" echo "-w /etc/docker -p wa" | sudo tee -a /etc/audit/rules.d/audit.rules # 1.8 - Ensure auditing is configured for Docker files and directories - docker.service echo "-w /usr/lib/systemd/system/docker.service -p wa" | sudo tee -a /etc/audit/rules.d/audit.rules # 1.9 - Ensure auditing is configured for Docker files and directories - docker.socket echo "-w /usr/lib/systemd/system/docker.socket -p wa" | sudo tee -a /etc/audit/rules.d/audit.rules # 1.10 - Ensure auditing is configured for Docker files and directories - /etc/default/docker echo "-w /etc/default/docker -p wa" | sudo tee -a /etc/audit/rules.d/audit.rules # 1.11 - Ensure auditing is configured for Docker files and directories - /etc/docker/daemon.json echo "-w /etc/docker/daemon.json -p wa" | sudo tee -a /etc/audit/rules.d/audit.rules # 1.12 - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-containerd echo "-w /usr/bin/docker-containerd -p wa" | sudo tee -a /etc/audit/rules.d/audit.rules # 1.13 - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-runc echo "-w /usr/bin/docker-runc -p wa" | sudo tee -a /etc/audit/rules.d/audit.rules
On redémarre le service
# sudo service auditd restart
Ensure network traffic is restricted between containers on the default bridge
Il est possible de restreindre les communications entre les containers sur l'interface bridge par défaut créé par Docker. Cela permet d'isoler nativement les containers au niveau réseau. Il sera alors nécessaire de rendre l'échange entre container explicite avec l'utilisation de l'option **--link** pour la commande Docker, ou avec le paramètre links dans un fichier de configuration Docker Compose.
L' avantage de cette option est que si un attaquant compromet un conteneur, il aura plus de mal à trouver et à attaquer d'autres conteneurs sur le même hôte.
Note:
Nous recommandons fortement l'utilisation de cette option. Il est vraiment important d'isoler le réseau de vos containers.
{ "icc": false }
Enable user namespace support
Les namespaces offrent une isolation supplémentaire pour les processus s'exécutant dans vos conteneurs. Le remappage de l'espace de noms des utilisateurs, permet aux processus de s'exécuter en tant que root dans un conteneur, tout en étant remappés vers un utilisateur moins privilégié sur l'hôte.
Vous pouvez activer cette option dans le fichier de configuration avec la ligne suivante : userns-remap“: “default”
En définissant le paramètre par default, Docker va créer un utilisateur dockermap sur lequel les utilisateurs de conteneurs seront remappés. Vous pouvez vérifier que l'utilisateur dockremap a été créé à l'aide de la commande id:
# sudo id dockremap
Vous devriez obtenir un retour similaire :
# id dockremap uid=986(dockremap) gid=981(dockremap) groupes=981(dockremap)
Si vous le souhaitez, vous pouvez changer l'utilisateur utilisé pour le remap. Il vous suffit alors de spécifier l'utilisateur et le groupe en lieu et place de default dans le fichier de configuration :
{ "userns-remap": "user:group" }
Ensure centralized and remote logging is configured
Vous pouvez facilement utiliser un serveur syslog dans la configuration du daemon Docker : “log-driver”
{ "log-driver": "syslog" }
Vous pouvez utiliser un serveur syslog centralisé : “log-opts”:
{ "syslog-address": "udp://198.168.100.100:514" }
Cette sécurité doit vous permettre d'externaliser vos journaux afin d'éviter qu'un attaquant puisse venir les altérer. Et ainsi effacer les traces de son passage ou dissimuler ses actions.
Bien évidemment vous pouvez également utiliser d'autres systèmes de récupération des journaux, splunk , fluentd ou encore gelf peuvent vous permettre d'envoyer les logs à un autre service d’agrégation avant de les stocker dans des bases externes comme elasticsearch par exemple.
Ensure live restore is Enabled
L'option “live-restore”: true permet à vos containers de continuer à fonctionner même lorsque votre daemon Docker est arrêté.
Cela va grandement faciliter vos mises à jour de Docker-CE :
{ "live-restore": true }
De plus en cas de “crash” du daemon Docker, aucune question. Tout fonctionne.
Ensure Userland Proxy is Disabled
Les versions modernes de Docker prennent en charge l'utilisation d'iptables.
L'idée est simple : plutôt qu'une application d'espace utilisateur mandatant les connexions au nom de votre conteneur, en l’occurrence docker-proxy, le noyau est configuré pour les modifier via des règles NAT et les acheminer de manière appropriée directement. Cette fonctionnalité n'est cependant pas activée par défaut.
{ "userland-proxy": false, "iptables": true }
Note:
Si elle n'est pas activée par défaut, ce n'est pas forcément pour rien. Il existe des cas de bug, notamment avec des kernels non à jour. Il est préférable de tester cette option avant de l'utiliser en production.
Ensure containers are restricted from acquiring new privileges
L'escalation de privilèges au sein d'un environnement Docker est possible. Autant donc le prévenir au travers de la configuration : no-new-privileges
{ "no-new-privileges": true }
Note:
Attention cette option garantit que votre container ne pourra pas recupérer de nouveau privilège, mais si vous le lancez déjà avec l'option --privileged ça ne changera rien…
Il est important au delà de cette option de vous assurer que vos containers n'ont pas de droits trop importants.