Un moyen fiable pour emprisonner les processus enfants en utilisant `nsenter:`

15

Je sais que les espaces de noms Linux, entre autres choses, peuvent être exploités pour gérer les processus enfants restrictifs et emprisonnés en toute sécurité sans aucune chance d'être zombiés et vidés init. Mais je suis flou sur les détails d'implémentation. Comment puis-je utiliser les outils fournis par util-linuxtels que mountet nsenterpour surveiller, surveiller et garantir que tous les processus lancés sont les descendants directs de l'espace de noms d'un autre processus?

mikeserv
la source

Réponses:

19

Créer un espace de noms PID

La commande correcte à utiliser ici est unshare. Notez que les options nécessaires pour ce faire ne sont disponibles qu'à partir de util-linux 2.23. L'idée est de créer un nouvel espace de noms PID pour le programme que vous exécutez de telle sorte que tous ses enfants soient également créés dans cet espace de noms. Vous pouvez exécuter une commande dans un nouvel espace de noms PID simplement en faisant:

sudo unshare -fp some_command

Pour exécuter un shell, omettez simplement la commande. Cela créera un processus qui, avec n'importe lequel de ses enfants, aura un PID comme d'habitude dans l'espace de noms parent (système). Cependant, dans le nouvel espace de noms, il aura un PID 1ainsi que certaines des caractéristiques spéciales du initprocessus. La caractéristique la plus pertinente du point de vue de la surveillance est peut-être que si l'un de ses descendants est orphelin, il sera re-parenté à ce processus plutôt qu'au initprocessus réel .

Faire cela peut être suffisant pour la plupart des cas de surveillance. Comme mentionné précédemment, les processus dans l'espace de noms ont tous des PID dans l'espace de noms parent, de sorte que des commandes régulières peuvent être utilisées pour surveiller leur activité. Nous sommes également assurés que si un processus de l'espace de noms devient orphelin, il ne tombera pas des branches de l'arbre de processus sous le PID du programme de niveau supérieur, ce qui signifie qu'il peut toujours être facilement suivi.

Combiner avec un espace de noms de montage

Cependant, ce que nous ne pouvons pas faire, c'est surveiller le processus en ce qui concerne le PID qu'il pense avoir. Pour ce faire, et en particulier pour pouvoir utiliser la pscommande dans le nouvel espace de noms, vous devez monter un procfssystème de fichiers distinct pour l'espace de noms. Cela entraîne à son tour un autre problème car le seul emplacement qui psaccepte procfsest /proc. Une solution serait de créer une chrootprison et d'y monter la nouvelle procfs. Mais c'est une approche lourde car au minimum nous aurions besoin de copier (ou du moins de lier dur) tous les binaires que nous avons l'intention d'utiliser avec toutes les bibliothèques dont ils dépendent vers la nouvelle racine.

La solution consiste à utiliser également un nouvel espace de noms de montage . Dans ce cadre, nous pouvons monter le nouveau procfsd'une manière qui utilise le vrai /procrépertoire racine , peut être utilisable dans l'espace de noms PID et n'interfère avec rien d'autre. Pour rendre ce processus très simple, la unsharecommande donne l' --mount-procoption:

sudo unshare -fp --mount-proc some_command

Désormais, l'exécution psdans les espaces de noms combinés n'affichera que les processus avec l'espace de noms PID et le processus de niveau supérieur aura un PID de 1.

Et alors nsenter?

Comme son nom l'indique, nsenterpeut être utilisé pour entrer un espace de noms qui a déjà été créé avec unshare. Ceci est utile si nous voulons obtenir des informations uniquement disponibles à l'intérieur de l'espace de noms à partir d'un script autrement indépendant. Le moyen le plus simple est d'accéder au PID de tout programme exécuté dans l'espace de noms. Pour être clair, il doit s'agir du PID du programme cible dans l'espace de noms à partir duquel il nsenterest exécuté (étant donné que les espaces de noms peuvent être imbriqués, il est possible qu'un seul processus ait plusieurs PID). Pour exécuter un shell dans l'espace de noms PID / mount cible, faites simplement:

sudo nsenter -t $PID -m -p

Si cet espace de noms est configuré comme ci-dessus, psrépertorie désormais uniquement les processus au sein de cet espace de noms.

Graeme
la source
Merci, Graeme. Cela a déjà répondu à la question et plus encore. Ce qui m'a vraiment demandé, c'est de lire les notes de la page de manuel procfs sur les différents fichiers dans / proc / pid / ns / * qui dit: "Lier le montage de ce fichier (voir mount (2)) à un autre endroit du système de fichiers ... l'espace de noms du processus spécifié par pid alive même si tous les processus actuellement dans l'espace de noms se terminent. " À peu près la même question, je sais, mais c'est déjà si bon que je pensais que si vous pensiez que c'était pertinent, vous pourriez l'ajouter. Linux.die.net/man/5/proc
mikeserv
Ceci est couvert dans la dernière section de l' article LWN (il suffit de rechercher le montage de liaison). Je ne suis pas vraiment sûr de l'intérêt, car il maintient l'espace de noms PID en vie, mais après la fin du initprocessus de style de niveau supérieur , vous ne pouvez plus créer.
Graeme
Ouais, je ne suis pas trop sûr du reste non plus. Mais avec cette réponse et manet un week-end pour moi, je veux me familiariser un peu avec. Merci encore. Peut-être qu'il a plus de pertinence dans l' --user espace de noms.
mikeserv