La saisie d'un espace de noms de montage avant de configurer un chroot
permet d'éviter d'encombrer l'espace de noms de l'hôte avec des montages supplémentaires, par exemple pour /proc
. Vous pouvez utiliser à l' chroot
intérieur d'un espace de noms de montage comme un hack agréable et simple.
Je pense qu'il y a des avantages à comprendre pivot_root
, mais cela a un peu de courbe d'apprentissage. La documentation n'explique pas tout ... bien qu'il y ait un exemple d'utilisation dans man 8 pivot_root
(pour la commande shell). man 2 pivot_root
(pour l'appel système) pourrait être plus clair s'il faisait de même, et incluait un exemple de programme C.
Comment utiliser pivot_root
Immédiatement après l'entrée dans l'espace de noms de montage, vous avez également besoin d' mount --make-rslave /
un équivalent. Sinon, toutes vos modifications de montage se propagent aux montures de l'espace de noms d'origine, y compris le pivot_root
. Vous ne voulez pas ça :).
Si vous avez utilisé la unshare --mount
commande, notez qu'elle est documentée pour s'appliquer mount --make-rprivate
par défaut. AFAICS c'est un mauvais défaut et vous ne voulez pas cela dans le code de production. Par exemple, à ce stade, il ne eject
fonctionnerait plus sur un DVD ou USB monté dans l'espace de noms de l'hôte. Le DVD ou l'USB resterait monté dans l'arborescence de montage privée et le noyau ne vous laisserait pas éjecter le DVD.
Une fois que vous avez fait cela, vous pouvez monter par exemple le /proc
répertoire que vous utiliserez. De la même manière que vous le feriez chroot
.
Contrairement à ce que vous utilisez chroot
, pivot_root
nécessite que votre nouveau système de fichiers racine soit un point de montage. S'il est pas déjà, vous pouvez satisfaire en appliquant simplement une monture bind: mount --rbind new_root new_root
.
Utilisez pivot_root
- puis umount
l'ancien système de fichiers racine, avec l' option -l
/ MNT_DETACH
. ( Vous n'avez pas besoin umount -R
, ce qui peut prendre plus de temps. ).
Techniquement, l'utilisation pivot_root
doit généralement impliquer l'utilisation chroot
également; ce n'est pas "l'un ou l'autre".
Selon man 2 pivot_root
, il est uniquement défini comme l'échange de la racine de l'espace de noms de montage. Il n'est pas défini pour changer le répertoire physique vers lequel pointe la racine du processus. Ou le répertoire de travail actuel ( /proc/self/cwd
). Il arrive que ce ne le font, mais cela est un hack pour les threads du noyau de poignée. La page de manuel indique que cela pourrait changer à l'avenir.
Habituellement, vous voulez cette séquence:
chdir(new_root); // cd new_root
pivot_root(".", put_old); // pivot_root . put_old
chroot("."); // chroot .
La position de la chroot
dans cette séquence est encore un autre détail subtil . Bien que l'objectif pivot_root
soit de réorganiser l'espace de noms de montage, le code du noyau semble trouver le système de fichiers racine à déplacer en regardant la racine par processus, ce qui chroot
définit.
Pourquoi utiliser pivot_root
En principe, il est logique d'utiliser pivot_root
pour la sécurité et l'isolement. J'aime penser à la théorie de la sécurité basée sur les capacités . Vous passez une liste des ressources spécifiques nécessaires et le processus ne peut accéder à aucune autre ressource. Dans ce cas, nous parlons des systèmes de fichiers transmis à un espace de noms de montage. Cette idée s'applique généralement à la fonction "namespaces" de Linux, bien que je ne l'exprime probablement pas très bien.
chroot
définit uniquement la racine du processus, mais le processus fait toujours référence à l'espace de noms de montage complet. Si un processus conserve le privilège d'effectuer chroot
, il peut parcourir en arrière l'espace de noms du système de fichiers. Comme détaillé dans man 2 chroot
, "le superutilisateur peut s'échapper d'une" prison chroot "en ...".
Une autre façon de faire réfléchir chroot
est de défaire nsenter --mount=/proc/self/ns/mnt
. C'est peut-être un argument plus fort pour le principe. nsenter
/ setns()
recharge nécessairement la racine du processus, à partir de la racine de l'espace de noms de montage ... bien que le fait que cela fonctionne lorsque les deux font référence à des répertoires physiques différents, peut être considéré comme un bogue du noyau. (Note technique: il peut y avoir plusieurs systèmes de fichiers montés les uns sur les autres à la racine; setns()
utilise le dernier, le plus récemment monté).
Cela illustre un avantage de combiner un espace de noms de montage avec un "espace de noms PID". Être à l'intérieur d'un espace de noms PID vous empêcherait d'entrer dans l'espace de noms de montage d'un processus non confiné. Cela vous empêche également d'entrer à la racine d'un processus non confiné ( /proc/$PID/root
). Et bien sûr, un espace de noms PID vous empêche également de tuer tout processus en dehors de celui-ci :-).
pivot_root
etchroot
: j'ai jeté un coup d'œil aux sources Docker et j'ai constaté que s'il échoue à l'exécutionpivot_root
, il revient àchroot
, c'est- à -dire que ces mécanismes sont considérés comme au moins similaires en termes de fonctionnalités à des fins de conteneurisation.