Poursuivant avec la série des espaces de noms, cet article couvre le PID espace de noms. Si vous voulez un aperçu général de tous les espaces de noms, consultez le premier article. Auparavant, vous avez créé un nouveau mnt espace de noms. Fait intéressant, comme vous l'avez découvert, même après avoir créé un nouveau mnt l'espace de noms, vous avez toujours accès aux ID de processus (PID) de l'hôte d'origine. Lorsque vous avez essayé de monter le fichier /proc espace de noms, vous avez reçu la plutôt déroutante autorisation refusée erreur, comme indiqué ci-dessous :
root@new-mnt$ mount -t proc proc /proc
mount: permission denied (are you root?)
root@new-mnt$ whoami
root
Bien que vous puissiez créer toutes sortes de montages dans le nouvel espace de noms de montage, vous ne pouviez pas interagir ou modifier /proc . Dans cet article, je passe en revue le PID l'espace de noms et montrez comment vous pouvez l'utiliser, ainsi que le mnt espace de noms, pour sécuriser davantage votre conteneur naissant.
[ Les lecteurs ont également aimé : Comment les espaces de noms Linux PID fonctionnent avec les conteneurs ]
Que sont les ID de processus ?
Avant de sauter directement dans le PID espace de noms, je pense que c'est une bonne idée de fournir un peu de contexte pour expliquer pourquoi cet espace de noms est important.
Lorsqu'un processus est créé sur la plupart des systèmes d'exploitation de type Unix, il reçoit un identifiant numérique spécifique appelé ID de processus (PID). Ce PID permet d'identifier un processus de manière unique même s'il existe deux processus qui partagent le même nom lisible par l'homme. Par exemple, si plusieurs sessions ssh sont actives sur un système et que vous devez fermer une connexion spécifique, le PID permet à l'administrateur de s'assurer que la bonne session est fermée.
Tous ces processus sont suivis dans un système de fichiers spécial appelé procfs
. Bien que ce système de fichiers puisse techniquement être monté n'importe où, la plupart des outils (et conventions) attendent le procfs
à monter sous /proc
. Si vous faites une liste de /proc
, vous verrez un dossier pour chaque processus en cours d'exécution sur votre système. À l'intérieur de ce dossier se trouvent toutes sortes de fichiers spéciaux utilisés pour suivre divers aspects du processus. Pour les besoins de cet article, ces fichiers ne sont pas importants. Il suffit de savoir que /proc
est l'endroit où la plupart des systèmes de type Unix stockent des informations concernant les processus sur un système en cours d'exécution.
L'espace de noms PID
L'une des principales raisons du PID namespace est de permettre l'isolation des processus. Plus précisément, comme le dit la page de manuel :
Les espaces de noms PID isolent l'espace des numéros d'ID de processus, ce qui signifie que les processus dans différents espaces de noms PID peuvent avoir le même PID.
Ceci est important car cela signifie que les processus peuvent être assurés de ne pas avoir de PID en conflit avec un autre processus. Lorsque l'on considère un seul système, bien sûr, il n'y a aucune chance que les PID soient en conflit car le système incrémente continuellement le numéro d'identification du processus et n'attribue jamais le même numéro deux fois. Lorsqu'il s'agit de conteneurs sur plusieurs machines, ce problème devient plus important. Comme décrit dans la page de manuel :
Les espaces de noms PID permettent aux conteneurs de fournir des fonctionnalités telles que la suspension/reprise de l'ensemble des processus dans le conteneur et la migration du conteneur vers un nouvel hôte tandis que les processus à l'intérieur du conteneur conservent les mêmes PID.
Mis à part l'isolement, le système PID fonctionne presque identique à celui en dehors de l'espace de noms. Les ID de processus à l'intérieur du nouvel espace de noms commencent à 1 , avec le premier processus considéré comme init processus. L'initialisation processus est géré très différemment de tous les autres PID sur un hôte. Cela a des implications particulières pour le système en cours d'exécution qui sortent du cadre de cette série. Si vous souhaitez plus d'informations, consultez la section "Les signaux et le processus d'initialisation" de l'article Espaces de noms LWN.
Ce qui est à noter, cependant, c'est que quel que soit le processus qui a le PID 1 est vital pour la longévité des espaces de noms. Si PID 1 est terminé pour une raison quelconque, le noyau enverra un SIGKILL
à tous les processus restants dans l'espace de noms, fermant efficacement cet espace de noms.
Explorer les espaces de noms PID
Si vous vous demandez, comme moi, si vous pouvez imbriquer PID espaces de noms, la réponse est oui. En fait, le noyau fait de la place pour jusqu'à 32 PID imbriqués espaces de noms. Ceci est considéré comme une relation à sens unique. Cela signifie que le parent peut voir les PID des enfants, petits-enfants, etc. Cependant, il ne peut voir aucun des PID de ses ancêtres. Considérez ce qui suit :
[user@localhost ~] sudo unshare -fp /bin/bash
[root@localhost ~] sleep 90000 &
[root@localhost ~] ps -ef
UID PID PPID C STIME TTY TIME CMD
[truncated ]
.....
root 11627 11620 0 09:16 pts/0 00:00:00 sudo unshare -fp /bin/bash
root 11633 11627 0 09:17 pts/0 00:00:00 unshare -fp /bin/bash
root 11634 11633 0 09:17 pts/0 00:00:00 /bin/bash
root 11639 11634 0 09:17 pts/0 00:00:00 sleep 90000
root 11641 11634 0 09:17 pts/0 00:00:00 ps -ef
[root@localhost ~] sudo unshare -fp /bin/bash
[root@localhost ~] sleep 8000 &
[root@localhost ~] ps -ef
[truncated ]
.....
UID PID PPID C STIME TTY TIME CMD
root 11650 11634 0 09:17 pts/0 00:00:00 sudo unshare -fp /bin/bash
root 11654 11650 0 09:17 pts/0 00:00:00 unshare -fp /bin/bash
root 11655 11654 0 09:17 pts/0 00:00:00 /bin/bash
root 11661 11655 0 09:17 pts/0 00:00:00 sleep 8000
root 11671 11655 0 09:17 pts/0 00:00:00 ps -ef
Vous remarquerez que j'ai tronqué la sortie car le PID l'espace de noms apparaît pour avoir un accès complet à tous les PID dans /proc
. Observez ce qui se passe si vous essayez d'arrêter un processus qui se trouve dans un ancêtre :
[root@localhost ~] kill -9 11361
bash: kill: (11361) - No such process
Pourquoi est-ce? En termes simples, des outils traditionnels comme ps
ne sont pas conscients de l'espace de noms et lisent réellement à partir de /proc
annuaire. Si vous avez fait un ls /proc
, vous verrez toujours tous les dossiers et fichiers d'avant car, comme indiqué dans le dernier article, le PID l'espace de noms hérite tous les mnt montages d'espace de noms. J'aborde cette situation plus tard. Pour l'instant, revenez à l'exemple actuel.
Dans un autre shell, identifiez les processus en veille :
[user@localhost ~] ps -ef |grep sleep
root 11639 11634 0 09:17 pts/0 00:00:00 sleep 90000
root 11661 11655 0 09:17 pts/0 00:00:00 sleep 8000
Si vous voulez vérifier que ces processus sont dans des espaces de noms différents, vous devrez trouver le bash
processus PID. N'oubliez pas que depuis que vous avez exécuté sudo unshare -fp /bin/bash
, le bash
le processus est init processus dans le nouvel espace de noms. C'est donc le PID qui sera lié à l'ID de l'espace de noms. Prenons les PID :
[root@localhost ~] ps -ef |grep bash
root 11627 11620 0 09:16 pts/0 00:00:00 sudo unshare -fp /bin/bash
root 11633 11627 0 09:17 pts/0 00:00:00 unshare -fp /bin/bash
root 11634 11633 0 09:17 pts/0 00:00:00 /bin/bash
root 11650 11634 0 09:17 pts/0 00:00:00 sudo unshare -fp /bin/bash
root 11654 11650 0 09:17 pts/0 00:00:00 unshare -fp /bin/bash
root 11655 11654 0 09:17 pts/0 00:00:00 /bin/bash
Vous pouvez voir les PID 11634 et 11655 dans la sortie. Si vous comparez cela à la sortie de lsns
(répertorier les espaces de noms), vous verrez ce qui suit :
[root@localhost ~] lsns |grep bash
NS TYPE NPROCS PID USER COMMAND
4026532952 pid 4 11634 root /bin/bash
4026532954 pid 4 11655 root /bin/bash
Comme vous pouvez le voir, les ID d'espace de noms sont différents, et donc les processus sont dans des espaces de noms différents.
Maintenant que vous avez établi que les espaces de noms sont effectivement différents, regardons l'ascendance PID mentionnée précédemment. Vous pouvez le faire en identifiant le NSpid attribut d'un PID donné dans le /proc
répertoire, comme indiqué ci-dessous :
sudo cat /proc/11655/status |grep NSpid
NSpid: 11655 6 1
Les colonnes se lisent de gauche à droite et indiquent le PID dans leurs espaces de noms respectifs. Le PID le plus à gauche est l'espace de noms principal ou racine. Dans ce cas, il a un PID de 11655 , un PID secondaire de 6 , et un PID tertiaire de 1 . Étant donné que les espaces de noms possèdent chaque PID descendant espace de noms, vous pouvez le penser comme ceci :
- Sur l'hôte, le
bash
processus exécutant lesleep 8000
la commande a un PID de 11655 . - À l'intérieur du premier "conteneur", le
bash
processus exécutant lesleep 8000
la commande a un PID de 6 . - À l'intérieur du deuxième "conteneur" imbriqué, le PID est 1 . Il s'agit du conteneur qui a réellement lancé le processus.
Chacun de ces bash
commandes a été créée dans son propre espace de noms mais est visible par le parent (dans ce cas, la racine espace de noms).
/proc, PID et utilisateurs non privilégiés
Le lecteur avisé aurait remarqué que, dans les deux derniers articles, un utilisateur régulier pouvait créer à la fois utilisateur et mnt espaces de noms. Dans cet article, j'ai utilisé le sudo
commande. C'est parce que vous ne pouvez pas créer un PID espace de noms seul avec un utilisateur non privilégié. La réponse à cela est de combiner plusieurs créations d'espaces de noms en un seul événement. Il existe plusieurs solutions différentes pour monter /proc
en tant qu'utilisateur non privilégié.
Si vous essayez simplement de créer un nouvel utilisateur namespace, vous obtiendrez un résultat étrange :
[ user@localhost ~] unshare -Urp
-bash: fork: Cannot allocate memory
-bash-5.1# ps -ef
-bash: fork: Cannot allocate memory
-bash-5.1# ls
-bash: fork: Cannot allocate memory
Que se passe-t-il ici? Rappelez-vous comment le premier processus à l'intérieur d'un nouveau PID l'espace de noms devient init processus? Dans ce cas, le shell actuel ne peut pas déplacer les espaces de noms. Il existe dans la racine espace de noms et lorsque vous avez créé un nouveau PID espace de noms, le système ne savait pas comment le gérer. La solution à cela est d'avoir le processus lui-même. Cela permet au shell actuel de devenir un processus enfant de unshare
commande. Utiliser le -f
flag entraîne la création de l'espace de noms :
[ user@localhost ~] unshare -Urfp
[ root@localhost ~]
Cependant, vous voyez toujours la contamination du /proc
point de montage. Il existe deux solutions à cela. Tout d'abord, vous pouvez créer un nouveau mnt namespace puis remontez /proc
vous-même :
[ user@localhost ~]$ unshare -Urpmf
[ root@localhost ~]# mount -t proc proc /proc
[ root@localhost ~]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 09:31 pts/0 00:00:00 -bash
root 10 1 0 09:31 pts/0 00:00:00 ps -ef
En effet, pendant de nombreuses années, c'était la seule option mais, un indicateur --mount-proc
a été créé il y a quelque temps pour le faire en une seule étape. La page de manuel indique :
Juste avant d'exécuter le programme, montez le système de fichiers proc au point de montage (la valeur par défaut est /proc). Ceci est utile lors de la création d'un nouvel espace de noms PID. Cela implique également la création d'un nouvel espace de noms de montage car le montage /proc gâcherait autrement les programmes existants sur le système. Le nouveau système de fichiers proc est explicitement monté en tant que privé (avec MS_PRIVATE|MS_REC).
Ainsi, par conséquent, vous pouvez voir des références à la commande suivante :
unshare -Urpf --mount-proc
Cela crée un nouveau mnt espace de noms lors du montage de /proc
pour vous.
Saisie d'un espace de noms
Pour réduire la complexité, j'ai quitté les espaces de noms créés précédemment. J'ai créé un nouvel espace de noms avec la commande suivante :
unshare -Urfp --mount-proc
J'ai également créé un différent sleep
processus juste pour aider à identifier l'espace de noms. Comme je n'ai qu'un seul nouvel espace de noms, je peux utiliser le lsns
commande pour déterminer le bon PID :
[ user@localhost ~]$ lsns |grep bash
4026532965 pid 2 13142 user -bash
Ensuite, exécutez le nsenter
commande :
sudo nsenter -t 13142 -a
Le -a
flag indique au nsenter
pour entrer tous les espaces de noms de ce PID. sudo
est requis avec le -a
flag, sinon vous ne pourrez pas passer à tous les espaces de noms appropriés. Vous devriez maintenant pouvoir lister tous les PIDS de ce NS :
[ root@localhost ~]$ ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 09:54 pts/0 00:00:00 -bash
root 8 1 0 09:54 pts/0 00:00:00 sleep 99999
root 25 0 0 10:15 pts/1 00:00:00 -bash
root 31 25 0 10:15 pts/1 00:00:00 ps -ef
[ Apprenez les bases de l'utilisation de Kubernetes dans cet aide-mémoire gratuit. ]
Conclusion
Le PID L'espace de noms est important lorsqu'il s'agit de créer des environnements isolés. Il permet aux processus d'avoir leurs propres PID quel que soit le système hôte. Dans un monde où plusieurs hôtes peuvent être impliqués dans l'orchestration d'environnements isolés (conteneurs), il devient crucial de disposer d'une installation garantissant des PID uniques lors du gel et de la migration des processus. De plus, pour des raisons de sécurité, si vous exécutez des espaces de noms pour l'isolation des applications, le PID L'espace de noms est essentiel pour empêcher les fuites d'informations par le biais des processus qu'un hôte peut exécuter.
Lorsqu'il est combiné avec l'utilisateur et mnt espaces de noms, le PID L'espace de noms fournit une grande protection sans nécessiter de privilèges root. Les navigateurs modernes tels que Firefox et Vivaldi utilisent des espaces de noms pour fournir un bac à sable du navigateur. Dans le prochain article, je vais vous montrer le net namespace et voyez comment vous pouvez continuer à construire votre conteneur à la main en ajoutant des composants réseau discrets.