Niezawodny sposób na więzienie procesów potomnych za pomocą `nsenter:`

15

Wiem, że przestrzeń nazw Linuksa, między innymi, może być wykorzystana do bezpiecznego ograniczania i osadzania procesów potomnych w bezpieczny sposób, bez żadnej szansy na zombie i zrzut init. Ale jestem rozmyślny na temat szczegółów implementacji. W jaki sposób mogę korzystać z narzędzi util-linuxtakich jak mounti, nsenteraby oglądać, monitorować i upewnić się, że wszystkie uruchomione procesy są bezpośrednimi potomkami przestrzeni nazw innego procesu?

mikeserv
źródło

Odpowiedzi:

19

Utwórz przestrzeń nazw PID

Prawidłowe polecenie do użycia tutaj to unshare. Pamiętaj, że niezbędne opcje, aby to zrobić, są dostępne tylko w util-linux 2.23. Chodzi o to, aby utworzyć nowy obszar nazw PID dla uruchomionego programu, tak aby wszystkie jego elementy potomne również zostały utworzone w tym obszarze nazw. Możesz uruchomić polecenie w nowej przestrzeni nazw PID, po prostu wykonując:

sudo unshare -fp some_command

Aby uruchomić powłokę, po prostu pomiń polecenie. Spowoduje to utworzenie procesu, który wraz z dowolnym z jego elementów podrzędnych będzie miał PID jak zwykle w nadrzędnej (systemowej) przestrzeni nazw. Jednak w nowej przestrzeni nazw będzie miał PID 1wraz z niektórymi szczególnymi cechami tego initprocesu. Być może najbardziej istotną cechą z punktu widzenia monitorowania jest to, że jeśli którykolwiek z jego potomków zostanie osierocony, zostanie ponownie wychowany w tym procesie, a nie w rzeczywistym initprocesie.

Takie postępowanie może wystarczyć w większości przypadków monitorowania. Jak wcześniej wspomniano, wszystkie procesy w przestrzeni nazw mają PID w nadrzędnej przestrzeni nazw, więc do monitorowania ich aktywności można używać zwykłych poleceń. Jesteśmy również pewni, że jeśli jakikolwiek proces w przestrzeni nazw zostanie osierocony, nie wypadnie on z gałęzi drzew procesu poniżej PID programu najwyższego poziomu, co oznacza, że ​​nadal można go łatwo śledzić.

Połącz z przestrzenią nazw montowania

Jednak, czego nie możemy zrobić, to monitorowanie procesu w odniesieniu do PID, że myśli, że ma. Aby to zrobić, a zwłaszcza aby móc korzystać z pspolecenia w nowej przestrzeni nazw, musisz zamontować osobny procfssystem plików dla przestrzeni nazw. To z kolei prowadzi do kolejnego problemu, ponieważ jedyną psakceptowaną lokalizacją procfsjest /proc. Jednym z rozwiązań byłoby utworzenie chrootwięzienia i zamontowanie procfstam nowego . Jest to jednak uciążliwe podejście, ponieważ musielibyśmy co najmniej skopiować (lub przynajmniej twarde łącze) dowolne pliki binarne, które zamierzamy używać wraz z bibliotekami, od których zależą od nowego katalogu głównego.

Rozwiązaniem jest również użycie nowej przestrzeni nazw montowania . W ramach tego możemy zamontować nowy procfsw sposób, który wykorzystuje prawdziwy /prockatalog główny , może być użyteczny w przestrzeni nazw PID i nie koliduje z niczym innym. Aby ten proces był bardzo prosty, unsharepolecenie daje --mount-procopcję:

sudo unshare -fp --mount-proc some_command

Teraz uruchomione psw połączonych przestrzeniach nazw pokażą tylko procesy z przestrzenią nazw PID i pokażą proces najwyższego poziomu jako mający PID o wartości 1.

Co nsenter?

Jak sama nazwa wskazuje, nsentermożna go użyć do wprowadzenia przestrzeni nazw, która została już utworzona unshare. Jest to przydatne, jeśli chcemy, aby informacje były dostępne tylko z przestrzeni nazw z niepowiązanego skryptu. Najprościej jest uzyskać dostęp, podając PID dowolnego programu działającego w przestrzeni nazw. Aby to wyjaśnić, musi to być PID programu docelowego w obszarze nazw, z którego nsenterjest uruchamiany (ponieważ obszary nazw można zagnieżdżać, jeden proces może mieć wiele PID). Aby uruchomić powłokę w docelowej przestrzeni nazw PID / mount, po prostu wykonaj:

sudo nsenter -t $PID -m -p

Jeśli ta przestrzeń nazw jest skonfigurowana jak powyżej, psbędzie teraz wyświetlać listę tylko procesów w tej przestrzeni nazw.

Graeme
źródło
Dzięki, Graeme. To już odpowiedziało na pytanie i wiele więcej. To, co tak naprawdę sprawiło, że zapytałem, to przeczytanie notatek ze strony podręcznika procfs w różnych plikach w / proc / pid / ns / *, która mówi: „Powiązanie montażu tego pliku (patrz mount (2)) z innym miejscem w systemie plików ... przestrzeń nazw procesu określonego przez pid żywa, nawet jeśli wszystkie procesy aktualnie znajdujące się w przestrzeni nazw zakończą się. " Wiem, że to nie jest to samo pytanie, ale jest już tak dobre. Pomyślałem, że jeśli uważasz, że jest to istotne, możesz je dodać. Linux.die.net/man/5/proc
mikeserv
Jest to omówione w ostatniej sekcji artykułu LWN (po prostu wyszukaj bind mount). Nie jestem do końca pewien, o co w tym chodzi, ponieważ utrzymuje przestrzeń nazw PID przy życiu, ale po zakończeniu initprocesu stylu najwyższego poziomu nie możesz już tworzyć.
Graeme
Tak, nie jestem też zbyt pewny co do reszty. Ale z tą odpowiedzią i manweekendem dla siebie zamierzam się trochę z nią zapoznać. Dzięki jeszcze raz. Może ma to większe znaczenie w --user przestrzeni nazw.
mikeserv