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.

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

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

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.

Vous pouvez l'activer dans le fichier /etc/docker/daemon.json avec la ligne suivante :

{
        "icc": false
}

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"
}

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.

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.

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.

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.

Ce site web utilise des cookies. En utilisant le site Web, vous acceptez le stockage de cookies sur votre ordinateur. Vous reconnaissez également que vous avez lu et compris notre politique de confidentialité. Si vous n'êtes pas d'accord, quittez le site.En savoir plus