Blog

Védekezés a konténer-szökés ellen: Gyakorlati útmutató a Docker izolációhoz több-bérlős tárhelyekhez

Ismerje meg, hogyan védheti meg Docker-konténereit a szökési sérülékenységek és az izolációs hibák ellen több-bérlős környezetekben, konkrét lépésekkel és példákkal.

Összefoglaló

A Docker konténerek megosztják a gazdagép kernelét, így az izoláció kritikus fontosságú – különösen több-bérlős tárhelyek esetén, ahol egyetlen konténer-szökés az összes bérlőt veszélyeztetheti. Sok fejlesztő azt hiszi, hogy a konténerek tökéletesen izolált virtuális gépek, de a valóság más. Ez a cikk elmagyarázza a Docker izoláció mögötti Linux kernel funkciókat (névterek, cgroupok) és azokat a támadási vektorokat, amelyek veszélyeztetik őket. Megtanulja a Docker-beállítások megerősítésének gyakorlati lépéseit: a jogosultságok korlátozása, biztonságos futtatókörnyezet használata, képek szkennelése és hálózati szegmentálás megvalósítása. Egy valós, több-bérlős WordPress tárhelyszolgáltató példáján keresztül láthatja, hogyan alkalmazza ezeket a védelmi intézkedéseket. Kitérünk olyan megfontolásokra is, mint a teljesítménybeli kompromisszumok és a seccomp/AppArmor használata. A cél egy robusztus izolációs stratégia biztosítása, amely megakadályozza a konténer-szökéseket és biztonságban tartja bérlőit.

Bevezetés

Ha több-bérlős tárhelyplatformot üzemeltet – legyen az megosztott WordPress tárhely, SaaS alkalmazás vagy fejlesztői környezeti szolgáltatás –, a konténer-szökés az rémálom forgatókönyve. Egy kernel sérülékenység vagy egy helytelen konfiguráció lehetővé teheti egy bérlő számára, hogy kitörjön a konténeréből, és hozzáférjen más bérlők adataihoz vagy magához a gazdagéphez. A Docker izolációja olyan Linux kernel funkciókra támaszkodik, mint a névterek és a cgroupok, de a gyári konfigurációk gyakran nem elegendőek a robusztus biztonsághoz. Ez a cikk végigvezeti Önt a támadási vektorokon, és végrehajtható lépéseket kínál Docker-konténereinek lezárásához, illusztrálva egy valós, több-bérlős WordPress példával. A termelési orchestráció szélesebb körű megtekintéséhez tekintse meg útmutatónkat a Termelésre kész konténeres alkalmazások orchestrálása.

A Docker izoláció megértése

A Docker konténerek Linux névtereket használnak a folyamatszintű izoláció biztosítására: a PID névterek elkülönítik a folyamatfákat, a hálózati névterek szétválasztják a hálózati interfészeket, a mount névterek elkülönítik a fájlrendszer-mountokat, és a felhasználói névterek lehetővé teszik a konténer root felhasználójának egy nem-privilegizált gazdagép felhasználóhoz való hozzárendelését. A Control Groups (cgroupok) korlátozzák az erőforrás-használatot, mint például a CPU, memória és lemez I/O. Ezek a funkciók együtt egy „homokozót” hoznak létre minden konténer körül. Azonban, ellentétben egy virtuális géppel, amely külön kernelt futtat, a konténerek megosztják a gazdagép kernelt. Ez azt jelenti, hogy egy kernel sérülékenysége (pl. CVE-2022-0492) kihasználható a konténer névterének izolációjából való kitöréshez. Ezenkívül a helytelen konfigurációk, mint például a konténeren belüli root felhasználóként futtatás, a konténernek minden képességének megadása, vagy a felesleges Linux képességek el nem dobása, kiszélesíthetik a támadási felületet.

Támadási vektorok

Általános támadási vektorok:

  • Kernel exploitok: A gazdagép kernelének hibájának kihasználása a gazdagéphez való hozzáférés megszerzéséhez.
  • Privilegizált konténerek: A --privileged kapcsolóval futtatás minden képességet megad, és figyelmen kívül hagyja a legtöbb izolációt.
  • Képesség-visszaélés: Még teljes privilegizált mód nélkül is, egy veszélyes képességekkel, mint a CAP_SYS_ADMIN vagy a CAP_NET_ADMIN rendelkező konténer fájlrendszereket mountolhat vagy hálózati beállításokat manipulálhat.
  • Biztonságtalan képességkezelési gyakorlatok: Ismert sérülékenységekkel rendelkező alapképek használata, vagy felesleges eszközök, mint fordítók vagy shell értelmezők beépítése.
  • Megosztott mount névterek: Gazdagép könyvtárak konténerekbe mountolása szökéshez vezethet, ha nem csak olvasható.

Gyakorlati biztonsági lépések

1. Konténerek futtatása nem-root felhasználóként

Alapértelmezés szerint a Docker a konténeren belül root felhasználóként futtatja a konténereket. Ha egy támadó megszerzi a root hozzáférést a konténeren belül, több mozgástere van. Hozzon létre egy felhasználót a Dockerfile-ban, és használja a USER direktívát. Kerülje a --user kapcsoló használatát a Docker Compose-ban, hogy lehetőség szerint egy tetszőleges gazdagép felhasználóhoz rendeljük.

2. Minden képesség eldobása és csak a szükségesek hozzáadása

A Linux képességek a szuperfelhasználói jogosultságokat kisebb egységekre bontják. A Docker Compose-ban használja a cap_drop: ALL parancsot, majd a cap_add paranccsal adja hozzá a szükségeseket (pl. NET_BIND_SERVICE). Kerülje a veszélyes képességeket, mint a SYS_ADMIN, NET_ADMIN, SYS_PTRACE.

3. Csak olvasható gyökérfájlrendszer használata

Állítsa a read_only: true értéket a konténer definíciójában. Ez megakadályozza, hogy a támadók írjanak a konténer fájlrendszerébe. Ha az alkalmazásnak ideiglenes fájlokat kell írnia, mountoljon egy tmpfs kötetet arra a helyre.

4. Felhasználói névtér átirányítás engedélyezése

A felhasználói névtér átirányítás a konténer root felhasználóját egy nem-privilegizált gazdagép felhasználóhoz rendeli hozzá. Ez egy extra izolációs réteget ad, mivel még ha egy konténer root felhasználója ki is törne, akkor is az átirányított felhasználó jogosultságaival rendelkezne. Engedélyezze ezt a /etc/docker/daemon.json fájlban a "userns-remap": "default" beállítással. Vegye figyelembe, hogy ez bonyolíthatja a kötetek engedélyeit. További részletekért tekintse meg a Docker izoláció mesterfogásai a biztonságos és hatékony webes tárhelyekhez útmutatót.

5. Seccomp és AppArmor/AppArmor profilok alkalmazása

A Seccomp korlátozza a konténer által hívható rendszerhívásokat. A Docker egy alapértelmezett seccomp profilt biztosít, amely blokkolja a veszélyes rendszerhívásokat. Egyéni profilokat is készíthet. Hasonlóképpen, az AppArmor (vagy SELinux) kötelező hozzáférés-vezérlést biztosít. Használja az AppArmor-t a konténer korlátozására az engedélyezett műveletek minimális készletére. A biztonsági profil a Docker Compose security_opt opcióján keresztül állítható be.

6. Minimális alapképek használata és sérülékenységek keresése

Válasszon kis képeket, mint az Alpine vagy a Distroless, amelyek kisebb támadási felülettel rendelkeznek. Rendszeresen szkennelje a képeket olyan eszközökkel, mint a Docker Scout, Trivy vagy Clair. Integrálja a szkennelést a CI/CD folyamatába, hogy megakadályozza a sérülékeny képek telepítését.

7. Hálózati szegmentálás egyéni bridge hálózatokkal

Hozzon létre külön bridge hálózatokat minden bérlő vagy alkalmazási réteg számára. Ez korlátozza a kelet-nyugati forgalmat. A Docker Compose-ban definiáljon hálózatokat és izolálja a szolgáltatásokat. Használja az internal: true beállítást, ha egy szolgáltatásnak nincs szüksége kimenő internetkapcsolatra. A gazdagépen lévő tűzfal szabályok tovább korlátozzák a konténerek közötti forgalmat.

8. Erőforrások korlátozása cgroupokkal

Állítson be CPU és memória korlátokat a Docker Compose-ban a deploy.resources.limits használatával. Ez megakadályozza, hogy egy feltört konténer erőforrás-kimerítési támadást indítson. Ezenkívül állítsa be a kernel_memory és a memory_reservation értékeket a finomabb vezérlés érdekében.

Valós példa: Több-bérlős WordPress tárhely Docker Compose-szal

Tekintsünk egy olyan forgatókönyvet, ahol több WordPress webhelyet tárol különböző ügyfelek számára, mindegyiket saját Docker konténerben. Egy biztonságtalan beállítás így nézhet ki:

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:

Ez a beállítás sebezhető: a WordPress konténer belülről root felhasználóként fut, minden képességgel rendelkezik (mivel egyiket sem dobta el), írási hozzáféréssel mountol egy gazdagép könyvtárat, és korlátlan hálózati hozzáféréssel rendelkezik.

Most erősítsük meg:

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:

Főbb fejlesztések:

  • Mindkét konténer nem-root felhasználóként fut (www-data és mysql).
  • Minden képesség eldobva, csak a NET_BIND_SERVICE hozzáadva.
  • A WordPress fájlrendszer csak olvasható, kivéve egy tmpfs mountot és egy feltöltési kötetet.
  • Seccomp és AppArmor profilok alkalmazva (egyéni profilokat kell biztosítani).
  • Külön hálózatok izolálják a webes és az adatbázis-forgalmat, az adatbázis hálózat belső.
  • Erőforrás-korlátok megakadályozzák az erőforrás-kimerülést.

A WordPress-specifikus Docker megerősítéséről többet a Docker WordPresshez: Miért változtat meg mindent az izolált konténerek cikkben olvashat.

Megfontolások

  • Felhasználói névtér átirányítás: Bár hatékony, megszakítja a kötetek mountolását, mert az átirányított gazdagép UID nem egyezik meg a konténer UID-jével. Előre létre kell hoznia a könyvtárakat a megfelelő engedélyekkel, vagy Docker köteteket kell használnia átirányítási támogatással.
  • Seccomp/AppArmor profilok: Az egyéni profilok megkövetelik az alkalmazás rendszerhívásainak és fájlelérési mintáinak ismeretét. A túl szigorú profilok működési problémákat okozhatnak. Alapos tesztelés szükséges.
  • Teljesítmény: További biztonsági rétegek, mint a seccomp és az AppArmor minimális többletterheléssel járnak, de az erőforrás-korlátok és az csak olvasható fájlrendszerek befolyásolhatják az írásintenzív alkalmazásokat.
  • Orchestrációs bonyolultság: Több-bérlős környezetben a bérlőnkénti Docker Compose fájlok kezelése nehézkessé válhat. Fontolja meg egy magasabb szintű orchestrációs eszköz, mint a Kubernetes használatát, de ez saját biztonsági megfontolásokat is felvet.

Következtetés

A konténer-szökés valós fenyegetés a több-bérlős Docker tárhelyeken, de megelőzhető. Az izolációs mechanizmusok megértésével és a védekezés mélységének alkalmazásával – képességek eldobása, nem-root felhasználóként futás, felhasználói névterek engedélyezése, seccomp, AppArmor, hálózati szegmentálás és rendszeres kép szkennelés – drámaian csökkentheti a kockázatot. Ne feledje, hogy a Docker alapértelmezett beállításai nem alkalmasak több-bérlős munkaterhelékekre a termelésben. Valósítsa meg ezeket a lépéseket még ma, hogy megvédje bérlőit és infrastruktúráját. A Docker biztonsági legjobb gyakorlatainak átfogó áttekintéséért tekintse meg a Webalkalmazások biztonságossá tétele Dockerrel: Gyakorlati útmutató az izolációhoz és a legjobb gyakorlatokhoz útmutatót.

Sources (5)