Blog

Obrana proti úniku kontejnerů: Praktický průvodce izolací Dockeru pro multi-tenant hosting

Naučte se zabezpečit Docker kontejnery proti zranitelnostem úniku a selháním izolace v multi-tenant prostředích pomocí konkrétních kroků a příkladů.

Shrnutí

Docker kontejnery sdílejí kernel hostitele, což činí izolaci kritickou – zejména v multi-tenant hostingu, kde jediný únik z kontejneru může ohrozit všechny tenanty. Mnoho vývojářů předpokládá, že kontejnery jsou dokonale izolované virtuální stroje, ale realita je jiná. Tento článek vysvětluje funkce Linuxového kernelu, které stojí za izolací Dockeru (namespaces, cgroups), a útočné vektory, které je ohrožují. Naučíte se praktické kroky k posílení vaší Docker konfigurace: omezení oprávnění, používání bezpečného runtime, skenování obrazů a implementace síťové segmentace. Na příkladu poskytovatele multi-tenant hostingu WordPress uvidíte, jak tyto obrany aplikovat. Pokrýváme také úskalí, jako jsou kompromisy ve výkonu a použití seccomp/AppArmor. Cílem je poskytnout vám robustní strategii izolace, která zabrání únikům z kontejnerů a udrží vaše tenanty v bezpečí.

Úvod

Pokud provozujete multi-tenant hostingovou platformu – ať už jde o sdílený WordPress hosting, SaaS aplikaci nebo službu vývojového prostředí – únik z kontejneru je noční můrou. Zranitelnost v kernelu nebo špatná konfigurace může jednomu tenantovi umožnit únik z jeho kontejneru a přístup k datům jiných tenantů nebo k samotnému hostiteli. Izolace Dockeru spoléhá na funkce Linuxového kernelu, jako jsou namespaces a cgroups, ale výchozí konfigurace často nejsou pro robustní zabezpečení dostatečné. Tento článek vás provede útočnými vektory a poskytne akční kroky k uzamčení vašich Docker kontejnerů, ilustrované na reálném příkladu multi-tenant hostingu WordPress. Pro širší pohled na orchestraci produkčních prostředí si přečtěte náš průvodce Orchestrace produkčních kontejnerových aplikací.

Pochopení izolace Dockeru

Docker kontejnery používají Linux namespaces k poskytování izolace na úrovni procesů: PID namespaces izolují strom procesů, network namespaces oddělují síťová rozhraní, mount namespaces izolují souborové systémy a user namespaces umožňují mapování root kontejneru na neoprávněného uživatele hostitele. Control groups (cgroups) omezují využití zdrojů, jako je CPU, paměť a I/O disku. Tyto funkce dohromady vytvářejí „sandbox“ kolem každého kontejneru. Na rozdíl od virtuálního stroje, který běží s vlastním kernelem, však kontejnery sdílejí kernel hostitele. To znamená, že zranitelnost v kernelu (např. CVE-2022-0492) může být zneužita k úniku z izolace namespace kontejneru. Navíc špatné konfigurace, jako je spouštění kontejnerů jako root uvnitř kontejneru, udělení kontejneru všech oprávnění nebo neodebrání nepotřebných Linux oprávnění, mohou rozšířit útočnou plochu.

Útočné vektory

Běžné útočné vektory zahrnují:

  • Exploity kernelu: Zneužití chyby v kernelu hostitele k získání přístupu k hostiteli.
  • Privilegované kontejnery: Spuštění s --privileged uděluje všechna oprávnění a obchází většinu izolace.
  • Zneužití oprávnění: I bez plného privilegovaného režimu může kontejner s nebezpečnými oprávněními, jako jsou CAP_SYS_ADMIN nebo CAP_NET_ADMIN, připojovat souborové systémy nebo manipulovat se síťovými nastaveními.
  • Nezabezpečené praktiky obrazů: Používání základních obrazů se známými zranitelnostmi nebo zahrnutí nepotřebných nástrojů, jako jsou kompilátory nebo interpretory shellu.
  • Sdílené mount namespaces: Připojení adresářů hostitele do kontejnerů může umožnit únik, pokud nejsou pouze pro čtení.

Praktické bezpečnostní kroky

1. Spouštějte kontejnery jako uživatel bez oprávnění root

Ve výchozím nastavení Docker spouští kontejnery jako root uvnitř kontejneru. Pokud útočník získá root oprávnění uvnitř kontejneru, má větší páku. Vytvořte uživatele ve svém Dockerfile a použijte direktivu USER. Také se vyhněte použití příznaku --user v Docker Compose k mapování na libovolného uživatele hostitele, pokud je to možné.

2. Odeberte všechna oprávnění a přidejte pouze potřebná

Linuxová oprávnění rozkládají privilegovaná oprávnění na menší jednotky. V Docker Compose použijte cap_drop: ALL a poté cap_add pouze požadovaná (např. NET_BIND_SERVICE). Vyhněte se nebezpečným oprávněním, jako jsou SYS_ADMIN, NET_ADMIN, SYS_PTRACE.

3. Použijte souborový systém root pouze pro čtení

Nastavte read_only: true ve vaší definici kontejneru. To zabrání útočníkům v zápisu do souborového systému kontejneru. Pokud vaše aplikace potřebuje zapisovat dočasné soubory, připojte na toto místo tmpfs volume.

4. Povolte přemapování uživatelského jmenného prostoru (User Namespace Remapping)

Přemapování uživatelského jmenného prostoru mapuje uživatele root kontejneru na uživatele bez oprávnění root na hostiteli. To přidává vrstvu izolace, protože i když uživatel root kontejneru unikne, bude mít oprávnění přemapovaného uživatele. Povolte to v /etc/docker/daemon.json pomocí "userns-remap": "default". Mějte na paměti, že to může zkomplikovat oprávnění volume. Další podrobnosti naleznete v Zvládnutí izolace Dockeru pro bezpečný a efektivní web hosting.

5. Aplikujte profily Seccomp a AppArmor/AppArmor

Seccomp omezuje systémová volání, která kontejner může provést. Docker poskytuje výchozí seccomp profil, který blokuje nebezpečná systémová volání. Můžete také vytvářet vlastní profily. Podobně AppArmor (nebo SELinux) poskytuje povinnou kontrolu přístupu. Použijte AppArmor k omezení vašeho kontejneru na minimální sadu povolených operací. Bezpečnostní profil lze nastavit pomocí security_opt v Docker Compose.

6. Používejte minimální základní obrazy a skenujte na zranitelnosti

Zvolte malé obrazy, jako jsou Alpine nebo Distroless, které mají menší útočnou plochu. Pravidelně skenujte obrazy nástroji jako Docker Scout, Trivy nebo Clair. Integrujte skenování do svého CI/CD pipeline, abyste zabránili nasazení zranitelných obrazů.

7. Síťová segmentace s vlastními bridge sítěmi

Vytvořte oddělené bridge sítě pro každého tenanta nebo aplikační vrstvu. To omezuje provoz mezi servery (east-west traffic). V Docker Compose definujte sítě a izolujte služby. Použijte internal: true, pokud služba nepotřebuje přístup k internetu. Pravidla firewallu na hostiteli dále omezují provoz mezi kontejnery.

8. Omezte zdroje pomocí cgroups

Nastavte limity CPU a paměti v Docker Compose pomocí deploy.resources.limits. To zabrání kompromitovanému kontejneru spustit útok vyčerpání zdrojů. Kromě toho nastavte kernel_memory a memory_reservation pro jemnější kontrolu.

Reálný příklad: Multi-tenant hosting WordPress s Docker Compose

Zvažte scénář, kdy hostujete více webů WordPress pro různé klienty, každý ve svém vlastním Docker kontejneru. Nezabezpečená konfigurace by mohla vypadat takto:

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:

Tato konfigurace je zranitelná: kontejner WordPress běží jako root uvnitř, má všechna oprávnění (protože žádná nejsou odebrána), připojuje adresář hostitele s právem zápisu a má neomezený síťový přístup.

Nyní ji posílíme:

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:

Klíčová vylepšení:

  • Oba kontejnery běží jako uživatelé bez oprávnění root (www-data a mysql).
  • Všechna oprávnění odebrána, přidáno pouze NET_BIND_SERVICE.
  • Souborový systém WordPress je pouze pro čtení kromě tmpfs mountu a volume pro nahrávání.
  • Jsou aplikovány profily Seccomp a AppArmor (bylo by nutné poskytnout vlastní profily).
  • Oddělené sítě izolují web od databáze, přičemž databázová síť je interní.
  • Limity zdrojů zabraňují vyčerpání zdrojů.

Více o posílení Dockeru specificky pro WordPress naleznete v Docker pro WordPress: Proč izolované kontejnery mění vše.

Úskalí

  • Přemapování uživatelského jmenného prostoru (User Namespace Remapping): Ačkoli je mocné, narušuje připojování volume, protože přemapované UID hostitele se neshoduje s UID kontejneru. Možná budete muset předem vytvořit adresáře se správnými oprávněními nebo použít Docker volumes s podporou přemapování.
  • Profily Seccomp/AppArmor: Vlastní profily vyžadují pochopení vzorů systémových volání a přístupu k souborům vaší aplikace. Příliš omezující profily mohou narušit funkčnost. Důkladně testujte.
  • Výkon: Další bezpečnostní vrstvy, jako jsou seccomp a AppArmor, mají minimální režii, ale limity zdrojů a souborové systémy pouze pro čtení mohou ovlivnit aplikace s intenzivním zápisem.
  • Složitost orchestrace: V multi-tenant prostředí se správa souborů Docker Compose pro jednotlivé tenanty může stát neohrabanou. Zvažte použití nástroje pro orchestraci vyšší úrovně, jako je Kubernetes, ale to přináší vlastní bezpečnostní úvahy.

Závěr

Únik z kontejneru je v multi-tenant Docker hostingu reálnou hrozbou, ale je předvídatelný. Pochopením mechanismů izolace a aplikací obrany v hloubce – odebráním oprávnění, spouštěním jako uživatel bez root, povolením uživatelských jmenných prostorů, seccomp, AppArmor, síťovou segmentací a pravidelným skenováním obrazů – můžete dramaticky snížit riziko. Pamatujte, že výchozí nastavení Dockeru nejsou pro produkční multi-tenant zátěž připravena. Implementujte tyto kroky ještě dnes, abyste ochránili své tenanty a svou infrastrukturu. Komplexní přehled osvědčených postupů pro zabezpečení Dockeru naleznete v Zabezpečení vašich webových aplikací pomocí Dockeru: Praktický průvodce izolací a osvědčenými postupy.

Sources (5)