Простір монтування — це функція ядра Linux, яка забезпечує ізоляцію точок монтування файлової системи, які бачить група процесів. Кожен простір монтування має свій власний набір точок монтування файлової системи, і зміни в точках монтування в одному просторі не впливають на інші простори. Це означає, що процеси, що виконуються в різних просторах монтування, можуть мати різні уявлення про ієрархію файлової системи.
Простори монтування особливо корисні в контейнеризації, де кожен контейнер повинен мати свою власну файлову систему та конфігурацію, ізольовану від інших контейнерів і хост-системи.
How it works:
Коли створюється новий простір монтування, він ініціалізується з копією точок монтування з його батьківського простору. Це означає, що при створенні новий простір ділить те ж саме уявлення про файлову систему, що й його батько. Однак будь-які подальші зміни в точках монтування в межах простору не вплинуть на батьківський або інші простори.
Коли процес змінює точку монтування в межах свого простору, наприклад, монтує або демонтує файлову систему, зміна є локальною для цього простору і не впливає на інші простори. Це дозволяє кожному простору мати свою власну незалежну ієрархію файлової системи.
Процеси можуть переміщатися між просторами, використовуючи системний виклик setns(), або створювати нові простори, використовуючи системні виклики unshare() або clone() з прапором CLONE_NEWNS. Коли процес переходить до нового простору або створює його, він почне використовувати точки монтування, пов'язані з цим простором.
Файлові дескриптори та іноди спільні між просторами, що означає, що якщо процес в одному просторі має відкритий файловий дескриптор, що вказує на файл, він може передати цей файловий дескриптор процесу в іншому просторі, і обидва процеси отримають доступ до одного й того ж файлу. Однак шлях до файлу може бути не однаковим в обох просторах через різницю в точках монтування.
Lab:
Create different Namespaces
CLI
sudounshare-m [--mount-proc] /bin/bash
При монтуванні нового екземпляра файлової системи /proc, якщо ви використовуєте параметр --mount-proc, ви забезпечуєте, що новий простір монтування має точний та ізольований вигляд інформації про процеси, специфічної для цього простору.
Помилка: bash: fork: Не вдається виділити пам'ять
Коли unshare виконується без параметра -f, виникає помилка через те, як Linux обробляє нові PID (ідентифікатори процесів) простори. Основні деталі та рішення наведені нижче:
Пояснення проблеми:
Ядро Linux дозволяє процесу створювати нові простори за допомогою системного виклику unshare. Однак процес, який ініціює створення нового PID простору (який називається "процесом unshare"), не входить до нового простору; лише його дочірні процеси входять.
Виконання %unshare -p /bin/bash% запускає /bin/bash в тому ж процесі, що й unshare. Відповідно, /bin/bash та його дочірні процеси знаходяться в оригінальному PID просторі.
Перший дочірній процес /bin/bash у новому просторі стає PID 1. Коли цей процес завершується, це викликає очищення простору, якщо немає інших процесів, оскільки PID 1 має особливу роль усиновлення сирітських процесів. Ядро Linux тоді вимкне виділення PID у цьому просторі.
Наслідок:
Завершення PID 1 у новому просторі призводить до очищення прапора PIDNS_HASH_ADDING. Це призводить до того, що функція alloc_pid не може виділити новий PID при створенні нового процесу, що викликає помилку "Не вдається виділити пам'ять".
Рішення:
Проблему можна вирішити, використовуючи параметр -f з unshare. Цей параметр змушує unshare створити новий процес після створення нового PID простору.
Виконання %unshare -fp /bin/bash% забезпечує, що команда unshare сама стає PID 1 у новому просторі. /bin/bash та його дочірні процеси тоді безпечно містяться в цьому новому просторі, запобігаючи передчасному завершенню PID 1 та дозволяючи нормальне виділення PID.
Забезпечивши, що unshare виконується з прапором -f, новий PID простір правильно підтримується, що дозволяє /bin/bash та його підпроцесам працювати без виникнення помилки виділення пам'яті.
sudofind/proc-maxdepth3-typel-namemnt-execreadlink{} \; 2>/dev/null|sort-u# Find the processes with an specific namespacesudofind/proc-maxdepth3-typel-namemnt-execls-l{} \; 2>/dev/null|grep<ns-number>
findmnt
Увійти в простір імен монтування
nsenter-mTARGET_PID--pid/bin/bash
Також ви можете входити в інший просторовий процес тільки якщо ви root. І ви не можетевходити в інший простір без дескриптора, що вказує на нього (наприклад, /proc/self/ns/mnt).
Оскільки нові монтування доступні лише в межах простору, можливо, що простір містить чутливу інформацію, яка може бути доступна лише з нього.
Монтувати щось
# Generate new mount nsunshare-m/bin/bashmkdir/tmp/mount_ns_examplemount-ttmpfstmpfs/tmp/mount_ns_examplemount|greptmpfs# "tmpfs on /tmp/mount_ns_example"echotest>/tmp/mount_ns_example/testls/tmp/mount_ns_example/test# Exists# From the hostmount|greptmpfs# Cannot see "tmpfs on /tmp/mount_ns_example"ls/tmp/mount_ns_example/test# Doesn't exist
# findmnt # List existing mounts
TARGET SOURCE FSTYPE OPTIONS
/ /dev/mapper/web05--vg-root
# unshare --mount # run a shell in a new mount namespace
# mount --bind /usr/bin/ /mnt/
# ls /mnt/cp
/mnt/cp
# exit # exit the shell, and hence the mount namespace
# ls /mnt/cp
ls: cannot access '/mnt/cp': No such file or directory
## Notice there's different files in /tmp
# ls /tmp
revshell.elf
# ls /mnt/tmp
krb5cc_75401103_X5yEyy
systemd-private-3d87c249e8a84451994ad692609cd4b6-apache2.service-77w9dT
systemd-private-3d87c249e8a84451994ad692609cd4b6-systemd-resolved.service-RnMUhT
systemd-private-3d87c249e8a84451994ad692609cd4b6-systemd-timesyncd.service-FAnDql
vmware-root_662-2689143848