После прочтения пространств имен Linux у меня сложилось впечатление, что среди множества других функций они являются альтернативой chroot. Например, в этой статье :
Другие применения [пространств имен] включают [...] chroot () - изоляцию стиля процесса от части единой иерархии каталогов.
Однако, когда я клонирую пространство имен монтирования, например, с помощью следующей команды, я все равно вижу все исходное корневое дерево.
unshare --mount -- /bin/bash
Я понимаю, что теперь я могу выполнять дополнительные монтирования в новом пространстве имен, которые не используются совместно с исходным пространством имен, и, таким образом, это обеспечивает изоляцию, но он все еще остается одним и тем же корнем, например /etc
, остается одинаковым для обоих пространств имен. Нужно ли еще chroot
менять рут или есть альтернатива?
Я ожидал, что этот вопрос даст ответ, но ответ только использует chroot
, опять же.
РЕДАКТИРОВАТЬ # 1
Был удаленный комментарий, в котором упоминалось pivot_root
. Так как это на самом деле является частью linux/fs/namespace.c
, это на самом деле является частью реализации пространств имен. Это говорит о том, что изменение корневого каталога только с помощью unshare
и mount
невозможно, но пространства имен предоставляют собственную - более умную - версию chroot
. Тем не менее, я не понимаю основную идею этого подхода, который делает его принципиально отличным chroot
даже после чтения исходного кода (в смысле, например, безопасности или лучшей изоляции).
РЕДАКТИРОВАТЬ № 2
Это не дубликат этого вопроса . После выполнения всех команд из ответа у меня есть отдельный /tmp/tmp.vyM9IwnKuY (или аналогичный), но корневой каталог все тот же!
pivot_root
иchroot
: я взглянул на исходные коды Docker и обнаружил, что если он не выполняетсяpivot_root
, он отступаетchroot
, т. Е. Эти механизмы считаются, по крайней мере, схожими по функциональности для целей контейнеризации.Ответы:
Ввод пространства имен монтирования перед настройкой a
chroot
позволяет избежать загромождения пространства имен хоста дополнительными монтированиями, например, для/proc
. Вы можете использоватьchroot
внутри пространства имен монтирования как приятный и простой взлом.Я думаю, что у понимания есть свои преимущества
pivot_root
, но у него есть некоторая кривая обучения. Документация не совсем объясняет все ... хотя есть пример использованияman 8 pivot_root
(для команды оболочки).man 2 pivot_root
(для системного вызова) может быть более понятным, если бы он делал то же самое и включал пример программы на Си.Как использовать pivot_root
Сразу после входа в пространство имен монтирования вам также потребуется
mount --make-rslave /
или эквивалентный. В противном случае все ваши изменения монтирования распространяются на монтирования в исходном пространстве имен, включаяpivot_root
. Вы не хотите этого :).Если вы использовали
unshare --mount
команду, обратите внимание, что она задокументирована для примененияmount --make-rprivate
по умолчанию. AFAICS, это плохое значение по умолчанию, и вы не хотите этого в производственном коде. Например, на этом этапе он не сможетeject
работать на подключенном DVD или USB в пространстве имен хоста. DVD или USB останутся подключенными внутри частного дерева монтирования, и ядро не позволит вам извлечь DVD.После этого вы можете смонтировать, например,
/proc
каталог, который вы будете использовать. Так же, как и выchroot
.В отличие от того, когда вы используете
chroot
,pivot_root
требует, чтобы ваша новая корневая файловая система была точкой монтирования. Если это не один уже, вы можете удовлетворить это, просто применяя привязка установки:mount --rbind new_root new_root
.Используйте
pivot_root
- и затемumount
старую корневую файловую систему, с-l
/MNT_DETACH
. ( Вам не нужноumount -R
, что может занять больше времени. )Технически, использование,
pivot_root
как правило, должно включать использованиеchroot
; это не «или-или».Согласно
man 2 pivot_root
, он определяется только как замена корня пространства имен монтирования. Не определено, на какую физическую директорию указывает корень процесса. Или текущий рабочий каталог (/proc/self/cwd
). Бывает, что так и есть, но это хак для обработки потоков ядра. На странице написано, что это может измениться в будущем.Обычно вы хотите эту последовательность:
Пост
chroot
в этой последовательности является еще одной тонкой деталью . Хотя смыслpivot_root
состоит в том, чтобы переставить пространство имен монтирования, кажется, что код ядра находит корневую файловую систему для перемещения, просматривая корень для каждого процесса, который иchroot
устанавливает.Зачем использовать pivot_root
В принципе, имеет смысл использовать
pivot_root
для безопасности и изоляции. Мне нравится думать о теории безопасности на основе возможностей . Вы передаете список необходимых ресурсов, и процесс не может получить доступ к другим ресурсам. В данном случае речь идет о файловых системах, передаваемых в пространство имен монтирования. Эта идея в целом применима к функции Linux "пространств имен", хотя я, вероятно, не очень хорошо ее выражаю.chroot
только устанавливает корень процесса, но процесс все еще ссылается на полное пространство имен монтирования. Если процесс сохраняет привилегию для выполненияchroot
, он может выполнить обратное копирование пространства имен файловой системы. Как подробно описано вman 2 chroot
статье, «суперпользователь может сбежать из« тюрьмы chroot »с помощью ...».Еще один заставляющий задуматься способ отменить
chroot
этоnsenter --mount=/proc/self/ns/mnt
. Возможно, это более сильный аргумент в пользу принципа.nsenter
/setns()
обязательно перезагружает корень процесса из корня пространства имен монтирования ... хотя тот факт, что это работает, когда оба ссылаются на разные физические каталоги, может рассматриваться как ошибка ядра. (Техническое примечание: может быть несколько файловых систем, смонтированных поверх друг друга в корне;setns()
используется верхняя, самая последняя из которых смонтирована).Это иллюстрирует одно преимущество объединения пространства имен монтирования с «пространством имен PID». Находясь внутри пространства имен PID, вы не сможете войти в пространство имен монтирования неограниченного процесса. Это также не позволяет вам войти в корень неограниченного процесса (
/proc/$PID/root
). И, конечно же, пространство имен PID также не позволяет вам убивать любой процесс, находящийся вне его :-).источник
mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL)
umount -l ./oldroot
pivot_root(".", ".")
трюк, который на самом деле самый простой способ использоватьpivot_root
в большинстве случаев (неchroot
обязательно).