Надежный способ заблокировать дочерние процессы, используя `nsenter:`

15

Я знаю, что пространства имен Linux, помимо прочего, могут быть использованы для безопасной обработки ограничивающих и заключающих в тюрьму дочерних процессов без какой-либо возможности их зомбирования и сброса init. Но я не совсем уверен в деталях реализации. Как я могу использовать предоставляемые инструменты, util-linuxтакие как mountи, nsenterчтобы наблюдать, контролировать и гарантировать, что все запущенные процессы являются прямыми потомками пространства имен другого процесса?

mikeserv
источник

Ответы:

19

Создайте пространство имен PID

Правильная команда для использования здесь unshare. Обратите внимание, что необходимые опции для этого доступны только из util-linux 2.23. Идея состоит в том, чтобы создать новое пространство имен PID для программы, которую вы запускаете, так что все ее дочерние элементы также создаются в этом пространстве имен. Вы можете запустить команду в новом пространстве имен PID, просто выполнив:

sudo unshare -fp some_command

Чтобы запустить оболочку, просто пропустите команду. Это создаст процесс, который, как и любой из его дочерних элементов, будет иметь PID, как обычно, в родительском (системном) пространстве имен. Однако в новом пространстве имен он будет иметь PID, 1а также некоторые специальные характеристики initпроцесса. Возможно, наиболее важной характеристикой с точки зрения мониторинга является то, что если какой-либо из его потомков осиротят, они будут заново связаны с этим процессом, а не с реальным initпроцессом.

Простого выполнения этого может быть достаточно для большинства случаев мониторинга. Как упоминалось ранее, все процессы в пространстве имен имеют идентификаторы PID в родительском пространстве имен, поэтому для мониторинга их активности можно использовать обычные команды. Мы также уверены, что если какой-либо процесс в пространстве имен станет осиротевшим, он не выпадет из ветвей дерева процессов под PID программы верхнего уровня, что означает, что его все еще можно легко отслеживать.

Объединить с пространством имен mount

Однако то, что мы не можем сделать, это контролировать процесс в отношении идентификатора PID, который, по его мнению , имеет. Для этого и, в частности, чтобы иметь возможность использовать psкоманду в новом пространстве имен, вам необходимо смонтировать отдельную procfsфайловую систему для пространства имен. Это, в свою очередь, приводит к другой проблеме, поскольку единственное место, которое psпринимает, procfs- это /proc. Одним из решений будет создание chrootтюрьмы и установка там нового procfs. Но это громоздкий подход, поскольку как минимум нам потребуется скопировать (или, по крайней мере, жесткую ссылку) любые двоичные файлы, которые мы намереваемся использовать вместе с любыми библиотеками, от которых они зависят, до нового корня.

Решением является также использование нового пространства имен монтирования . В рамках этого мы можем смонтировать новый procfsспособ, который использует истинный корневой /procкаталог, может быть использован в пространстве имен PID и не мешает ничему другому. Чтобы сделать этот процесс очень простым, unshareкоманда дает --mount-procвозможность:

sudo unshare -fp --mount-proc some_command

Теперь при выполнении psв объединенных пространствах имен будут отображаться только процессы с пространством имен PID и процесс верхнего уровня будет иметь PID, равный 1.

Как насчет nsenter?

Как следует из названия, nsenterможет использоваться для ввода пространства имен, которое уже было создано с помощью unshare. Это полезно, если мы хотим получить информацию, доступную только из пространства имен, из сценария, не связанного с другой. Самый простой способ - это указать PID любой программы, работающей в пространстве имен. Чтобы было ясно, это должен быть PID целевой программы в пространстве имен, из которого nsenterвыполняется (поскольку пространства имен могут быть вложенными, у одного процесса может быть много PID). Чтобы запустить оболочку в целевом пространстве имен PID / mount, просто выполните:

sudo nsenter -t $PID -m -p

Если это пространство имен настроено, как указано выше, psтеперь будут перечислены только процессы в этом пространстве имен.

Graeme
источник
Спасибо, Грэм. Это уже ответил на вопрос и многое другое. То, что на самом деле меня заинтересовало, так это чтение заметок со справочной страницы procfs по различным файлам в / proc / pid / ns / *, где написано: «Привязка при монтировании этого файла (см. Mount (2)) к другому месту в файловой системе сохраняет ... пространство имен процесса, указанного в pid live, даже если все процессы, находящиеся в данный момент в пространстве имен, завершаются. " Вряд ли тот же вопрос, я знаю, но это уже настолько хорошо, что я подумал, что если вы считаете, что это актуально, вы можете добавить его в. Linux.die.net/man/5/proc
mikeserv
Это описано в последнем разделе статьи LWN (просто найдите bind mount). Я не совсем уверен в этом, хотя, поскольку он поддерживает пространство имен PID, но после того, как initпроцесс стиля верхнего уровня умирает, вы больше не можете создавать.
Грэм
Да, я не слишком уверен в остальном. Но с этим ответом и manвыходными для себя я имею в виду немного поближе познакомиться с ним. Еще раз спасибо. Может быть, это имеет большее значение в --user пространстве имен.
mikeserv