Zuverlässige Methode, um untergeordnete Prozesse mit `nsenter:` in den Knast zu setzen

15

Ich weiß, dass Linux-Namespaces unter anderem genutzt werden können, um untergeordnete Prozesse sicher einzuschränken und einzusperren, ohne dass die Gefahr besteht, dass sie zombiert und ausgelagert werden init. Aber ich weiß nicht genau, wie die Implementierung aussieht. Wie kann ich die von util-linuxz. B. mountund bereitgestellten Tools verwenden nsenter, um zu überwachen und sicherzustellen, dass alle gestarteten Prozesse die direkten Namespace-Nachfahren eines anderen Prozesses sind?

mikeserv
quelle

Antworten:

18

Erstellen Sie einen PID-Namespace

Der richtige Befehl ist hier unshare. Beachten Sie, dass die dazu erforderlichen Optionen nur von verfügbar sind util-linux 2.23. Die Idee ist, einen neuen PID-Namespace für das von Ihnen ausgeführte Programm zu erstellen, sodass auch alle untergeordneten Programme in diesem Namespace erstellt werden. Sie können einen Befehl in einem neuen PID-Namespace ausführen, indem Sie Folgendes ausführen:

sudo unshare -fp some_command

Um eine Shell auszuführen, lassen Sie einfach den Befehl aus. Dadurch wird ein Prozess erstellt, der zusammen mit einem seiner untergeordneten Elemente wie gewohnt eine PID im übergeordneten Namespace (Systemnamespace) hat. Innerhalb des neuen Namespaces hat es jedoch eine PID von 1zusammen mit einigen der besonderen Merkmale des initProzesses. Aus Sicht der Überwachung ist das vielleicht relevanteste Merkmal, dass ein verwaister Nachkomme eines Unternehmens diesem Prozess und nicht dem eigentlichen initProzess zugeordnet wird.

Für die meisten Überwachungsfälle kann es ausreichen, dies einfach zu tun. Wie bereits erwähnt, weisen alle Prozesse im Namespace PIDs im übergeordneten Namespace auf, sodass reguläre Befehle zum Überwachen ihrer Aktivität verwendet werden können. Wir können auch versichern, dass ein verwaister Prozess im Namespace nicht aus den Prozessbaumverzweigungen unter der PID des Programms der obersten Ebene herausfällt, sodass er weiterhin leicht verfolgt werden kann.

Mit einem Mount-Namespace kombinieren

Was wir jedoch nicht tun können, ist, den Prozess in Bezug auf die PID zu überwachen, von der es denkt , dass sie die PID hat. Um dies zu tun und insbesondere den psBefehl im neuen Namespace verwenden zu können, müssen Sie ein separates procfsDateisystem für den Namespace bereitstellen. Dies führt wiederum zu einem anderen Problem, da der einzige Ort, psfür den dies akzeptiert wird, procfsist /proc. Eine Lösung wäre, ein chrootGefängnis zu errichten und das neue procfsdort anzubringen . Dies ist jedoch ein umständlicher Ansatz, da wir mindestens alle Binärdateien, die wir verwenden möchten, zusammen mit den Bibliotheken, von denen sie abhängen, in das neue Stammverzeichnis kopieren (oder fest verknüpfen) müssen.

Die Lösung besteht darin, auch einen neuen Mount-Namespace zu verwenden . Darin können wir das Neue procfsauf eine Weise einbinden, die das wahre Stammverzeichnis /procverwendet, im PID-Namespace verwendbar ist und nichts anderes beeinträchtigt. Um diesen Vorgang sehr einfach zu gestalten, unsharegibt der Befehl die --mount-procOption:

sudo unshare -fp --mount-proc some_command

psWenn Sie jetzt in den kombinierten Namespaces ausgeführt werden, werden nur die Prozesse mit dem PID-Namespace und der Prozess der obersten Ebene mit einer PID von angezeigt 1.

Was ist nsenter?

nsenterKann, wie der Name schon sagt, zur Eingabe eines Namensraums verwendet werden, mit dem bereits ein Namensraum erstellt wurde unshare. Dies ist nützlich, wenn Informationen nur aus dem Namespace eines ansonsten nicht verwandten Skripts abgerufen werden sollen. Am einfachsten ist es, auf die PID eines Programms zuzugreifen, das im Namespace ausgeführt wird. Um klar zu sein, muss dies die PID des Zielprogramms innerhalb des Namespaces sein, von dem aus nsenteres ausgeführt wird (da Namespaces verschachtelt sein können, kann es sein, dass ein einzelner Prozess viele PIDs hat). Gehen Sie wie folgt vor, um eine Shell im Ziel-PID / Mount-Namespace auszuführen:

sudo nsenter -t $PID -m -p

Wenn dieser Namespace wie oben eingerichtet ist, pswerden nur Prozesse in diesem Namespace aufgelistet.

Graeme
quelle
Danke, Graeme. Dies hat die Frage und mehr bereits beantwortet. Was mich eigentlich gefragt hat, war das Lesen der Notizen aus der procfs - Manpage in den verschiedenen Dateien in / proc / pid / ns / *, die besagen: "Binde das Mounten dieser Datei (siehe mount (2)) an eine andere Stelle im Dateisystem ... Namespace des von pid alive angegebenen Prozesses, auch wenn alle aktuell im Namespace befindlichen Prozesse beendet werden. " Kaum die gleiche Frage, ich weiß, aber das ist schon so gut, dass ich dachte, wenn Sie es für relevant hielten, möchten Sie es vielleicht hinzufügen. Linux.die.net/man/5/proc
mikeserv
Dies wird im letzten Abschnitt des LWN-Artikels behandelt (suchen Sie einfach nach bind mount). Ich bin mir nicht wirklich sicher, was das angeht, da es den PID-Namespace am Leben erhält, aber nachdem der Stilprozess auf oberster Ebene beendet initist, können Sie keine weiteren erstellen.
Graeme
Ja, im Übrigen bin ich mir auch nicht sicher. Aber mit dieser Antwort und maneinem Wochenende für mich möchte ich mich ein wenig vertrauter machen. Danke noch einmal. Vielleicht hat es mehr Relevanz im --user Namespace.
mikeserv