Blogg

Försvar mot container-escapes: En praktisk guide till Docker-isolering för multi-tenant-hosting

Lär dig hur du skyddar Docker-containrar mot sårbarheter för escape och isoleringsfel i multi-tenant-miljöer med konkreta steg och exempel.

Sammanfattning

Docker-containrar delar värdkärnan, vilket gör isolering kritisk – särskilt i multi-tenant-hosting där ett enda container-escape kan kompromettera alla hyresgäster. Många utvecklare antar att containrar är perfekt isolerade virtuella maskiner, men verkligheten är annorlunda. Den här artikeln förklarar Linux-kärnfunktionerna bakom Docker-isolering (namnrymder, cgroups) och attackvektorerna som hotar dem. Du får lära dig praktiska steg för att härda din Docker-installation: begränsa privilegier, använda säker körtid, skanna av bilder och implementera nätverkssegmentering. Genom att följa ett verkligt exempel på en multi-tenant WordPress-hostingleverantör ser du hur du tillämpar dessa skydd. Vi täcker även förbehåll som prestandakompromisser och användning av seccomp/AppArmor. Målet är att ge dig en robust isoleringsstrategi som förhindrar container-escapes och håller dina hyresgäster säkra.

Introduktion

Om du driver en multi-tenant-hostingplattform – oavsett om det är delad WordPress-hosting, en SaaS-applikation eller en utvecklingsmiljötjänst – är container-escape det mardrömsscenario. En sårbarhet i kärnan eller en felkonfiguration kan låta en hyresgäst bryta sig ur sin container och komma åt andra hyresgästdata eller själva värden. Dockers isolering bygger på Linux-kärnfunktioner som namnrymder och cgroups, men standardkonfigurationer är ofta otillräckliga för robust säkerhet. Den här artikeln guidar dig genom attackvektorerna och ger handlingsbara steg för att låsa ner dina Docker-containrar, illustrerat med ett verkligt multi-tenant WordPress-exempel. För en bredare översikt över produktionsorkestrering, se vår guide om Orkestrering av produktionsklara containeriserade applikationer.

Förståelse av Docker-isolering

Docker-containrar använder Linux-namnrymder för att ge processnivåisolering: PID-namnrymder isolerar process-träd, nätverksnamnrymder separerar nätverksgränssnitt, monteringsnamnrymder isolerar filsystemmonteringar och användarnamnrymder tillåter mappning av container-root till en oprivilegierad värdanvändare. Kontrollgrupper (cgroups) begränsar resursanvändning som CPU, minne och disk-I/O. Dessa funktioner skapar tillsammans en "sandlåda" runt varje container. Men till skillnad från en virtuell maskin som kör en separat kärna, delar containrar värdkärnan. Detta innebär att en sårbarhet i kärnan (t.ex. CVE-2022-0492) kan utnyttjas för att bryta sig ur containerns namnrymdsisolering. Dessutom kan felkonfigurationer som att köra containrar som root inuti containern, ge containern alla behörigheter, eller inte släppa onödiga Linux-behörigheter vidga attackytan.

Attackvektorer

Vanliga attackvektorer inkluderar:

  • Kärnexploateringar: Utnyttja en bugg i värdkärnan för att få åtkomst till värden.
  • Privilegierade containrar: Körning med --privileged ger alla behörigheter och kringgår det mesta av isoleringen.
  • Missbruk av behörigheter: Även utan fullständigt privilegierat läge kan en container med farliga behörigheter som CAP_SYS_ADMIN eller CAP_NET_ADMIN montera filsystem eller manipulera nätverksinställningar.
  • Osäkra bildmetoder: Använda basbilder med kända sårbarheter eller inkludera onödiga verktyg som kompilatorer eller skal-tolkar.
  • Delade monteringsnamnrymder: Montering av värdkataloger i containrar kan tillåta escape om de inte är skrivskyddade.

Praktiska säkerhetssteg

1. Kör containrar som en icke-root-användare

Som standard kör Docker containrar som root inuti containern. Om en angripare får root-åtkomst inuti containern har de mer hävstång. Skapa en användare i din Dockerfile och använd USER-direktivet. Undvik också att använda --user-flaggan i Docker Compose för att mappa till en godtycklig värdanvändare om möjligt.

2. Släpp alla behörigheter och lägg bara till nödvändiga

Linux-behörigheter bryter ner superanvändares privilegier i mindre enheter. I Docker Compose, använd cap_drop: ALL och lägg sedan till cap_add endast de nödvändiga (t.ex. NET_BIND_SERVICE). Undvik farliga behörigheter som SYS_ADMIN, NET_ADMIN, SYS_PTRACE.

3. Använd skrivskyddat root-filsystem

Ställ in read_only: true i din containerdefinition. Detta förhindrar angripare från att skriva till containerns filsystem. Om din app behöver skriva temporära filer, montera en tmpfs-volym på den platsen.

4. Aktivera användarnamnrymdsåtermappning

Användarnamnrymdsåtermappning mappar containerns root-användare till en icke-root värdanvändare. Detta lägger till ett isoleringslager, eftersom även om en container-root bryter sig ut, kommer de att ha privilegierna för den återmappade användaren. Aktivera det i /etc/docker/daemon.json med "userns-remap": "default". Var medveten om att detta kan komplicera volymbehörigheter. För mer detaljer, se Bemästra Docker-isolering för säker och effektiv webbhosting.

5. Tillämpa Seccomp och AppArmor/AppArmor-profiler

Seccomp begränsar systemanrop som en container kan göra. Docker tillhandahåller en standard seccomp-profil som blockerar farliga systemanrop. Du kan också skapa egna profiler. Likaså tillhandahåller AppArmor (eller SELinux) obligatorisk åtkomstkontroll. Använd AppArmor för att begränsa din container till en minimal uppsättning tillåtna operationer. Säkerhetsprofilen kan ställas in via security_opt i Docker Compose.

6. Använd minimala basbilder och skanna efter sårbarheter

Välj små bilder som Alpine eller Distroless som har en mindre attackyta. Skanna regelbundet bilder med verktyg som Docker Scout, Trivy eller Clair. Integrera skanning i din CI/CD-pipeline för att förhindra att sårbara bilder distribueras.

7. Nätverkssegmentering med anpassade bryggnätverk

Skapa separata bryggnätverk för varje hyresgäst eller applikationsnivå. Detta begränsar öst-väst-trafik. I Docker Compose, definiera nätverk och isolera tjänster. Använd internal: true om en tjänst inte behöver utgående internetåtkomst. Brandväggsregler på värden begränsar ytterligare trafik mellan containrar.

8. Begränsa resurser med Cgroups

Ställ in CPU- och minnesgränser i Docker Compose med deploy.resources.limits. Detta förhindrar en komprometterad container från att starta en resursutarmningsattack. Ställ dessutom in kernel_memory och memory_reservation för finare kontroll.

Verkligt exempel: Multi-tenant WordPress-hosting med Docker Compose

Överväg ett scenario där du hostar flera WordPress-sajter för olika kunder, var och en i sin egen Docker-container. En osäker installation kan se ut så här:

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:

Denna installation är sårbar: WordPress-containern körs som root inuti, har alla behörigheter (eftersom inga släpps), monterar en värdkatalog med skrivåtkomst och har obegränsad nätverksåtkomst.

Låt oss nu härda den:

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:

Viktiga förbättringar:

  • Båda containrarna körs som icke-root-användare (www-data och mysql).
  • Alla behörigheter släpps, endast NET_BIND_SERVICE läggs till.
  • WordPress-filsystemet är skrivskyddat förutom en tmpfs-montering och en uppladdningsvolym.
  • Seccomp- och AppArmor-profiler tillämpas (du skulle behöva tillhandahålla anpassade profiler).
  • Separata nätverk isolerar webb från databas, med databasnätverket internt.
  • Resursgränser förhindrar resursutarmning.

För mer om WordPress-specifik Docker-härdning, se Docker för WordPress: Varför isolerade containrar förändrar allt.

Förbehåll

  • Återmappning av användarnamnrymd: Även om det är kraftfullt, bryter det volymmontering eftersom den återmappade värd-UID inte är densamma som container-UID. Du kan behöva förskapa kataloger med korrekta behörigheter eller använda Docker-volymer med stöd för återmappning.
  • Seccomp/AppArmor-profiler: Anpassade profiler kräver förståelse för din applikations systemanrops- och filåtkomstmönster. Alltför restriktiva profiler kan bryta funktionaliteten. Testa noggrant.
  • Prestanda: Ytterligare säkerhetslager som seccomp och AppArmor har minimal overhead, men resursgränser och skrivskyddade filsystem kan påverka skrivintensiva applikationer.
  • Orkestreringskomplexitet: I en multi-tenant-miljö kan hantering av Docker Compose-filer per hyresgäst bli otymplig. Överväg att använda ett högre orkestreringsverktyg som Kubernetes, men det medför egna säkerhetsöverväganden.

Slutsats

Container-escape är ett verkligt hot i multi-tenant Docker-hosting, men det kan förebyggas. Genom att förstå isoleringsmekanismerna och tillämpa djupförsvar – släppa behörigheter, köra som icke-root, aktivera användarnamnrymder, seccomp, AppArmor, nätverkssegmentering och regelbunden bildskanning – kan du dramatiskt minska risken. Kom ihåg att Dockers standardinställningar inte är produktionsklara för multi-tenant-arbetsbelastningar. Implementera dessa steg idag för att skydda dina hyresgäster och din infrastruktur. För en omfattande översikt över Docker-säkerhetsbästa praxis, se Säkra dina webbapplikationer med Docker: En praktisk guide till isolering och bästa praxis.

Sources (5)