Tinklaraštis

Docker konteinerių griežtinimas daugianario prieglobai: žingsnis po žingsnio izoliacijos vadovas

Sužinokite, kaip apsaugoti Docker konteinerius daugianario aplinkose naudojant praktines saugumo priemones, tokias kaip ne root naudotojai, atimtos galimybės, tik skaitymui skirtos failų sistemos ir tinklo izoliacija.

Santrauka

Daugianario Docker prieglobos platformos vykdymas reikalauja hermetiškos konteinerių izoliacijos, kad būtų išvengta nuomininkų tarpusavio trukdžių ar pabėgimo į pagrindinę sistemą. Šis vadovas pateikia konkretų, nuoseklų griežtinimo procesą, kurį galite pritaikyti jau šiandien. Sužinosite, kaip konfigūruoti ne root naudotojus, atimti nereikalingas Linux galimybes, prijungti failų sistemas tik skaitymo režimu, taikyti išteklių limitus naudojant cgroups, segmentuoti tinklus ir taikyti seccomp ar AppArmor profilius. Taip pat aptarsime, kada sustiprinti konteinerius virtualiomis mašinomis maksimaliam saugumui užtikrinti. Pabaigoje turėsite kontrolinį sąrašą, kad sistemingai pašalintumėte įprastus konteinerių pabėgimo vektorius ir išlaikytumėte savo daugianario infrastruktūrą tikrai izoliuotą.

Tikroji problema su daugianario konteineriais

Docker konteineriai dalijasi pagrindinės sistemos branduoliu, o jei izoliacija sukonfigūruota neteisingai, vienas nuomininkas teoriškai gali pasiekti kito duomenis, sunaudoti visą CPU ar net pabėgti į pagrindinę sistemą. Kaip prieglobos tiekėjui, jums reikia hermetiškų ribų neaukojant konteinerių našumo privalumų. Daug komandų pradeda nuo numatytųjų Docker nustatymų, kurie yra skirti kūrimui, o ne gamybinei daugianariai veiklai. Geros naujienos: su sistemingu griežtinimo kontroliniu sąrašu galite užrakinti kiekvieną konteinerį iki beveik VM izoliacijos lygio, išlaikydami Docker greitį.

Šis straipsnis jus veda per kiekvieną griežtinimo žingsnį su praktiniais pavyzdžiais ir įspėjimais. Pabaigoje turėsite pakartojamą procesą, skirtą diegti saugius daugianario konteinerius.

1 žingsnis: paleiskite konteinerius kaip ne root naudotojas

Pagal numatytuosius nustatymus Docker konteineriai paleidžiami kaip root. Jei konteineris yra kompromituotas, atakuotojas įgyja root teises konteineryje ir gali bandyti pabėgti iš konteinerio. Pirmiausia sukurkite skirtą naudotoją savo Docker faile ir perjunkite į jį:

FROM ubuntu:22.04
RUN useradd -m appuser
USER appuser

Įspėjimas: kai kuriems procesams (pvz., prisijungimui prie portų < 1024) reikia root. Tokiais atvejais naudokite --cap-add vėliavėlę, kad suteiktumėte tik reikiamą galimybę, pvz., --cap-add=NET_BIND_SERVICE, ir vis tiek vykdykite procesą kaip ne root naudotojas.

Daugiau apie pagrindinę izoliaciją skaitykite mūsų vadove kaip pasiekti tikrą daugianario izoliaciją Docker.

2 žingsnis: Atimkite visas Linux galimybes ir pridėkite atgal tik tai, ko jums reikia

Linux galimybės suskaido root teises į mažus vienetus. Docker konteineriai turi numatytąjį galimybių rinkinį, kuris yra per daug leidus daugianario prieglobai. Atimkite visas ir pridėkite atgal tik tai, ko reikalauja jūsų programa:

docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE my-app

Dažniausiai vengtinos galimybės: SYS_ADMIN (konteinerio pabėgimas), NET_RAW (paketų šniukštinėjimas), SYS_PTRACE (proceso derinimas). Naudokite docker run su --security-opt no-new-privileges, kad išvengtumėte teisių eskalavimo per setuid dvejetainius failus.

3 žingsnis: Prijunkite pagrindinę failų sistemą kaip tik skaitymui

Atakuotojai dažnai rašo kenkėjiškus scenarijus į konteinerio failų sistemą. Padarę pagrindinę failų sistemą tik skaitymui, jūs to išvengsite:

docker run --read-only --tmpfs /tmp:rw,noexec,nosuid,size=64m my-app

--tmpfs sukuria laikiną rašomąjį prijungimą tokiems katalogams kaip /tmp ir /var/run. noexec vėliavėlė neleidžia vykdyti kodą iš to prijungimo. Šis metodas verčia atakuotojus judėti per rašomuosius katalogus, kuriuos galite stebėti.

4 žingsnis: Taikykite išteklių limitus naudodami cgroups

Neapriboti konteineriai gali atlikti paslaugų atsisakymo atakas išeikvodami pagrindinės sistemos atmintį arba CPU. Naudokite Docker vykdymo apribojimus:

docker run --memory=512m --memory-swap=512m --cpus=0.5 --pids-limit=100 my-app
  • --memory ir --memory-swap nustato kietus limitus (be swap).
  • --cpus riboja CPU.
  • --pids-limit užkerta kelią fork bomboms ribodamas procesų skaičių.

Įspėjimas: išteklių limitai yra taikomi naudojant cgroups, tačiau jie neapsaugo nuo duomenų išgavimo per tinklą. Derinkite su tinklo izoliacija (kitas žingsnis).

5 žingsnis: Segmentuokite tinklus naudodami Docker pasirinktinius tinklus

Pagal numatytuosius nustatymus Docker konteineriai dalijasi tiltiniu tinklu. Daugianario sąrankoje turite izoliuoti kiekvieno nuomininko tinklo steką. Sukurkite skirtą tinklą kiekvienam nuomininkui:

docker network create tenant-alpha --internal
docker run --network tenant-alpha my-app

Naudokite --internal vėliavėlę, kad blokuotumėte išėjimo interneto prieigą, tada atidarykite tik reikiamus portus per -p. Dėl pažangesnės tinklo segmentacijos apsvarstykite saugumo užtikrinimą žiniatinklio programoms su Docker izoliacija.

Įspėjimas: vidiniai tinklai neleidžia tiesioginio konteinerių bendravimo tarp nuomininkų, tačiau DNS nutekėjimai vis tiek gali įvykti, jei naudojate pagrindinio kompiuterio tinklą. Laikykitės tiltinių arba overlay tinklų.

6 žingsnis: Taikykite Seccomp ir AppArmor profilius

Seccomp filtruoja sistemos iškvietimus, o AppArmor (arba SELinux) taiko privalomą prieigos kontrolę. Docker pateikia numatytąjį seccomp profilį, kuris blokuoja pavojingus sistemos iškvietimus, pvz., clone su tam tikromis vėliavėlėmis. Dėl griežtesnės izoliacijos sukurkite pasirinktinį profilį:

docker run --security-opt seccomp=./custom.json --security-opt apparmor=docker-default my-app

Galite sugeneruoti bazinį profilį naudodami docker run --rm -it --security-opt seccomp=unconfined my-app strace -c -S time ir tada sumažinti. Įspėjimas: per daug ribojantys profiliai gali sugadinti teisėtą funkcionalumą. Kruopščiai išbandykite bandomojoje aplinkoje.

7 žingsnis: Apsvarstykite hibridinę izoliaciją su virtualiomis mašinomis

Jei jūsų nuomininkai reikalauja absoliučios izoliacijos (pvz., reguliuojama pramonė), paleiskite konteinerius lengvoje VM. Įrankiai, tokie kaip Sysbox arba Kata Containers, suteikia aparatinės įrangos lygio atskyrimą neaukojant konteinerio greičio. Tai yra požiūris, naudojamas Docker Enhanced Container Isolation (ECI). Nors pridėtinės sąnaudos yra didesnės nei pliki konteineriai, jos yra daug mažesnės nei pilnos VM vienai darbo krūviui.

Daugiau apie tinkamo izoliacijos lygio pasirinkimą skaitykite daugianario Docker architektūros projektavimas.

Viską sudedame į vieną vietą: griežtinimo kontrolinis sąrašas

  1. Kurkite konteinerius su ne root naudotoju.
  2. Atimkite visas galimybes, pridėkite tik būtinas.
  3. Prijunkite failų sistemą tik skaitymui su laikinais rašomaisiais prijungimais.
  4. Nustatykite atminties, CPU ir PID limitus.
  5. Sukurkite izoliuotus Docker tinklus kiekvienam nuomininkui.
  6. Taikykite pasirinktinius seccomp ir AppArmor profilius.
  7. Įvertinkite hibridinius VM konteinerius didelio saugumo poreikiams.

Išvada

Konteinerių griežtinimas nėra vienkartinė užduotis – tai nuolatinė disciplina. Pirmiau pateikti žingsniai sudaro saugumo pagrindą daugianario prieglobai. Atminkite, kad jokia atskira priemonė negarantuoja saugumo; gynyba gylyje yra esminė. Pradėkite nuo pagrindų: ne root naudotojų ir atimtų galimybių. Tada pridėkite išteklių limitus ir tinklo segmentaciją. Labiausiai jautriems darbo krūviams derinkite konteinerius su VM. Su šiuo vadovu galite užtikrintai diegti daugianario Docker aplinkas, kurios yra ir efektyvios, ir saugios.

Sources (5)