Блог

Практичен списък за сигурност на изолацията на Docker за многотенентен хостинг

Осигурете своя многотенентен Docker хостинг с този практически списък, обхващащ потребители без root права, възможности (capabilities), seccomp, пространства от имена на потребители, ограничения на ресурси и само за четене файлови системи.

Резюме

Многотенентният Docker хостинг изисква силна изолация за предотвратяване на излизания от контейнери. Тази статия предоставя практически списък за сигурност, обхващащ шест ключови области: работа като non-root, премахване на възможности, прилагане на seccomp профили, активиране на пренасочване на потребителски пространства от имена, задаване на ограничения за ресурси и използване на само за четене коренови файлови системи. Всяка стъпка включва конкретен пример за конфигурация за Docker Compose. Ще научите и често срещани капани като проблеми със съвместимостта на ядрото с потребителски пространства от имена и компромиси с производителността при прилагане на seccomp. Следвайки този списък, можете значително да намалите повърхността за атака, без да добавяте ненужна сложност. Статията завършва с препоръчителна базова конфигурация за продукционни многотенентни среди.

Ако управлявате многотенентна Docker среда, призракът на атака за излизане от контейнер ви държи будни през нощта. Един експлойт на ядрото може да излезе от контейнер и да даде на атакуващия неограничен достъп до хоста и данните на всички останали наематели. Въпреки че Docker предоставя мощни примитиви за изолация—пространства от имена, cgroups и възможности—неправилната конфигурация оставя празнини. Тази статия представя поетапен списък за сигурност, който можете да приложите днес. Всяка стъпка включва работещ фрагмент за Docker Compose и ключови предупреждения. В края ще имате укрепена базова линия, която балансира сигурност и производителност.

1. Стартиране на контейнери като потребител без root права

Контейнерите по подразбиране се изпълняват като root вътре в контейнера. Ако атакуващ придобие root в контейнера, той има преднина при излизане. Винаги дефинирайте потребител без root права във вашия Dockerfile.

FROM alpine:3.18
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

В Compose можете също да зададете потребителя директно:

services:
  app:
    image: myapp
    user: "1000:1000"

Предупреждение: Някои приложения изискват root за легитимни операции (например свързване към портове под 1024). Използвайте CAP_NET_BIND_SERVICE вместо да стартирате целия контейнер като root. За по-задълбочен преглед на основите на изолацията вижте нашето ръководство за постигане на истинска многотенентна изолация в Docker.

2. Премахване на всички възможности и добавяне само на необходимите

Възможностите на Linux предоставят на контейнерите фино настроени привилегии. По подразбиране Docker предоставя набор от възможности. Премахнете всички и предоставете само необходимите.

services:
  app:
    image: myapp
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE  # ако е необходимо

Предупреждение: Възможности като SYS_ADMIN или NET_RAW рядко са необходими. Одитирайте вашето приложение, за да определите минималния набор. Премахването на всички възможности блокира много вектори за излизане.

3. Прилагане на Seccomp профил

Seccomp (сигурен изчислителен режим) филтрира системните извиквания, достъпни за контейнера. Docker идва с профил seccomp по подразбиране, който блокира опасни системни извиквания като clone с определени флагове. Можете да го персонализирате допълнително.

services:
  app:
    image: myapp
    security_opt:
      - seccomp=/path/to/custom-profile.json

Укрепен профил може да блокира unshare, ptrace и mount. Започнете с профила по подразбиране на Docker и ограничете повече. Предупреждение: Прекалено строгите профили могат да нарушат работата на приложенията. Тествайте задълбочено в среда за тестване. За повече информация относно защитата срещу излизане от контейнери, прочетете защита срещу излизане от контейнер.

4. Активиране на пренасочване на потребителско пространство от имена

Потребителските пространства от имена картографират root потребителя на контейнера към непривилегирован потребител на хоста. Това означава, че дори ако атакуващ придобие root вътре в контейнера, той няма специални привилегии на хоста.

Активирайте го на Docker демона чрез редактиране на /etc/docker/daemon.json:

{
  "userns-remap": "default"
}

След това рестартирайте Docker. Предупреждение: Пренасочването на потребителско пространство от имена има два недостатъка: нарушава монтирането на томове, ако не е конфигурирано внимателно (файловете се притежават от пренасочвания потребител) и е несъвместимо с някои драйвери за съхранение като overlay2 на по-стари ядра. Тествайте задълбочено.

5. Задаване на ограничения на ресурсите с Cgroups

Ограниченията на ресурсите предотвратяват атаки за отказ на услуга от компрометиран контейнер срещу хоста. Използвайте cgroups за ограничаване на CPU, памет и диск I/O.

services:
  app:
    image: myapp
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

За Docker Compose v3 използвайте секцията deploy (работи с swarm или compose v2). За обикновен Docker използвайте --memory и --cpus. Предупреждение: Задаването на твърде ниски ограничения може да доведе до убиване поради липса на памет (OOM). Следете използването и коригирайте съответно.

6. Използване на само за четене коренова файлова система

Само за четене коренова файлова система предотвратява записването на злонамерени двоични файлове или промяна на конфигурационни файлове вътре в контейнера.

services:
  app:
    image: myapp
    read_only: true
    tmpfs:
      - /tmp:noexec,nosuid,size=64m

Монтирайте tmpfs на директории, които се нуждаят от достъп за запис (като /tmp). Това принуждава всички записваеми данни да бъдат временни. Предупреждение: Някои приложения изискват постоянно съхранение; използвайте именувани томове за това.

Често срещани капани

  • Съвместимост на ядрото: Пренасочването на потребителско пространство от имена и някои seccomp правила изискват скорошно Linux ядро (4.14+). Проверете версията на вашето ядро.
  • Влияние върху производителността: Seccomp и потребителските пространства от имена добавят малко допълнително натоварване, но то е незначително за повечето работни натоварвания. Направете бенчмарк на вашето конкретно приложение.
  • Сложност: Добавянето на всичките шест мерки наведнъж може да наруши нещата. Приложете ги една по една, тествайте всяка промяна.

За по-широк преглед на моделите за оркестрация вижте нашето ръководство за проектиране на многотенентна Docker архитектура.

Заключение

Сигурният многотенентен Docker хост не изисква екзотични инструменти—просто правилно използване на вградените функции на Docker. Започнете с потребител без root права, премахнете всички възможности, приложете seccomp профил, активирайте пренасочване на потребителско пространство от имена, задайте ограничения на ресурсите и използвайте файлова система само за четене. Този списък формира силна базова линия, която блокира най-често срещаните техники за излизане. След внедряване, пуснете инструменти за сигурност като docker-bench-security, за да проверите конфигурацията си. Запомнете: сигурността е процес, а не продукт. С появата на нови уязвимости на ядрото, преразгледайте настройките си. За автоматизирани целеви страници, които представят вашата хостинг услуга, използвайте Pagenza, за да стартирате сайта си за минути.

Sources (5)