Введення простору імен для монтування перед налаштуванням a chroot
дозволяє уникнути захаращення простору імен хоста додатковими кріпленнями, наприклад, для /proc
. Ви можете використовувати chroot
всередині простору імен кріплення як гарний і простий хак.
Я думаю, що в розумінні є переваги pivot_root
, але це має трохи криву навчання. Документація не зовсім пояснює все, хоча є приклад використання в man 8 pivot_root
(для команди shell). man 2 pivot_root
(для системного виклику) може бути зрозумілішим, якби це робилося те саме, і включив приклад програми C.
Як користуватися 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
). Буває, що це так і робиться, але це хак для обробки потоків ядра. На сторінці вказано, що це може змінитися в майбутньому.
Зазвичай потрібно цю послідовність:
chdir(new_root); // cd new_root
pivot_root(".", put_old); // pivot_root . put_old
chroot("."); // chroot .
Повідомлення 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 також не дозволяє вбити будь-який процес, що знаходиться поза нею :-).
pivot_root
іchroot
: я переглянув джерела Докера і виявив, що якщо його не виконатиpivot_root
, він повертається назадchroot
, тобто ці механізми вважаються принаймні схожими за функціональністю для цілей контейнерації.