Введення простору імен для монтування перед налаштуванням 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, тобто ці механізми вважаються принаймні схожими за функціональністю для цілей контейнерації.