Le noyau Linux est capable de décomposer les privilèges de l’utilisateur root en unités distinctes appelées capabilities. Par exemple, la capabilities CAP_CHOWN
est ce qui permet à l’utilisateur root d’apporter des modifications arbitraires aux UID et aux GID de fichier. La fonctionnalité CAP_DAC_OVERRIDE
permet à l’utilisateur root de contourner les vérifications des autorisations du noyau pour les opérations de lecture, d’écriture et d’exécution de fichier. Presque tous les pouvoirs spéciaux associés à l’utilisateur root Linux sont décomposés en capacités individuelles.
Introduction aux capabilities
Le noyau Linux est capable de décomposer les privilèges de l’utilisateur root en unités distinctes appelées capacités. Par exemple, la capacité CAP_CHOWN
est ce qui permet à l’utilisateur root d’apporter des modifications arbitraires aux UID et aux GID de fichier. La fonctionnalité CAP_DAC_OVERRIDE
permet à l’utilisateur root de contourner les vérifications des autorisations du noyau pour les opérations de lecture, d’écriture et d’exécution de fichier. Presque tous les pouvoirs spéciaux associés à l’utilisateur root Linux sont décomposés en capacités individuelles.
Cette décomposition des privilèges root en capacités granulaires vous permet de :
- Supprimez les fonctionnalités individuelles du compte utilisateur root, le rendant moins puissant/dangereux.
- Ajoutez des privilèges aux utilisateurs non root à un niveau très granulaire.
Les capacités s’appliquent aux fichiers et aux threads. Les fonctionnalités de fichier permettent aux utilisateurs d’exécuter des programmes avec des privilèges plus élevés. Ceci est similaire au fonctionnement du bit setuid. Les capacités de threads gardent une trace de l’état actuel des capacités dans les programmes en cours d’exécution.
Le noyau Linux vous permet de définir des ensembles de limites de capacité qui imposent des limites aux capacités qu’un fichier/thread peut obtenir.
Docker impose certaines limitations qui rendent le travail avec des fonctionnalités beaucoup plus simple. Par exemple, les fonctionnalités de fichier sont stockées dans les attributs étendus d’un fichier, lesquels sont supprimés lors de la création des images Docker. Cela signifie que vous ne devrez normalement pas trop vous préoccuper des capacités de fichier dans les conteneurs.
Il est bien sûr possible d’obtenir des capacités de fichiers dans les conteneurs au moment de l’exécution, mais cela n’est pas recommandé.
Dans un environnement dépourvu de fonctionnalités basées sur des fichiers, il est impossible pour les applications d’élever leurs privilèges au-delà du jeu de limites (jeu au-delà duquel les capacités ne peuvent pas croître). Docker définit le groupe de reliure avant de démarrer un conteneur. Vous pouvez utiliser les commandes Docker pour ajouter ou supprimer des fonctionnalités au jeu de limites.
Par défaut, Docker supprime toutes les fonctionnalités, à l’exception de celles qui sont nécessaires en utilisant une approche de liste blanche :
// DefaultCapabilities returns a Linux kernel default capabilities |
Un des principaux risques liés à l’exécution de conteneurs Docker est que l’ensemble par défaut de fonctionnalités et de montages donnés à un conteneur peut fournir une isolation incomplète, soit indépendamment, soit en combinaison avec des vulnérabilités du noyau.
Docker prend en charge l’ajout et la suppression de fonctionnalités, ce qui permet d’utiliser un profil autre que celui par défaut. Cela peut rendre Docker plus sûr grâce à la suppression de fonctionnalités ou moins sécurisé grâce à l’ajout de fonctionnalités.
Les conteneurs Docker sont, par défaut, assez sécurisés, surtout si vous vous occupez d’exécuter vos processus à l’intérieur des conteneurs en tant qu’utilisateurs non privilégiés (c’est-à-dire non root).
Utiliser les capabilities
Il existe 3 options pour utiliser les capabilities :
- Exécutez les conteneurs :
- en root avec des capabilities et gérer manuellement les capabilities du conteneur (à éviter).
- en root avec des capabilities limitées et ne pas les modifier dans un conteneur (la plus réaliste).
- en tant qu’utilisateur sans privilèges et sans capabilities (idéale mais pas réaliste).
Pour supprimer des capabilities du compte root d’un conteneur.
# docker run --rm -it --cap-drop $CAP alpine sh |
Pour ajouter des capabilities du compte root d’un conteneur.
# docker run --rm -it --cap-add $CAP alpine sh |
Supprimer toutes les capabilities, puis ajouter explicitement des capabilities individuelles au compte root d’un conteneur.
# docker run --rm -it --cap-drop ALL --cap-add $CAP alpine sh |
Le noyau Linux préfixe toutes les constantes de capabilities avec CAP_
. Par exemple, CAP_CHOWN
, CAP_NET_ADMIN
, CAP_SETUID
, CAP_SYSADMIN
, etc. Les constantes de fonctionnalité Docker ne portent pas le préfixe CAP_
mais correspondent aux constantes du noyau.
Liste des capabilities
Pour plus d’informations sur les capabilities, y compris une liste complète, voir la page de manuel relative aux capabilities : http://man7.org/linux/man-pages/man7/capabilities.7.html.
La liste suivante montre les capabilities implémentées sous Linux et
les opérations ou comportements qu’elles permettent :
CAP_AUDIT_CONTROL (since Linux 2.6.11) |
Documentation
http://man7.org/linux/man-pages/man7/capabilities.7.html
https://training.play-with-docker.com/security-capabilities/
https://github.com/docker/labs/tree/master/security/capabilities#docker_cap
https://docs.docker.com/v17.09/engine/security/security/#linux-kernel-capabilities
https://github.com/moby/moby/blob/master/oci/defaults.go#L14-L30
Plus sur les capabilities :
https://training.play-with-docker.com/security-capabilities
https://github.com/docker/labs/tree/master/security/capabilities#step-3-testing-docker-capabilities
https://github.com/docker/labs/tree/master/security/capabilities#step-4-extra-for-experts