Блог

Захист від втечі з контейнера: Практичний посібник з ізоляції Docker для багатоорендного хостингу

Дізнайтеся, як захистити контейнери Docker від вразливостей втечі та збоїв ізоляції в багатоорендних середовищах за допомогою конкретних кроків та прикладів.

Огляд

Контейнери Docker спільно використовують ядро хоста, тому ізоляція є критично важливою — особливо в багатоорендному хостингу, де одна втеча з контейнера може скомпрометувати всіх орендарів. Багато розробників вважають, що контейнери — це ідеально ізольовані віртуальні машини, але реальність інша. Ця стаття пояснює функції ядра Linux, що лежать в основі ізоляції Docker (простори імен, cgroups), та вектори атак, які їм загрожують. Ви дізнаєтеся практичні кроки для зміцнення вашої конфігурації Docker: обмеження привілеїв, використання безпекового середовища виконання, сканування образів та впровадження мережевої сегментації. На прикладі реального постачальника багатоорендного хостингу WordPress ви побачите, як застосувати ці засоби захисту. Ми також розглянемо застереження, такі як компроміси в продуктивності та використання seccomp/AppArmor. Мета — надати вам надійну стратегію ізоляції, яка запобігає втечі з контейнерів і забезпечує безпеку ваших орендарів.

Вступ

Якщо ви керуєте багатоорендною хостинговою платформою — чи то спільний хостинг WordPress, SaaS-додаток, чи сервіс розробницького середовища — втеча з контейнера є кошмаром. Вразливість у ядрі або неправильна конфігурація може дозволити одному орендарю вирватися зі свого контейнера та отримати доступ до даних інших орендарів або самого хоста. Ізоляція Docker покладається на функції ядра Linux, такі як простори імен та cgroups, але конфігурації за замовчуванням часто недостатні для надійного захисту. Ця стаття проведе вас через вектори атак та надасть дієві кроки для блокування ваших контейнерів Docker, проілюстровані реальним багатоорендним прикладом WordPress. Для ширшого огляду оркестрації продакшену дивіться наш посібник з Оркестрації контейнерних додатків, готових до продакшену.

Розуміння ізоляції Docker

Контейнери Docker використовують простори імен Linux для забезпечення ізоляції на рівні процесів: простори імен PID ізолюють дерева процесів, мережеві простори імен розділяють мережеві інтерфейси, простори імен монтування ізолюють файлові системи, а простори імен користувачів дозволяють відображати корінь контейнера на непривілейованого користувача хоста. Групи керування (cgroups) обмежують використання ресурсів, таких як процесор, пам'ять та введення/виведення диска. Ці функції разом створюють «пісочницю» навколо кожного контейнера. Однак, на відміну від віртуальної машини, яка запускає окреме ядро, контейнери спільно використовують ядро хоста. Це означає, що вразливість у ядрі (наприклад, CVE-2022-0492) може бути використана для виходу з ізоляції простору імен контейнера. Крім того, неправильні конфігурації, такі як запуск контейнерів з правами root всередині контейнера, надання контейнеру всіх можливостей або невідкидання непотрібних можливостей Linux, можуть розширити поверхню атаки.

Вектори атак

Поширені вектори атак включають:

  • Експлойти ядра: Використання помилки в ядрі хоста для отримання доступу до хоста.
  • Привілейовані контейнери: Запуск з --privileged надає всі можливості та обходить більшість ізоляції.
  • Зловживання можливостями: Навіть без повного привілейованого режиму, контейнер з небезпечними можливостями, такими як CAP_SYS_ADMIN або CAP_NET_ADMIN, може монтувати файлові системи або маніпулювати мережевими налаштуваннями.
  • Небезпечні практики роботи з образами: Використання базових образів з відомими вразливостями або включення непотрібних інструментів, таких як компілятори або інтерпретатори оболонки.
  • Спільні простори імен монтування: Монтування каталогів хоста в контейнери може дозволити втечу, якщо вони не є тільки для читання.

Практичні кроки безпеки

1. Запускайте контейнери від імені непривілейованого користувача

За замовчуванням Docker запускає контейнери від імені root всередині контейнера. Якщо зловмисник отримує права root всередині контейнера, він має більше важелів впливу. Створіть користувача у вашому Dockerfile та використовуйте директиву USER. Також уникайте використання прапора --user у Docker Compose для відображення на довільного користувача хоста, якщо це можливо.

2. Відкиньте всі можливості та додайте лише необхідні

Можливості Linux розбивають привілеї суперкористувача на менші одиниці. У Docker Compose використовуйте cap_drop: ALL, а потім cap_add лише необхідні (наприклад, NET_BIND_SERVICE). Уникайте небезпечних можливостей, таких як SYS_ADMIN, NET_ADMIN, SYS_PTRACE.

3. Використовуйте файлову систему root тільки для читання

Встановіть read_only: true у визначенні вашого контейнера. Це запобігає запису зловмисниками у файлову систему контейнера. Якщо вашому додатку потрібно записувати тимчасові файли, змонтуйте том tmpfs у цьому місці.

4. Увімкніть перепризначення простору імен користувачів

Перепризначення простору імен користувачів відображає користувача root контейнера на непривілейованого користувача хоста. Це додає рівень ізоляції, оскільки навіть якщо root контейнера вирветься, він матиме привілеї перепризначеного користувача. Увімкніть його в /etc/docker/daemon.json за допомогою "userns-remap": "default". Майте на увазі, що це може ускладнити дозволи томів. Для отримання додаткової інформації дивіться Опанування ізоляції Docker для безпечного та ефективного веб-хостингу.

5. Застосовуйте профілі Seccomp та AppArmor/AppArmor

Seccomp обмежує системні виклики, які може робити контейнер. Docker надає профіль seccomp за замовчуванням, який блокує небезпечні системні виклики. Ви також можете створювати власні профілі. Аналогічно, AppArmor (або SELinux) забезпечує обов'язковий контроль доступу. Використовуйте AppArmor для обмеження вашого контейнера мінімальним набором дозволених операцій. Профіль безпеки можна встановити через security_opt у Docker Compose.

6. Використовуйте мінімальні базові образи та скануйте на наявність вразливостей

Вибирайте невеликі образи, такі як Alpine або Distroless, які мають меншу поверхню атаки. Регулярно скануйте образи за допомогою таких інструментів, як Docker Scout, Trivy або Clair. Інтегруйте сканування у ваш конвеєр CI/CD, щоб запобігти розгортанню вразливих образів.

7. Мережева сегментація за допомогою користувацьких мостових мереж

Створюйте окремі мостові мережі для кожного орендаря або рівня додатків. Це обмежує трафік між сервісами (east-west). У Docker Compose визначайте мережі та ізолюйте сервіси. Використовуйте internal: true, якщо сервіс не потребує вихідного доступу до Інтернету. Правила брандмауера на хості додатково обмежують трафік між контейнерами.

8. Обмежуйте ресурси за допомогою cgroups

Встановіть ліміти процесора та пам'яті в Docker Compose за допомогою deploy.resources.limits. Це запобігає запуску атаки вичерпання ресурсів скомпрометованим контейнером. Крім того, встановіть kernel_memory та memory_reservation для точнішого контролю.

Реальний приклад: Багатоорендний хостинг WordPress з Docker Compose

Розглянемо сценарій, де ви розміщуєте кілька сайтів WordPress для різних клієнтів, кожен у своєму контейнері Docker. Небезпечна конфігурація може виглядати так:

version: '3'
services:
  wordpress:
    image: wordpress:latest
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb
    volumes:
      - ./wp-content:/var/www/html/wp-content
  db:
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_ROOT_PASSWORD: somewordpress
    volumes:
      - db_data:/var/lib/mysql
volumes:
  db_data:

Ця конфігурація вразлива: контейнер WordPress запускається від імені root всередині, має всі можливості (оскільки жодні не відкинуті), монтує каталог хоста з доступом на запис і має необмежений мережевий доступ.

Тепер давайте зміцнимо її:

version: '3'
services:
  wordpress:
    image: wordpress:latest
    user: www-data
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
    read_only: true
    tmpfs:
      - /var/www/html/wp-content/plugins
    security_opt:
      - seccomp=seccomp-profile.json
      - apparmor=wordpress-profile
    networks:
      - frontend
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb
    volumes:
      - wp-uploads:/var/www/html/wp-content/uploads
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 256M
  db:
    image: mysql:5.7
    user: mysql
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
    networks:
      - backend
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_ROOT_PASSWORD: somewordpress
    volumes:
      - db_data:/var/lib/mysql
    deploy:
      resources:
        limits:
          cpus: '0.25'
          memory: 128M
networks:
  frontend:
    driver: bridge
    internal: false
  backend:
    driver: bridge
    internal: true
volumes:
  wp-uploads:
  db_data:

Ключові покращення:

  • Обидва контейнери запускаються від імені непривілейованих користувачів (www-data та mysql).
  • Всі можливості відкинуті, додано лише NET_BIND_SERVICE.
  • Файлова система WordPress доступна тільки для читання, за винятком монтування tmpfs та тому завантажень.
  • Застосовуються профілі Seccomp та AppArmor (вам потрібно буде надати власні профілі).
  • Окремі мережі ізолюють веб від бази даних, причому мережа бази даних є внутрішньою.
  • Ліміти ресурсів запобігають вичерпанню ресурсів.

Щоб дізнатися більше про специфічне для WordPress зміцнення Docker, дивіться Docker для WordPress: чому ізольовані контейнери змінюють усе.

Застереження

  • Перепризначення простору імен користувачів: Хоча це потужно, це порушує монтування томів, оскільки перепризначений UID хоста не збігається з UID контейнера. Вам може знадобитися попередньо створити каталоги з правильними дозволами або використовувати томи Docker з підтримкою перепризначення.
  • Профілі Seccomp/AppArmor: Власні профілі вимагають розуміння шаблонів системних викликів та доступу до файлів вашого додатку. Надмірно обмежувальні профілі можуть порушити функціональність. Ретельно тестуйте.
  • Продуктивність: Додаткові рівні безпеки, такі як seccomp та AppArmor, мають мінімальні накладні витрати, але обмеження ресурсів та файлові системи тільки для читання можуть вплинути на додатки з інтенсивним записом.
  • Складність оркестрації: У багатоорендному середовищі керування файлами Docker Compose для кожного орендаря може стати громіздким. Розгляньте можливість використання інструменту оркестрації вищого рівня, такого як Kubernetes, але це вносить власні міркування безпеки.

Висновок

Втеча з контейнера є реальною загрозою в багатоорендному хостингу Docker, але її можна запобігти. Розуміючи механізми ізоляції та застосовуючи багаторівневий захист — відкидаючи можливості, запускаючи від імені непривілейованого користувача, увімкнувши простори імен користувачів, seccomp, AppArmor, мережеву сегментацію та регулярне сканування образів — ви можете значно зменшити ризик. Пам'ятайте, що налаштування Docker за замовчуванням не готові до продакшену для багатоорендних робочих навантажень. Впровадьте ці кроки сьогодні, щоб захистити своїх орендарів та свою інфраструктуру. Для комплексного огляду найкращих практик безпеки Docker зверніться до Захист ваших веб-додатків за допомогою Docker: Практичний посібник з ізоляції та найкращих практик.

Sources (5)