Tinklaraštis

Apsauga nuo konteinerio pabėgimo: praktinis Docker izoliavimo vadovas daugia nuomininkų talpinimui

Sužinokite, kaip apsaugoti Docker konteinerius nuo pabėgimo pažeidžiamumų ir izoliavimo gedimų daugia nuomininkų aplinkose, naudojant konkrečius veiksmus ir pavyzdžius.

Santrauka

Docker konteineriai dalijasi pagrindinio kompiuterio branduoliu, todėl izoliavimas yra kritiškas – ypač daugia nuomininkų talpinime, kur vienas konteinerio pabėgimas gali pakenkti visiems nuomininkams. Daugelis kūrėjų mano, kad konteineriai yra visiškai izoliuotos virtualios mašinos, tačiau realybė yra kitokia. Šiame straipsnyje paaiškinamos Linux branduolio funkcijos, kuriomis grindžiamas Docker izoliavimas (vardų erdvės, cgroups), ir jas keliančios grėsmes atakos vektoriai. Sužinosite praktinius veiksmus, kaip sustiprinti savo Docker sąranką: apriboti privilegijas, naudoti saugų vykdymo laiką, skenuoti vaizdus ir įgyvendinti tinklo segmentavimą. Sekdami realaus pasaulio daugia nuomininkų WordPress talpinimo paslaugų teikėjo pavyzdį, pamatysite, kaip taikyti šias gynybines priemones. Taip pat aptariame išimtis, tokias kaip našumo kompromisai ir seccomp/AppArmor naudojimas. Tikslas – suteikti jums tvirtą izoliavimo strategiją, kuri užkirstų kelią konteinerio pabėgimui ir užtikrintų jūsų nuomininkų saugumą.

Įvadas

Jei valdote daugia nuomininkų talpinimo platformą – nesvarbu, ar tai bendras WordPress talpinimas, SaaS programa, ar kūrimo aplinkos paslauga – konteinerio pabėgimas yra košmariškas scenarijus. Branduolio pažeidžiamumas arba netinkama konfigūracija gali leisti vienam nuomininkui pabėgti iš savo konteinerio ir pasiekti kitų nuomininkų duomenis arba patį pagrindinį kompiuterį. Docker izoliavimas remiasi Linux branduolio funkcijomis, tokiomis kaip vardų erdvės ir cgroups, tačiau standartinės konfigūracijos dažnai nepakankamos tvirtam saugumui. Šiame straipsnyje apžvelgsime atakos vektorius ir pateiksime veiksmingų veiksmų, kaip užrakinti Docker konteinerius, iliustruodami realaus pasaulio daugia nuomininkų WordPress pavyzdžiu. Daugiau informacijos apie gamybos orkestravimą rasite mūsų vadove Gamybai paruoštų konteinerizuotų programų orkestravimas.

Docker izoliavimo supratimas

Docker konteineriai naudoja Linux vardų erdves procesų lygio izoliavimui: PID vardų erdvės izoliuoja procesų medžius, tinklo vardų erdvės atskiria tinklo sąsajas, prijungimo vardų erdvės izoliuoja failų sistemos prijungimus, o vartotojų vardų erdvės leidžia susieti konteinerio root su neprivilegijuotu pagrindinio kompiuterio vartotoju. Kontrolės grupės (cgroups) riboja išteklių naudojimą, pvz., CPU, atminties ir disko I/O. Šios funkcijos kartu sukuria „smėlio dėžę“ aplink kiekvieną konteinerį. Tačiau, skirtingai nei virtuali mašina, kuri naudoja atskirą branduolį, konteineriai dalijasi pagrindinio kompiuterio branduoliu. Tai reiškia, kad branduolio pažeidžiamumas (pvz., CVE-2022-0492) gali būti išnaudotas norint pabėgti iš konteinerio vardų erdvės izoliavimo. Be to, netinkamos konfigūracijos, pvz., konteinerio paleidimas kaip root viduje, suteikiant konteineriui visas galimybes arba neatsisakant nereikalingų Linux galimybių, gali padidinti atakos paviršių.

Atakos vektoriai

Dažni atakos vektoriai apima:

  • Branduolio išnaudojimai: Pagrindinio kompiuterio branduolio klaidos išnaudojimas siekiant gauti prieigą prie pagrindinio kompiuterio.
  • Privilegijuoti konteineriai: Paleidimas su --privileged suteikia visas galimybes ir apeina daugumą izoliavimo priemonių.
  • Galimybių piktnaudžiavimas: Net ir be visiško privilegijuoto režimo, konteineris su pavojingomis galimybėmis, tokiomis kaip CAP_SYS_ADMIN arba CAP_NET_ADMIN, gali prijungti failų sistemas arba manipuliuoti tinklo nustatymais.
  • Ne saugios vaizdų praktikos: Naudojant pagrindinius vaizdus su žinomais pažeidžiamumais arba įtraukiant nereikalingus įrankius, tokius kaip kompiliatoriai ar apvalkalo interpretatoriai.
  • Bendros prijungimo vardų erdvės: Prijungiant pagrindinio kompiuterio katalogus prie konteinerių, gali kilti pabėgimo rizika, jei jie nėra tik skaitymo režimu.

Praktiniai saugos veiksmai

1. Konteinerius paleiskite kaip ne root vartotojas

Pagal numatytuosius nustatymus Docker konteinerius viduje paleidžia kaip root. Jei atakuotojas gauna root prieigą konteinerio viduje, jis turi daugiau galimybių. Sukurkite vartotoją savo Dockerfile ir naudokite USER direktyvą. Taip pat venkite naudoti --user žymą Docker Compose, kad susietumėte su atsitiktiniu pagrindinio kompiuterio vartotoju, jei įmanoma.

2. Atsisakykite visų galimybių ir pridėkite tik reikalingas

Linux galimybės suskaido supervartotojo privilegijas į mažesnius vienetus. Docker Compose naudokite cap_drop: ALL, tada cap_add tik reikalingas (pvz., NET_BIND_SERVICE). Venkite pavojingų galimybių, tokių kaip SYS_ADMIN, NET_ADMIN, SYS_PTRACE.

3. Naudokite tik skaitymo root failų sistemą

Nustatykite read_only: true savo konteinerio apibrėžime. Tai neleidžia atakuotojams rašyti į konteinerio failų sistemą. Jei jūsų programai reikia rašyti laikinus failus, prijunkite tmpfs garsumą toje vietoje.

4. Įgalinkite vartotojų vardų erdvės persiuntimą

Vartotojų vardų erdvės persiuntimas susieja konteinerio root vartotoją su neprivilegijuotu pagrindinio kompiuterio vartotoju. Tai suteikia papildomą izoliavimo sluoksnį, nes net jei konteinerio root pabėga, jis turės persiųsto vartotojo privilegijas. Įgalinkite tai /etc/docker/daemon.json su "userns-remap": "default". Turėkite omenyje, kad tai gali apsunkinti garsumų leidimus. Daugiau informacijos rasite Docker izoliavimo valdymas saugiam ir efektyviam žiniatinklio talpinimui.

5. Taikykite Seccomp ir AppArmor/AppArmor profilius

Seccomp apriboja sistemos iškvietimus, kuriuos gali atlikti konteineris. Docker pateikia standartinį seccomp profilį, kuris blokuoja pavojingus sistemos iškvietimus. Taip pat galite kurti pasirinktinius profilius. Panašiai AppArmor (arba SELinux) teikia privalomą prieigos kontrolę. Naudokite AppArmor, kad apribotumėte savo konteinerį iki minimalaus leidžiamų operacijų rinkinio. Saugos profilį galima nustatyti per security_opt Docker Compose.

6. Naudokite minimalius pagrindinius vaizdus ir skenuokite dėl pažeidžiamumų

Pasirinkite mažus vaizdus, tokius kaip Alpine ar Distroless, kurie turi mažesnį atakos paviršių. Reguliariai skenuokite vaizdus su įrankiais, tokiais kaip Docker Scout, Trivy ar Clair. Integruokite skenavimą į savo CI/CD procesą, kad būtų išvengta pažeidžiamų vaizdų diegimo.

7. Tinklo segmentavimas su pasirinktiniais tilto tinklais

Kiekvienam nuomininkui ar programos lygiui sukurkite atskirus tilto tinklus. Tai riboja ryšių srautą tarp serverių. Docker Compose apibrėžkite tinklus ir izoliuokite paslaugas. Naudokite internal: true, jei paslauga nereikalauja prieigos prie interneto. Pagrindinio kompiuterio ugniasienės taisyklės dar labiau apriboja ryšius tarp konteinerių.

8. Ribokite išteklius su cgroups

Nustatykite CPU ir atminties ribas Docker Compose naudodami deploy.resources.limits. Tai neleidžia pažeistam konteineriui paleisti išteklių išeikvojimo atakos. Be to, nustatykite kernel_memory ir memory_reservation tikslesniam valdymui.

Pavyzdys iš realaus pasaulio: Daugia nuomininkų WordPress talpinimas su Docker Compose

Apsvarstykite scenarijų, kai talpinate kelias WordPress svetaines skirtingiems klientams, kiekvieną savo Docker konteineryje. Nesaugus nustatymas gali atrodyti taip:

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:

Šis nustatymas yra pažeidžiamas: WordPress konteineris viduje veikia kaip root, turi visas galimybes (kadangi niekas nenutraukta), prijungia pagrindinio kompiuterio katalogą su rašymo prieiga ir turi neribotą tinklo prieigą.

Dabar sustiprinkime jį:

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:

Pagrindiniai patobulinimai:

  • Abu konteineriai veikia kaip ne root vartotojai (www-data ir mysql).
  • Visos galimybės atmestos, pridėta tik NET_BIND_SERVICE.
  • WordPress failų sistema yra tik skaitymo, išskyrus tmpfs garsumą ir įkėlimų garsumą.
  • Taikomi Seccomp ir AppArmor profiliai (reikėtų pateikti pasirinktinius profilius).
  • Atskiri tinklai izoliuoja žiniatinklį nuo duomenų bazės, duomenų bazės tinklas yra vidinis.
  • Išteklių ribos neleidžia išeikvoti išteklių.

Daugiau informacijos apie specifinį WordPress Docker stiprinimą rasite Docker WordPress: Kodėl izoliuoti konteineriai keičia viską.

Pastabos

  • Vartotojų vardų erdvės persiuntimas: Nors ir galingas, jis sutrikdo garsumų prijungimą, nes persiųstas pagrindinio kompiuterio UID nesutampa su konteinerio UID. Gali tekti iš anksto sukurti katalogus su tinkamais leidimais arba naudoti Docker garsumus su persiuntimo palaikymu.
  • Seccomp/AppArmor profiliai: Pasirinktiniai profiliai reikalauja suprasti jūsų programos sistemos iškvietimų ir failų prieigos modelius. Per daug ribojantys profiliai gali sutrikdyti funkcionalumą. Kruopščiai išbandykite.
  • Našumas: Papildomi saugos sluoksniai, tokie kaip seccomp ir AppArmor, turi minimalų papildomą apkrovą, tačiau išteklių ribos ir tik skaitymo failų sistemos gali turėti įtakos intensyviai rašantiems programoms.
  • Orkestravimo sudėtingumas: Daugia nuomininkų aplinkoje, valdyti kiekvieno nuomininko Docker Compose failus gali tapti sudėtinga. Apsvarstykite aukštesnio lygio orkestravimo įrankio, pvz., Kubernetes, naudojimą, tačiau tai sukelia savo saugumo svarstymus.

Išvada

Konteinerio pabėgimas yra reali grėsmė daugia nuomininkų Docker talpinime, tačiau jo galima išvengti. Suprasdami izoliavimo mechanizmus ir taikydami gynybą iš kelių sluoksnių – atsisakydami galimybių, veikdami kaip ne root, įgalindami vartotojų vardų erdves, seccomp, AppArmor, tinklo segmentavimą ir reguliarų vaizdų skenavimą – galite žymiai sumažinti riziką. Atminkite, kad Docker standartiniai nustatymai nėra paruošti gamybai daugia nuomininkų darbo krūviams. Įgyvendinkite šiuos veiksmus šiandien, kad apsaugotumėte savo nuomininkus ir infrastruktūrą. Išsamų Docker saugos geriausių praktikų apžvalgą rasite Saugumo užtikrinimas jūsų žiniatinklio programoms su Docker: praktinis izoliavimo ir geriausių praktikų vadovas.

Sources (5)