virli/tutorial/4/mountns.md

5.9 KiB

Le namespace mount

L'espace de noms mount permet d'isoler la vision du système de fichiers qu'ont un processus et ses fils.

Peut-être que l'on peut trouver avec ça, un moyen de faire un chroot plus sûr ?

::::: {.warning} Attention il convient de prendre garde aux types de liaison existant entre vos points de montage (voir la partie sur les particularités des points de montage), car les montages et démontages pourraient alors être répercutés dans l'espace de noms parent.\

Une manière rapide pour s'assurer que nos modifications ne sortiront pas de notre namespace est d'appliquer le type esclave à l'ensemble de nos points de montage, récursivement, dès que l'on est entré dans notre nouvel espace de noms.

``` mount --make-rslave / ```
:::::

Préparation du changement de racine

Nous allons essayer de changer la racine de notre système de fichier. À la différence d'un chroot(2), changer de racine est quelque chose d'un peu plus sportif car il s'agit de ne plus avoir aucune trace de l'ancienne racine. Au moins ici, il ne sera certainement pas possible de revenir en arrière dans l'arborescence !

Pour l'instant, votre système utilise sans doute la partition d'un disque physique comme racine de son système de fichier. Le changement de racine, va nous permettre d'utiliser un autre système.

Bien sûr, nous n'allons pas changer la racine de votre système hôte, nous allons faire cela dans un namespace qui nous permet d'avoir des points de montage virtuels. Le changement de racine sera donc effectif uniquement dans cet espace de noms.

L'environnement\

Pour pouvoir changer de racine, il est nécessaire que la nouvelle racine soit la racine d'un point de montage, comme l'explique pivot_root(2). En effet, il serait encore possible hypothétiquement de remonter dans l'arborescence si l'on ne se trouvait pas à la racine d'une partition au moment du basculement.

Si vous n'avez pas de partition à disposition, vous pouvez utiliser un tmpfs :

``` 42sh# mkdir /mnt/newroot 42sh# mount -t tmpfs none /mnt/newroot ```

Placez ensuite dans cette nouvelle racine le système de votre choix.

::::: {.exercice}

Changer de racine -- myswitch_root.sh

Voici les grandes étapes du changement de racine :

  1. S'isoler dans les namespaces adéquats ;
  2. Démonter ou déplacer toutes les partitions de l'ancienne racine vers la nouvelle racine ;
  3. pivot_root !

S'isoler\

Notre but étant de démonter toutes les partitions superflues, nous allons devoir nous isoler sur :

  • les points de montages, ça semble évident ;
  • les PIDs : car on ne pourra pas démonter une partition en cours d'utilisation. S'il n'y a pas de processus, il n'y a personne pour nous empêcher de démonter une partition !
  • les autres namespaces ne sont pas forcément nécessaires.

Isolons-nous :

``` 42sh# unshare -p -m -f --mount-proc ```

::::: {.warning}

Avant de pouvoir commencer à démonter les partitions, il faut s'assurer que les démontages ne se propagent pas via une politique de shared mount.

:::::

Dissocier la propagation des démontages\

Commençons donc par étiqueter tous nos points de montage (de ce namespace), comme esclaves :

``` 42sh# mount --make-rslave / ```

Démonter tout !\

À vous maintenant de démonter vos points d'attache. Il ne devrait vous rester après cette étape que : /, /dev, /sys, /proc, /run et leurs fils.

Switch !\

À ce stade, dans votre console, vous avez plusieurs solutions : utiliser switch_root(8) ou pivot_root(8). La première abstrait plus de choses que la seconde.

switch_root {-}

\

Cette commande s'occupe de déplacer les partitions restantes pour vous, et lance la première commande (init) de votre choix.

pivot_root {-}

\

Cette commande, plus proche du fonctionnement de l'appel système pivot_root(2), requiert de notre part que nous ayons préalablement déplacé les partitions systèmes à leur place dans la nouvelle racine.

L'appel de la commande sert à intervertir les deux racines ; elle prend en argument :

  • le chemin de la nouvelle racine,
  • le chemin dans la nouvelle racine où placer l'ancienne.

Une fois le pivot effectué, on peut démonter l'ancienne racine.

Pour lancer la première commande dans la nouvelle racine, on passe généralement par :

``` 42sh# exec chroot / command ```

Erreurs courantes {-}

\

Voici une liste des erreurs les plus courantes que vous allez sans doute rencontrer :

EINVAL
  • La nouvelle racine n'est pas un point de montage.
  • Le chemin où placer l'ancienne racine n'est pas sur la nouvelle racine.
  • Le point de montage de la nouvelle ou l'ancienne racine utilise le type de propagation shared.
EBUSY
La nouvelle racine ou le chemin où mettre l'ancienne racine se trouve sur la racine actuelle.
ENOTDIR
La nouvelle racine ou le chemin où mettre l'ancienne racine ne sont pas des dossiers.
EPERM
Le processus appelant ne dispose pas de la capability CAP_SYS_ADMIN.

Vous pouvez retrouver toutes les erreurs dans le manuel de pivot_root(2).

Assemblage {-}

\

Vous devriez maintenant pouvoir réaliser un script myswitch_root.sh qui enchaîne toutes les étapes précédentes.

On considère préalablement que l'environnement est propice à la réalisation de ce script :

``` 42sh# mkdir -p /mnt/newroot 42sh# mount -t tmpfs none /mnt/newroot 42sh# wget https://dl-cdn.alpinelinux.org/alpine/v3.14/releases/x86_64/alpine-minirootfs-3.14.8-x86_64.tar.gz 42sh# tar xpf alpine-minirootfs-*.tar.gz -C /mnt/newroot 42sh# cd / ```

Puis on s'attend à le lancer ainsi :

``` 42sh# ~/myswitch_root.sh /mnt/newroot /bin/bash innewns# _ ```

:::::