IPC (міжпроцесна комунікація) простір імен є функцією ядра Linux, яка забезпечує ізоляцію об'єктів IPC System V, таких як черги повідомлень, сегменти спільної пам'яті та семафори. Ця ізоляція гарантує, що процеси в різних просторах імен IPC не можуть безпосередньо отримувати доступ або змінювати об'єкти IPC один одного, забезпечуючи додатковий рівень безпеки та конфіденційності між групами процесів.
Як це працює:
Коли створюється новий простір імен IPC, він починається з повністю ізольованого набору об'єктів IPC System V. Це означає, що процеси, що виконуються в новому просторі імен IPC, не можуть за замовчуванням отримувати доступ або втручатися в об'єкти IPC в інших просторах імен або в системі хоста.
Об'єкти IPC, створені в межах простору імен, видимі та доступні лише для процесів у цьому просторі імен. Кожен об'єкт IPC ідентифікується унікальним ключем у своєму просторі імен. Хоча ключ може бути ідентичним у різних просторах імен, самі об'єкти ізольовані і не можуть бути доступні між просторами імен.
Процеси можуть переміщатися між просторами імен, використовуючи системний виклик setns(), або створювати нові простори імен, використовуючи системні виклики unshare() або clone() з прапором CLONE_NEWIPC. Коли процес переходить до нового простору імен або створює його, він почне використовувати об'єкти IPC, пов'язані з цим простором імен.
Лабораторія:
Створити різні простори імен
CLI
sudounshare-i [--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-nameipc-execreadlink{} \; 2>/dev/null|sort-u# Find the processes with an specific namespacesudofind/proc-maxdepth3-typel-nameipc-execls-l{} \; 2>/dev/null|grep<ns-number>
Увійти в IPC простір імен
nsenter-iTARGET_PID--pid/bin/bash
Також ви можете входити в інший простір процесів лише якщо ви root. І ви не можетевходити в інший простір без дескриптора, що вказує на нього (наприклад, /proc/self/ns/net).
Створити об'єкт IPC
# Containersudounshare-i/bin/bashipcmk-M100Sharedmemoryid:0ipcs-m------SharedMemorySegments--------keyshmidownerpermsbytesnattchstatus0x2fba90210root6441000# From the hostipcs-m# Nothing is seen