Обмеження безпеки ядра Linux для Podʼів та контейнерів

Обмеження безпеки ядра Linux для Podʼів та контейнерів

Огляд модулів безпеки ядра Linux та обмежень, які можна використовувати для зміцнення ваших Podʼів і контейнерів.

На цій сторінці описано деякі можливості безпеки, вбудовані в ядро Linux, які ви можете використовувати у своїх робочих навантаженнях Kubernetes. Щоб дізнатися, як застосувати ці можливості до ваших Podʼів і контейнерів, дивіться Налаштування контексту безпеки для Podʼа або контейнера. Ви вже маєте бути знайомі з Linux та основами робочих навантажень Kubernetes.

Запуск робочих навантажень без привілеїв root

Коли ви розгортаєте робоче навантаження в Kubernetes, використовуйте специфікацію Podʼа, щоб заборонити йому працювати від імені користувача root на вузлі. За допомогою securityContext Podʼа можна визначити конкретного користувача та групу Linux для процесів у Podʼі та явно заборонити контейнерам працювати від імені root. Значення, встановлені в маніфесті Podʼа, мають вищий пріоритет за аналогічні значення в образі контейнера, що особливо корисно, якщо ви запускаєте образи, які вам не належать.

Увага:

Переконайтеся, що користувач або група, яку ви призначаєте робочому навантаженню, має дозволи, потрібні для правильної роботи застосунку. Зміна користувача або групи на таких, що не мають потрібних дозволів, може призвести до проблем із доступом до файлів або збоїв операцій.

Налаштування описаних на цій сторінці можливостей безпеки ядра забезпечує детальний контроль над діями процесів у вашому кластері, але керування цими налаштуваннями може бути складним у великому масштабі. Запуск контейнерів не від імені root або в просторах імен користувачів, якщо вам потрібні привілеї root, зменшує ймовірність того, що вам доведеться застосовувати налаштовані можливості безпеки ядра.

Можливості безпеки в ядрі Linux

Kubernetes дозволяє налаштовувати та використовувати можливості ядра Linux для кращої ізоляції та зміцнення ваших контейнеризованих робочих навантажень. Серед поширених можливостей:

  • Режим безпечних обчислень (seccomp): фільтрування системних викликів, які може робити процес
  • AppArmor: обмеження привілеїв доступу окремих програм
  • Security Enhanced Linux (SELinux): призначення міток безпеки обʼєктам для зручнішого застосування політик безпеки

Щоб налаштувати одну з цих можливостей, операційна система ваших вузлів має вмикати її в ядрі. Наприклад, Ubuntu 7.10 і новіші стандартно вмикають AppArmor. Щоб дізнатися, чи ввімкнено певну можливість у вашій ОС, зверніться до документації ОС.

Поле securityContext у специфікації Podʼа визначає обмеження, що застосовуються до цих процесів. Воно також підтримує інші налаштування безпеки, такі як конкретні capabilities Linux або дозволи на доступ до файлів за допомогою UID і GID. Докладніше дивіться в розділі Налаштування контексту безпеки для Podʼа або контейнера.

seccomp

Деяким вашим робочим навантаженням можуть бути потрібні привілеї для виконання певних дій від імені користувача root на хост-машині вузла. Linux використовує capabilities, щоб розділити доступні привілеї на категорії, тож процеси можуть отримувати привілеї, потрібні для певних дій, без надання всіх привілеїв. Кожна capability має набір системних викликів (syscalls), які може робити процес. seccomp дозволяє обмежувати ці окремі syscalls. Його можна використовувати, щоб ізолювати привілеї процесу в пісочниці, обмежуючи виклики, які він може робити з простору користувача до ядра.

У Kubernetes для запуску контейнерів на кожному вузлі використовується середовище виконання контейнерів. Приклади середовищ — CRI-O, Docker або containerd. Кожне середовище стандартно дозволяє лише підмножину capabilities Linux. Ви можете додатково обмежити дозволені syscalls окремо за допомогою профілю seccomp. Середовища виконання контейнерів зазвичай містять стандартний профіль seccomp. Kubernetes дозволяє автоматично застосовувати до ваших Podʼів і контейнерів профілі seccomp, завантажені на вузол.

Примітка:

У Kubernetes також є налаштування allowPrivilegeEscalation для Podʼів і контейнерів. Якщо встановити його в false, процеси не зможуть отримувати нові capabilities, а непривілейовані користувачі не зможуть змінити застосований профіль seccomp на менш суворий.

Щоб дізнатися, як застосувати seccomp у Kubernetes, дивіться Обмеження системних викликів контейнера за допомогою seccomp або Довідку про seccomp на вузлах.

Докладніше про seccomp дивіться в розділі Seccomp BPF документації ядра Linux.

Міркування щодо seccomp

seccomp — це низькорівнева конфігурація безпеки, яку варто налаштовувати самостійно лише тоді, коли потрібен детальний контроль над системними викликами Linux. Використання seccomp, особливо у великому масштабі, має такі ризики:

  • Конфігурації можуть ламатися під час оновлень застосунків
  • Зловмисники все ще можуть використовувати дозволені syscalls для експлуатації вразливостей
  • Керування профілями окремих застосунків стає складним у великому масштабі

Рекомендація: Використовуйте стандартний профіль seccomp, що постачається з вашим середовищем виконання контейнерів. Якщо потрібне більш ізольоване середовище, розгляньте пісочницю, таку як gVisor. Пісочниці усувають наведені вище ризики власних профілів seccomp, але потребують більше обчислювальних ресурсів на вузлах і можуть мати проблеми сумісності з GPU та іншим спеціалізованим обладнанням.

AppArmor та SELinux: обовʼязковий контроль доступу на основі політик

Для зміцнення робочих навантажень Kubernetes можна використовувати механізми обовʼязкового контролю доступу (MAC) Linux на основі політик, такі як AppArmor і SELinux.

AppArmor

AppArmor — це модуль безпеки ядра Linux, який доповнює стандартні дозволи Linux на основі користувачів і груп, обмежуючи програми певним набором ресурсів. AppArmor можна налаштувати для будь-якого застосунку, щоб зменшити його потенційну поверхню атаки й забезпечити багаторівневий захист. Він налаштовується через профілі, що дозволяють доступ, потрібний конкретній програмі чи контейнеру, зокрема capabilities Linux, мережевий доступ і дозволи на файли. Кожен профіль може працювати в режимі примусового застосування (enforcing), який блокує доступ до заборонених ресурсів, або в режимі скарг (complain), який лише повідомляє про порушення.

AppArmor може допомогти зробити розгортання безпечнішим, обмежуючи дії контейнерів, та/або покращити аудит через системні логи. Середовище виконання контейнерів може постачатися зі стандартним профілем AppArmor, або ви можете використовувати власний профіль.

Щоб дізнатися, як використовувати AppArmor у Kubernetes, дивіться Обмеження доступу контейнера до ресурсів за допомогою AppArmor.

SELinux

SELinux — це модуль безпеки ядра Linux, який дозволяє обмежувати доступ певного субʼєкта, такого як процес, до файлів у вашій системі. Ви визначаєте політики безпеки, які застосовуються до субʼєктів із певними мітками SELinux. Коли процес із міткою SELinux намагається отримати доступ до файлу, сервер SELinux перевіряє, чи дозволяє політика безпеки цього процесу такий доступ, і приймає рішення про авторизацію.

У Kubernetes ви можете встановити мітку SELinux у полі securityContext вашого маніфесту. Вказані мітки призначаються цим процесам. Якщо ви налаштували політики безпеки, що стосуються цих міток, ядро ОС хоста застосовує ці політики.

Щоб дізнатися, як використовувати SELinux у Kubernetes, дивіться Призначення міток SELinux контейнеру.

Різниця між AppArmor та SELinux

Операційна система на ваших вузлах Linux зазвичай містить або AppArmor, або SELinux. Обидва механізми забезпечують схожий захист, але мають такі відмінності:

  • Налаштування: AppArmor використовує профілі для визначення доступу до ресурсів. SELinux використовує політики, які застосовуються до певних міток.
  • Застосування політики: В AppArmor ви визначаєте ресурси за допомогою шляхів до файлів. SELinux ідентифікує ресурс за його індексним дескриптором (inode).

Підсумок можливостей

У наведеній нижче таблиці описано сценарії використання та область дії кожного засобу контролю безпеки. Ви можете використовувати всі ці засоби разом, щоб створити більш захищену систему.

Підсумок можливостей безпеки ядра Linux
Можливість безпекиОписЯк використовуватиПриклад
seccompОбмежуйте окремі виклики ядра в просторі користувача. Зменшує ймовірність того, що вразливість, яка використовує обмежений системний виклик, скомпрометує систему.Вказуйте завантажений профіль seccomp у специфікації Podʼа або контейнера, щоб застосувати його обмеження до процесів у Podʼі.Відхиляйте системний виклик unshare, який використовувався в CVE-2022-0185.
AppArmorОбмежуйте доступ програм до певних ресурсів. Зменшує поверхню атаки програми. Покращує логування аудиту.Вкажіть завантажений профіль AppArmor у специфікації контейнера.Заборонити програмі, що працює лише для читання, запис за будь-яким шляхом у системі.
SELinuxОбмежуйте доступ до ресурсів, таких як файли, застосунки, порти та процеси за допомогою міток та політик безпеки.Вкажіть обмеження доступу для конкретних міток. Позначте процеси цими мітками, щоб застосувати обмеження доступу, повʼязані з міткою.Заборонити контейнеру доступ до файлів поза його власною файловою системою.

Примітка:

Механізми на кшталт AppArmor і SELinux можуть забезпечувати захист, що виходить за межі контейнера. Наприклад, SELinux може допомогти помʼякшити CVE-2019-5736.

Міркування щодо керування власними конфігураціями

seccomp, AppArmor і SELinux зазвичай мають стандартну конфігурацію, що надає базовий захист. Ви також можете створювати власні профілі й політики, що відповідають вимогам ваших робочих навантажень. Керування цими власними конфігураціями та їх розповсюдження у великому масштабі може бути складним, особливо якщо ви використовуєте всі три можливості разом. Для цього використовуйте інструмент на кшталт Kubernetes Security Profiles Operator.

Можливості безпеки на рівні ядра та привілейовані контейнери

Kubernetes дозволяє вказати, що деякі довірені контейнери можуть працювати в привілейованому режимі. Будь-який контейнер у Podʼі може працювати в привілейованому режимі, щоб використовувати адміністративні capabilities операційної системи, які інакше були б недоступні. Це доступно і для Windows, і для Linux.

Привілейовані контейнери явно перевизначають деякі обмеження ядра Linux, які ви можете використовувати у своїх робочих навантаженнях:

  • seccomp: Привілейовані контейнери працюють із профілем seccomp Unconfined, перевизначаючи будь-який профіль seccomp, вказаний у маніфесті.
  • AppArmor: Привілейовані контейнери ігнорують будь-які застосовані профілі AppArmor.
  • SELinux: Привілейовані контейнери працюють у домені unconfined_t.

Привілейовані контейнери

Будь-який контейнер у Podʼі може ввімкнути привілейований режим, якщо встановити privileged: true у полі securityContext контейнера. Привілейовані контейнери перевизначають або скасовують багато інших налаштувань зміцнення безпеки, таких як застосований профіль seccomp, профіль AppArmor або обмеження SELinux. Привілейовані контейнери отримують усі capabilities Linux, зокрема ті, які їм не потрібні. Наприклад, користувач root у привілейованому контейнері може використовувати capabilities CAP_SYS_ADMIN і CAP_NET_ADMIN на вузлі, оминаючи конфігурацію seccomp середовища виконання та інші обмеження.

У більшості випадків слід уникати привілейованих контейнерів і натомість надавати контейнеру потрібні capabilities за допомогою поля capabilities у полі securityContext. Використовуйте привілейований режим, лише якщо потрібна capability, яку не можна надати через securityContext. Це корисно для контейнерів, яким потрібні адміністративні capabilities операційної системи, наприклад для керування мережевим стеком або доступу до апаратних пристроїв.

У Kubernetes 1.26 і новіших ви також можете запускати контейнери Windows у подібному привілейованому режимі, встановивши прапорець windowsOptions.hostProcess у контексті безпеки специфікації Podʼа. Докладніше дивіться в розділі Створення HostProcess Pod для Windows.

Рекомендації

  • Перш ніж налаштовувати можливості безпеки на рівні ядра, розгляньте впровадження ізоляції на рівні мережі. Докладніше читайте в розділі Список перевірки безпеки.
  • Якщо немає потреби в іншому, запускайте робочі навантаження Linux не від імені root, вказавши конкретні ідентифікатори користувача та групи в маніфесті Podʼа та runAsNonRoot: true.

Крім того, ви можете запускати робочі навантаження в просторах імен користувачів, встановивши hostUsers: false у маніфесті Podʼа. Це дозволяє запускати контейнери від імені root у просторі імен користувача, але не від імені root у просторі імен хоста на вузлі. Ця можливість ще на ранніх етапах розробки й може не мати потрібного вам рівня підтримки. Інструкції дивіться в розділі Використання простору імен користувачів із Podʼом.

Що далі