Installation et sécurisation de Docker pour un environnement de production (Docker Rootless)
Historiquement, Docker a toujours exigé des privilèges root pour s’exécuter. En effet, certaines fonctionnalités telles que les espaces de noms ou les points de montage qui constituent la base de Docker ont toujours requis des privilèges élevés.
Étant donné que Docker est composé d’une pile entière de processus sous-jacent (runc, containerd, dockerd, etc.). L’exécution de docker mode Rootless signifie donc que l’intégralité de la stack docker sera exécutée en mode Rootless. De plus, étant donné que dockerd lui-même s’exécute en tant qu’utilisateur non root, les conteneurs lancés n’auront également aucun privilège root associé.
Ce mode, qui constitue une bonne pratique recommandé par l’ANSI protège le système hôte contre des attaques qui pourraient exploiter des vulnérabilités potentielles du code de l’application ou d’erreurs de configuration.
Guide https://www.ssi.gouv.fr/uploads/2020/12/docker_fiche_technique.pdf
I. Prérequis et environnement de test
- Ne pas avoir docker « normal » d’installé sur la machine hôte
- Dans mon cas, mon hôte docker sera : Ubuntu 20.04.X
II. Choses que vous ne pourrez pas faire avec docker Rootless
Etant donnez que le deamon Docker ne fonctionnera pas avec root
, vous ferez face à quelques restrictions comme :
- L’impossibilité d’exposer un conteneur sur un port privilégié (port < 1024). Exemple de message d’erreur avec un conteneur Nginx « bindé » sur le port 80 (hôte).
docker run -p 80:80 -d nginx
...
cannot expose privileged port 80, you can add 'net.ipv4.ip_unprivileged_port_start=80' to /etc/sysctl.conf (currently 1024), or set CAP_NET_BIND_SERVICE on rootlesskit binary, or choose a larger port number (>= 1024): listen tcp4 0.0.0.0:80: bind: permission denied.
- L’utilisateur du conteneur docker sera toujours root, mais se sera un compte que je vais appeler « root light« , car il n’aura pas accès à certain fichiers comme :
/mnt/etc/shadow
(dans le cas où vous montez tout ou partie du système hôte en tant que volume dans le conteneur. Cela ne vous arrivera jamais, ou alors si vous essayez de faire une escalade privilège). ^^ - Toutes autres manœuvres nécessitant un accès super utilisateur seront aussi prohibées. Par exemple :
- le lancement de processus nécessitant un accès privilégié
- L’allocation de ressources physiques customisé pour un conteneur : CPU,RAM)
III. Installation de Docker Rootless
A. Commandes à exécuter en tant que root (ou sudoer)
apt update
Docker en mode rootless a besoin du packet uidmap, pour fonctionner. Installez le par le biais de la commande ci-dessous :
apt install uidmap
Puis, créez l’utilisateur suivant :
adduser docker-for-prod
Ouvrez un autre terminal et connectez vous avec l’utilisateur docker-for-prod
su docker-for-prod
B. Commandes à exécuter par le biais de l’utilisateur non privilégié docker-for-prod
Vérifiez si votre utilisateur docker-for-prod a été automatiquement ajouté au contrôleur du gestionnaire de connexion systemd (loginctl) :
ls /var/lib/systemd/linger
Si celui-ci n’est pas présent, ajoutez votre utilisateur manuellement au contrôleur à l’aide de la commande suivante :
loginctl enable-linger docker-for-prod
Note : Pour plus d’informations concernant loginctl
, libre à vous d’utiliser vos doigts et votre cerveau pour taper votre meilleure requête sur votre moteur de recherche favoris.^^
Vérifiez que la commande a bien été prise en compte en saisissant de nouveau la commande suivante :
ls /var/lib/systemd/linger
Si tout est ok, de votre côté, connectez vous en SSH à votre machine hôte, afin :
- D’installer docker en mode rootless
- D’interagir avec la commande systemctl, et d’autres composants sous-jacent nécessitant d’être connectés en SSH. (Je ne m’en rappel plus ^^)
Ouvrez donc un autre terminal, et connectez vous en ssh à cette même machine. (Même si ça peut paraître bizarre, vous avez besoin de faire ça pour actualiser le processus loginctl):
ssh [email protected]
Lancez l’installation de docker Rootless, par l’intermédiaire de la commande curl
suivante :
curl -fsSl https://get.docker.com/rootless | sh
Maintenant que docker Rootless est installé, nous devons encore passer par quelques étapes de configuration.
Insérez les deux variables globales (telles quelles) ci-dessous dans votre fichier .bashrc (ou .zshrc etc., si-vous avez un autre shell que bash)
nano ~/.bashrc
# Dans le cas ou votre shell est zsh
nano ~/.zshrc
export PATH=/home/docker-for-prod/bin:$PATH
export DOCKER_HOST=unix:///run/user/1001/docker.sock
Enregistrez les modifications, puis « sourcer » (comprendre : recharger, regénérer) votre shell courant.
source .bashrc
# OU
source .zshrc
Démarrez ensuite docker et par la même occasion activez le démarrage du service au lancement de l’OS :
systemctl --user start docker
systemctl --user enable docker
IV. Test
Afin de tester si docker Rootless est bel et bien installé, instanciez un conteneur :
docker run -d alpine
Comme vous pouvez le constatez, docker-for-prod (qui est un user non privilégié) peut maintenant exécuter des conteneurs en mode Rootless.
Comme on est jamais assez prudent, redémarrez votre machine hôte, et vérifiez que vous pouvez utiliser de nouveau docker avec l’utilisateur prévu à cet effet :
docker-for-prod
Voilà, c’est tout pour cette fois-ci. Je vous laisse avec cette phrase (à méditer ^^)
A. L’article résumé en une phrase :
In rootless mode, root inside the container is not the same root as the host.
++
Geoffrey
En savoir plus sur Le Guide Du SecOps • LGDS
Subscribe to get the latest posts sent to your email.