Блог

Одбрана од бекства из контејнера: Практични водич за изолацију Docker-а за вишезакупно хостовање

Сазнајте како да заштитите Docker контејнере од рањивости бекства и кварова изолације у окружењима са више закупаца, уз конкретне кораке и примере.

Резиме

Docker контејнери деле хост кернел, чинећи изолацију критичном — посебно у вишезакупном хостовању где једно бекство из контејнера може компромитовати све закупце. Многи програмери претпостављају да су контејнери савршено изоловане виртуелне машине, али стварност је другачија. Овај чланак објашњава функције Линукс кернела које стоје иза Docker изолације (нејмспејсови, цгроупс) и векторе напада који их угрожавају. Научићете практичне кораке за побољшање вашег Docker подешавања: ограничавање привилегија, коришћење сигурног рунтајма, скенирање имиџа и имплементација мрежне сегментације. Пратећи пример из стварног света вишезакупног WordPress хостинг провајдера, видећете како да примените ове одбране. Такође покривамо напомене попут компромиса у перформансама и употребе сеццомпу/АппАрмора. Циљ је да вам пружимо робусну стратегију изолације која спречава бекство из контејнера и чува ваше закупце безбедним.

Увод

Ако управљате платформом за вишезакупно хостовање — било да је то дељено WordPress хостовање, СааС апликација или услуга развојног окружења — бекство из контејнера је сценарио из ноћне море. Рањивост у кернелу или погрешна конфигурација може омогућити једном закупцу да се пробије из свог контејнера и приступи подацима других закупаца или самом хосту. Docker изолација се ослања на функције Линукс кернела попут нејмспејсова и цгроупса, али подешавања која се добијају ван кутије често нису довољна за робусну безбедност. Овај чланак ће вас провести кроз векторе напада и пружити акционе кораке за закључавање ваших Docker контејнера, илустровано примером вишезакупног WordPress-а из стварног света. За широк преглед оркестрације у продукцији, погледајте наш водич о Оркестрацији контејнерских апликација спремних за продукцију.

Разумевање Docker изолације

Docker контејнери користе Линукс нејмспејсове за пружање изолације на нивоу процеса: ПИД нејмспејсови изолују дрвеће процеса, мрежни нејмспејсови одвајају мрежне интерфејсе, моунт нејмспејсови изолују моунтоване фајл системе, а кориснички нејмспејсови омогућавају мапирање корена контејнера на непривилегованог хост корисника. Контролне групе (цгроупс) ограничавају коришћење ресурса као што су ЦПУ, меморија и И/О диска. Ове функције заједно стварају „песковит простор“ око сваког контејнера. Међутим, за разлику од виртуелне машине која покреће одвојен кернел, контејнери деле хост кернел. То значи да се рањивост у кернелу (нпр. ЦВЕ-2022-0492) може искористити за бекство из изолације нејмспејсова контејнера. Поред тога, погрешне конфигурације попут покретања контејнера као роот унутар контејнера, давања свих могућности контејнеру, или неиспуштања непотребних Линукс могућности могу проширити површину напада.

Вектори напада

Уобичајени вектори напада укључују:

  • Искоришћавање кернела: Искоришћавање грешке у хост кернелу за добијање приступа хосту.
  • Привилеговани контејнери: Покретање са --privileged даје све могућности и заобилази већину изолације.
  • Злоупотреба могућности: Чак и без пуног привилегованог режима, контејнер са опасним могућностима попут CAP_SYS_ADMIN или CAP_NET_ADMIN може моунтовати фајл системе или манипулисати мрежним подешавањима.
  • Несигурне праксе имиџа: Коришћење основних имиџа са познатим рањивостима или укључивање непотребних алата попут компајлера или интерпретера шела.
  • Заједнички моунт нејмспејсови: Моунтовање хост директорија у контејнере може омогућити бекство ако нису само за читање.

Практични безбедносни кораци

1. Покрените контејнере као корисник који није роот

Подразумевано, Docker покреће контејнере као роот унутар контејнера. Ако нападач добије роот приступ унутар контејнера, има више полуге. Направите корисника у вашем Dockerfile-у и користите USER директиву. Такође, избегавајте коришћење --user флага у Docker Compose-у за мапирање на произвољног хост корисника ако је могуће.

2. Одбаците све могућности и додајте само потребне

Линукс могућности разбијају суперкорисничке привилегије на мање јединице. У Docker Compose-у, користите cap_drop: ALL, а затим cap_add само потребне (нпр. NET_BIND_SERVICE). Избегавајте опасне могућности попут SYS_ADMIN, NET_ADMIN, SYS_PTRACE.

3. Користите роот фајл систем само за читање

Поставите read_only: true у дефиницији вашег контејнера. Ово спречава нападаче да пишу у фајл систем контејнера. Ако ваша апликација треба да пише привремене фајлове, моунтујте tmpfs волумен на тој локацији.

4. Омогућите ремапирање корисничких нејмспејсова

Ремапирање корисничких нејмспејсова мапира корисника роот контејнера на непривилегованог хост корисника. Ово додаје слој изолације, јер чак и ако роот контејнера побегне, имаће привилегије ремапираног корисника. Омогућите га у /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 pipeline да бисте спречили деплој рањивих имиџа.

7. Мрежна сегментација са прилагођеним мостовима (bridge networks)

Креирајте одвојене мостове за сваког закупца или слој апликације. Ово ограничава источни-западни саобраћај. У 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 контејнер се покреће као роот унутар, има све могућности (пошто ниједна није одбачена), моунтује хост директоријум са приступом писању и има неограничен мрежни приступ.

Сада да га побољшамо:

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 профили (морали бисте да обезбедите прилагођене профиле).
  • Одвојене мреже изолују веб од базе података, са унутрашњом мрежом базе података.
  • Ограничења ресурса спречавају исцрпљивање ресурса.

Више о Docker побољшањима специфичним за WordPress, погледајте Docker за WordPress: Зашто изоловани контејнери мењају све.

Напомене

  • Ремапирање корисничких нејмспејсова: Иако моћно, квари моунтање волумена јер ремапирани хост УИД није исти као УИД контејнера. Можда ћете морати унапред да креирате директоријуме са исправним дозволама или користите Docker волумене са подршком за ремапирање.
  • Seccomp/AppArmor профили: Прилагођени профили захтевају разумевање образаца системских позива и приступа фајловима ваше апликације. Превише рестриктивни профили могу покварити функционалност. Тестирајте темељно.
  • Перформансе: Додатни слојеви безбедности попут seccomp-а и AppArmor-а имају минималан надзорни трошак, али ограничења ресурса и фајл системи само за читање могу утицати на апликације са интензивним писањем.
  • Комплексност оркестрације: У окружењу са више закупаца, управљање Docker Compose фајловима по закупцу може постати незграпно. Размотрите коришћење алата за оркестрацију вишег нивоа попут Kubernetes-а, али то уводи сопствене безбедносне разматрања.

Закључак

Бекство из контејнера је стварна претња у вишезакупном Docker хостовању, али се може спречити. Разумевањем механизама изолације и применом одбране у дубину — одбацивањем могућности, покретањем као корисник који није роот, омогућавањем корисничких нејмспејсова, seccomp-а, AppArmor-а, мрежне сегментације и редовног скенирања имиџа — можете драматично смањити ризик. Запамтите да подразумевана Docker подешавања нису спремна за продукцију за вишезакупна оптерећења. Примените ове кораке данас да бисте заштитили своје закупце и своју инфраструктуру. За свеобухватан преглед најбољих пракси Docker безбедности, погледајте Обезбеђивање ваших веб апликација са Docker-ом: Практични водич за изолацију и најбоље праксе.

Sources (5)