Blog

Forsvar mod Container Escape: En Praktisk Guide til Docker-isolering til Multi-Tenant Hosting

Lær, hvordan du sikrer Docker-containere mod escape-sårbarheder og isolationsfejl i multi-tenant-miljøer med konkrete trin og eksempler.

Oversigt

Docker-containere deler host-kernen, hvilket gør isolering kritisk – især i multi-tenant-hosting, hvor en enkelt container-escape kan kompromittere alle lejere. Mange udviklere antager, at containere er perfekt isolerede virtuelle maskiner, men virkeligheden er anderledes. Denne artikel forklarer Linux-kernens funktioner bag Docker-isolering (navnerum, cgroups) og de angrebsvektorer, der truer dem. Du lærer praktiske trin til at hærde din Docker-opsætning: begrænsning af privilegier, brug af sikker runtime, scanning af images og implementering af netværkssegmentering. Ved at følge et reelt eksempel på en multi-tenant WordPress-hostingudbyder ser du, hvordan du anvender disse forsvar. Vi dækker også forbehold som ydelsesafvejninger og brug af seccomp/AppArmor. Målet er at give dig en robust isolationsstrategi, der forhindrer container-escapes og holder dine lejere sikre.

Introduktion

Hvis du driver en multi-tenant hostingplatform – hvad enten det er delt WordPress-hosting, en SaaS-applikation eller en udviklingsmiljøtjeneste – er container-escape et mareridtsscenarie. En sårbarhed i kernen eller en forkert konfiguration kan lade en lejer bryde ud af deres container og få adgang til andre lejeres data eller selve hosten. Dockers isolering er afhængig af Linux-kernens funktioner som navnerum og cgroups, men standardkonfigurationer er ofte utilstrækkelige til robust sikkerhed. Denne artikel vil guide dig gennem angrebsvektorerne og give handlingsrettede trin til at låse dine Docker-containere ned, illustreret med et reelt multi-tenant WordPress-eksempel. For et bredere overblik over produktionsorkestrering, se vores guide om Orkestrering af Produktionsklare Containeriserede Applikationer.

Forståelse af Docker-isolering

Docker-containere bruger Linux-navnerum til at give proces-niveau isolering: PID-navnerum isolerer proces-træer, netværksnavnerum adskiller netværksinterfaces, mount-navnerum isolerer filsystem-mounts, og bruger-navnerum tillader mapping af container-root til en ikke-privilegeret host-bruger. Kontrolgrupper (cgroups) begrænser ressourceforbruget som CPU, hukommelse og disk I/O. Disse funktioner skaber tilsammen en "sandkasse" omkring hver container. Men i modsætning til en virtuel maskine, der kører en separat kerne, deler containere host-kernen. Dette betyder, at en sårbarhed i kernen (f.eks. CVE-2022-0492) kan udnyttes til at bryde ud af containerens navnerumsisolering. Derudover kan forkert konfiguration som at køre containere som root inde i containeren, give containeren alle kapaciteter eller ikke at droppe unødvendige Linux-kapaciteter udvide angrebsfladen.

Angrebsvektorer

Almindelige angrebsvektorer inkluderer:

  • Kernel-udnyttelser: Udnyttelse af en fejl i host-kernen for at opnå host-adgang.
  • Privilegerede containere: Kørsel med --privileged giver alle kapaciteter og omgår det meste af isoleringen.
  • Kapacitetsmisbrug: Selv uden fuld privilegeret tilstand kan en container med farlige kapaciteter som CAP_SYS_ADMIN eller CAP_NET_ADMIN mounte filsystemer eller manipulere netværksindstillinger.
  • Usikre image-praksisser: Brug af basis-images med kendte sårbarheder eller inkludering af unødvendige værktøjer som compilere eller shell-interpretere.
  • Delte mount-navnerum: Montering af host-mapper ind i containere kan tillade escape, hvis ikke read-only.

Praktiske Sikkerhedstrin

1. Kør Containere som en Ikke-Root Bruger

Som standard kører Docker containere som root inde i containeren. Hvis en angriber får root-adgang inde i containeren, har de mere indflydelse. Opret en bruger i din Dockerfile og brug USER-direktivet. Undgå også at bruge --user-flaget i Docker Compose til at mappe til en vilkårlig host-bruger, hvis muligt.

2. Drop Alle Kapaciteter og Tilføj Kun Nødvendige

Linux-kapaciteter opdeler superuser-privilegier i mindre enheder. I Docker Compose skal du bruge cap_drop: ALL og derefter cap_add kun de nødvendige (f.eks. NET_BIND_SERVICE). Undgå farlige kapaciteter som SYS_ADMIN, NET_ADMIN, SYS_PTRACE.

3. Brug Read-Only Root Filsystem

Indstil read_only: true i din containerdefinition. Dette forhindrer angribere i at skrive til containerens filsystem. Hvis din applikation skal skrive midlertidige filer, skal du mounte et tmpfs-volumen på den placering.

4. Aktiver Bruger-Navnerums-Remapping

Bruger-navnerums-remapping mapper containerens root-bruger til en ikke-privilegeret host-bruger. Dette tilføjer et isolationslag, da selv hvis en container-root bryder ud, vil de have privilegierne af den remappede bruger. Aktiver det i /etc/docker/daemon.json med "userns-remap": "default". Vær opmærksom på, at dette kan komplicere volumen-tilladelser. For flere detaljer, se Mastering Docker Isolation for Secure and Efficient Web Hosting.

5. Anvend Seccomp og AppArmor/AppArmor Profiler

Seccomp begrænser de systemkald, en container kan foretage. Docker leverer en standard seccomp-profil, der blokerer farlige syscalls. Du kan også oprette brugerdefinerede profiler. Tilsvarende giver AppArmor (eller SELinux) obligatorisk adgangskontrol. Brug AppArmor til at begrænse din container til et minimalt sæt af tilladte operationer. Sikkerhedsprofilen kan indstilles via security_opt i Docker Compose.

6. Brug Minimale Basis-Images og Scan for Sårbarheder

Vælg små images som Alpine eller Distroless, der har en mindre angrebsflade. Scan regelmæssigt images med værktøjer som Docker Scout, Trivy eller Clair. Integrer scanning i din CI/CD-pipeline for at forhindre, at sårbare images bliver implementeret.

7. Netværkssegmentering med Brugerdefinerede Bridge-Netværk

Opret separate bridge-netværk for hver lejer eller applikationslag. Dette begrænser øst-vest-trafik. I Docker Compose skal du definere netværk og isolere tjenester. Brug internal: true, hvis en tjeneste ikke har brug for udgående internetadgang. Firewall-regler på hosten begrænser yderligere inter-container-trafik.

8. Begræns Ressourcer med Cgroups

Indstil CPU- og hukommelsesgrænser i Docker Compose ved hjælp af deploy.resources.limits. Dette forhindrer en kompromitteret container i at starte et ressourceudmattelsesangreb. Derudover skal du indstille kernel_memory og memory_reservation for finere kontrol.

Reelt Eksempel: Multi-Tenant WordPress Hosting med Docker Compose

Overvej et scenarie, hvor du hoster flere WordPress-sider for forskellige kunder, hver i sin egen Docker-container. En usikker opsætning kunne se således ud:

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:

Denne opsætning er sårbar: WordPress-containeren kører som root indeni, har alle kapaciteter (da ingen er droppet), monterer en host-mappe med skriveadgang og har ubegrænset netværksadgang.

Lad os nu hærde 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:

Væsentlige forbedringer:

  • Begge containere kører som ikke-root brugere (www-data og mysql).
  • Alle kapaciteter droppet, kun NET_BIND_SERVICE tilføjet.
  • WordPress-filsystemet er read-only undtagen et tmpfs-mount og et uploads-volumen.
  • Seccomp- og AppArmor-profiler anvendes (du skal levere brugerdefinerede profiler).
  • Separate netværk isolerer web fra database, med database-netværket internt.
  • Ressourcegrænser forhindrer ressourceudmattelse.

For mere om WordPress-specifik Docker-hærdning, se Docker til WordPress: Hvorfor isolerede containere ændrer alt.

Forbehold

  • Bruger-Navnerums-Remapping: Selvom det er kraftfuldt, bryder det volumen-montering, fordi den remappede host UID ikke er den samme som containerens UID. Du skal muligvis forudoprette mapper med de korrekte tilladelser eller bruge Docker-volumener med remapping-understøttelse.
  • Seccomp/AppArmor Profiler: Brugerdefinerede profiler kræver forståelse af din applikations syscall- og filadgangsmønstre. Overdrevent restriktive profiler kan bryde funktionaliteten. Test grundigt.
  • Ydeevne: Yderligere sikkerhedslag som seccomp og AppArmor har minimal overhead, men ressourcegrænser og read-only filsystemer kan påvirke skrive-tunge applikationer.
  • Orkestreringskompleksitet: I et multi-tenant miljø kan administration af per-lejer Docker Compose-filer blive uhåndterlig. Overvej at bruge et højere niveau orkestreringsværktøj som Kubernetes, men det introducerer sine egne sikkerhedsovervejelser.

Konklusion

Container-escape er en reel trussel i multi-tenant Docker-hosting, men den kan forebygges. Ved at forstå isoleringsmekanismerne og anvende forsvar i dybden – droppe kapaciteter, køre som ikke-root, aktivere bruger-navnerum, seccomp, AppArmor, netværkssegmentering og regelmæssig image-scanning – kan du dramatisk reducere risikoen. Husk, at Dockers standardindstillinger ikke er produktionsklare til multi-tenant arbejdsbelastninger. Implementer disse trin i dag for at beskytte dine lejere og din infrastruktur. For en omfattende oversigt over Docker-sikkerhed bedste praksis, se Sikring af dine webapplikationer med Docker: En Praktisk Guide til Isolering og Bedste Praksis.

Sources (5)