Parfois, les utilisateurs s'interrogent sur les contraintes du mode sans racine pour les moteurs de conteneurs Buildah et Podman. Avec le mode sans racine, nous repoussons les limites de ce qu'un utilisateur non privilégié peut faire. L'un de mes travaux consiste à travailler avec les équipes du noyau et les équipes du système de fichiers pour améliorer le rootless. Dans cet article, j'explique pourquoi le montage d'images est plus difficile en mode rootless.
[ Vous pourriez également aimer : Équilibrer la sécurité Linux avec la convivialité ]
Montage sans racine
Un utilisateur normal ne peut pas monter un système de fichiers à moins qu'il ne se trouve dans un espace de noms d'utilisateur avec son propre espace de noms de montage . Un espace de noms de montage permet aux processus qu'il contient de monter des systèmes de fichiers qui ne sont pas vus par l'espace de noms de montage hôte. Cette contrainte de noyau protège le système d'exploitation hôte des attaques potentielles où un utilisateur pourrait monter du contenu sur /tmp
ou même dans leur répertoire personnel, puis inciter d'autres processus du système ou des administrateurs à utiliser les points de montage.
Une fois que le processus de l'utilisateur rejoint l'espace de noms de l'utilisateur et le nouvel espace de noms de montage, le noyau n'autorise le montage que de certains systèmes de fichiers. Au moment d'écrire ces lignes, le noyau autorise les systèmes de fichiers sysfs, procfs, tmpfs, bind mount et fuse. Nous avons récemment obtenu un correctif dans le noyau en amont pour prendre en charge les systèmes de fichiers superposés, ce qui constituera une grande amélioration, mais actuellement, la plupart des distributions n'ont pas cette prise en charge. J'aimerais obtenir le support NFS, mais il y a des risques de sécurité avec cela. Espérons que le noyau résoudra ces problèmes et qu'il sera éventuellement pris en charge.
Les moteurs de conteneurs sans racine comme Podman et Buildah créent automatiquement leur propre espace de noms d'utilisateur et montent un espace de noms lorsqu'ils s'exécutent. Lorsque le processus du moteur de conteneur se termine, les espaces de noms utilisateur et de montage disparaissent et le processus utilisateur revient à l'espace de noms de montage hôte. À ce stade, les montages créés lors de l'exécution des outils ne sont plus visibles ni utilisables par d'autres processus sur l'hôte.
Pourquoi est-ce important ?
L'une des fonctionnalités intéressantes de Buildah est de permettre aux utilisateurs d'accéder à la sémantique de bas niveau de la construction de conteneurs. La plupart des constructeurs d'images de conteneurs n'ont qu'une seule façon de créer des conteneurs, essentiellement en utilisant Containerfiles ou Dockerfiles. Buildah bud
prend en charge la construction avec ces fichiers. Buildah permet également aux utilisateurs de créer des conteneurs à l'aide de primitives de bas niveau. Les utilisateurs peuvent l'utiliser pour créer un répertoire, remplir le répertoire avec du contenu, créer une image et la transférer vers un registre.
# ctr=$(buildah from scratch)
# mnt=$buildah mount $ctr)
# dnf -y --install-root $mnt httpd
# buildah config --entrypoint .... $ctr
# buildah commit $ctr IMAGE
# buildah push IMAGE REGISTRY
Tout cela fonctionne très bien lorsqu'il est exécuté en tant que root, mais lorsque les utilisateurs tentent de l'exécuter en mode sans racine, leurs scripts explosent.
$ mnt=$(buildah mount $ctr)
cannot mount using driver overlay in rootless mode. You need to run it in a `buildah unshare` session
Le problème est mnt=$(buildah mount $ctr)
refuse de monter l'image avec le pilote de superposition si vous n'avez pas exécuté buildah unshare
.
Regarder de plus près
Lorsque vous exécutez buildah
commandes, comme bud
et run
, en mode rootless, le buildah
La commande entre l'utilisateur et les espaces de noms de montage. Il monte correctement le système de fichiers du conteneur et exécute les commandes. Lorsque la commande se termine, buildah
se termine, provoquant la destruction des espaces de noms. Lorsque vous faites cela avec le mount
commande, le système de fichiers monté n'a jamais été vu dans l'espace de noms de montage hôte. Buildah vérifie maintenant cette situation et signale à l'utilisateur qu'il doit émettre un buildah unshare
d'abord.
construire non partagé
Buildah et Podman ont une commande spéciale, unshare
. Cette commande crée et entre dans l'espace de noms d'utilisateur sans créer ni interagir avec un conteneur. Il est en fait assez intéressant d'explorer ce mode pour bien comprendre ce que fait l'espace de noms de l'utilisateur. Exécuter le buildah unshare
La commande exécutera une commande shell dans les espaces de noms exécutés en tant que root dans l'espace de noms d'utilisateur. Vous pouvez maintenant exécuter n'importe quelle commande, y compris buildah
commandes décrites ci-dessus. Comme ces commandes sont déjà dans les espaces de noms, le buildah mount
La commande fonctionnera de la même manière qu'en mode root. Tout se passe à l'intérieur des espaces de noms et l'utilisateur obtient ce qu'il attend.
L'utilisateur peut maintenant prendre les commandes répertoriées ci-dessus et créer un script shell. Ce script shell est ensuite exécuté directement avec le buildah unshare
commande.
$ cat > buildahimage.sh < _EOF
ctr=$(buildah from scratch)
mnt=$buildah mount $ctr)
dnf -y --install-root $mnt httpd
buildah config --entrypoint .... $ctr
buildah commit $ctr IMAGE
buildah push IMAGE REGISTRY
< _EOF
chmod +x /buildahimage.sh
buildah unshare ./buildimage.sh
[ Vous débutez avec les conteneurs ? Découvrez ce cours gratuit. Déploiement d'applications conteneurisées :présentation technique. ]
Récapitulez
Malheureusement, nous ne pouvons pas tout réparer dans le noyau pour offrir aux utilisateurs l'expérience sans racine qu'ils attendent, principalement en raison de problèmes de sécurité. Mais on peut s'en approcher assez. Et bien sûr, vous pouvez toujours travailler en mode root si vous avez besoin de fonctionnalités supplémentaires.