Biztonsági kérdések¶
A konténerek biztonsága kiemelt fontosságú az alkalmazások védelme és az adatok biztonságának megőrzése érdekében. Az utolsó a fejezetben áttekintjük a konténerek néhány biztonsági kérdését, beleértve a konténerizáció biztonsági szempontú előnyeit és kihívásait, valamint bemutatunk néhány, a gyakorlatban is jól hasznosítható módszert.
Szükséges eszközök: |
Windows, MacOS vagy Linux operációs rendszerű számítógép, telepített Docker szoftverrel. |
Feldolgozási idő: |
Kb. 1 óra, a gyakorlati feladatok megoldására további 1 óra. |
A konténerek működtetése során több, informatikai biztonsági szempont is felmerül, lássunk néhányat ezek közül! A legnagyobb kockázatot a felhasználók ellenőrizetlen konténerei jelentik, elsősorban akkor, ha nincsenek megfelelő intézkedések a felhasználók tevékenységének ellenőrzésére és korlátozására. A leggyakoribb kockázatok az alábbiak:
Biztonsági sérülékenységek: egy konténer használatba vétele előtt azt ellenőrizni kell és ki kell értékelni az elindításának kockázatait. Kifejezetten kockázatos, ha a felhasználók ellenőrzés nélkül indíthatnak saját konténereket.
Túlzott erőforráshasználat: a felhasználók által indított konténerek alapesetben korlátlan hozzáféréssel rendelkeznek a rendszer erőforrásai felett, így a teljes infrastruktúrát túlterhelhetik. Ennek következtében nem csak a szóban forgó alkalmazás, hanem a gépen futó más szolgáltatások is teljesítmény csökkentést szenvedhetnek el, vagy teljes egészében elérhetetlenné válhatnak.
Adathozzáférés korlátozása: a konténerek indításának engedélyezése kockázatokat jelenthet az adathozzáférés tekintetében is. A felhasználók hozzáférhetnek olyan adatokhoz is, amelyeket normál helyzetben az operációs rendszer nem tenne lehetővé. Ez végső soron bizalmas információk jogosulatlan megszerzését eredményezheti.
Ismeretlen forrású konténerek: amennyiben a felhasználók saját konténereket indíthatnak, az ismeretlen forrásból származók szintén biztonsági kockázatot jelenthetnek. Ezek a konténerek kártékony kódokat vagy biztonsági réseket tartalmazhatnak, amelyek végső soron a host gép rendszer stabilitását és biztonságát is veszélyeztethetik.
Felügyelet és ellenőrzés: a megfelelő ellenőrzés és a felhasználók által indított konténerek felügyelete nélkül nehéz feladat a biztonsági fenyegetések, a hibás vagy rosszindulatú tevékenységet végző alkalmazások felismerése és gyors válasz adása.
A union fájlrendszer működéséből fakadó adatszivárgás (a dockerhub-ra és más felületre publikált konténerek tartalmazhatnak bizalmas adatokat, amelyeket a klasszikus törléssel nem lehet törölni). Ennek okát a A union fájlrendszer fejezetben ismertettük. A MITRE ATT&CK mátrix (azon belül az ún. Containers Matrix) a támadás egyes lépései szerint csoportosítva gyűjti össze a potenciális támadási lehetőségeket és módszereket. A CIS Benchmark pedig ajánlást tesz a biztonsági szabályok fokozására – és bár ez kifejezetten docker alkalmazásokra koncentrál, de nem szabad elfeledkezni a gazda operációs rendszer megfelelő védelméről sem.
Jogosulatlan hozzáférés¶
A Docker működéséhez nélkülözhetetlen annak háttérfolyamata, amelynek rendszergazdai jogkörökkel kell futnia. Ez a Docker biztonsági achillesi sarka, melyet a konténereket futtató kiszolgálók felépítésekor figyelembe kell venni azért, hogy a konténerekben futó alkalmazás sem futhasson magasabb jogkörrel, mint amit neki szánunk. Az alábbiakban egy példát látunk erre: a konténer alkalmazás megjeleníti a /etc/shadow tartalmát, mely a felhasználók kódolt jelszavait tartalmazza. Ezt a fájlt normális esetben az operációs rendszer normál felhasználói nem olvashatják, de az alábbi példában ezt sikeresen meg lehet kerülni:
A védelem megkerülésére készítsünk egy egyszerű konténert, amely egyetlen parancsot hajt végre, ez a cat /etc/shadow.
FROM ubuntu:latest
LABEL maintainer="koczka.ferenc@uni-eszterhazy.hu"
CMD ["cat", "/etc/shadow"]
Építsük fel a konténert:
1koczka@columbo:~/docker$ docker build -t dockerhack .
Majd indítsuk el úgy, hogy a host gép /etc/shadow fájljával helyettesítsük a konténer /etc/shadow fájlját! A kimenetben látható, hogy a root jogosultságokkal futó konténer képes volt a fájl olvasására és meg tudta jeleníteni annak tartalmát:
1koczka@columbo:~/docker$ docker run -v /etc/shadow:/etc/shadow dockerhack
2root:$6$eSGcg3WD...ebWVEyrJ1Z2WNHCm8qnP3RWIbOAcffV7zUI/.:19627:0:99999:7:::
3daemon:*:19412:0:99999:7:::
4bin:*:19412:0:99999:7:::
Hogyan lehet az ilyen típusú támadásokat kivédeni? Azt első és legfontosabb, hogy üzemeltetőként ne tegyük lehetővé a felhasználók számára a konténerek tetszőleges paraméterekkel történő indítását, azaz felügyeljük azokat. Különösen érzékeny kérdés a kötetek csatolása, ha erre van szükség, mindig alaposan ellenőrizni kell, hogy csak a konténer csak azokat csatolhassa, amelyekre valóban engedélyt adunk. Emellett csak megbízható felhasználók számára tegyük lehetővé a konténer indítását!
Erőforrások védelme¶
Az erőforrások védelmére a docker számos paramétert biztosít, amelyekkel az egyes konténerek kordában tarthatók. A legfontosabb paraméterek CPU-ra és az elérhető memória nagyságának korlátozására szolgálnak. A témával kapcsolatban részletes leírás érhető el a docs.docker.com oldalon, mi most a két legfontosabb erőforrás, a processzorra és a memóriára vonatkozó korlátozását tekintjük át.
A columbo.uni-eszterhazy.hu gép 4 processzor magot tartalmaz, amit a /proc/cpuinfo „fájlból” olvastam ki. A memória nagyságát pedig a free -h --si paranccsal kérdeztem le, ez 3,9G (hát elég sovány már ez a gép, na):
koczka@columbo:~$ cat /proc/cpuinfo | grep processor
processor : 0
processor : 1
processor : 2
processor : 3
koczka@columbo:~$ free -h --si
total used free shared buff/cache available
Mem: 3,9G 895M 445M 1,0M 2,6G 2,7G
Swap: 7,6G 39M 7,6G
Az egyes konténerek számára elérhető erőforrások nagyságát a konténer példányok indításakor meghatározott extra paraméterekkel lehet beállítani. A processzor magok számát --cpus, a memória nagyságát a --memory szabályozza. Ahhoz, hogy a paraméterek hatását láthassuk, indítsunk el két konténert, az egyiket hagyjuk korlátozások nélkül, a másik esetében pedig az elérhető processzor magok számát állítsuk be 1-re, a memória nagyságát pedig 512Mbyte-ra! (A -d hatására tehát a konténer a háttérben fut, a -t pedig biztosítja, hogy az Linux terminál módban működjön, azaz ne lépjen ki azonnal.)
koczka@columbo:~$ docker run -t -d --name unrestricted_linux ubuntu:16.04
ebcdc01e10e3fdaf1d725f2b9b8a0e2adedfc48e4f56609c8326aa39d5dae6a1
koczka@columbo:~$ docker run -t -d --cpus="1" --memory="512M" --name restricted_linux ubuntu:16.04
WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap.
e5961ae5f48371ef623f9fa1c95ae6f8967bc8a85344f8e7717a32205f6cfff3
Az egyes konténerek által felhasznált és elérhető memória mennyiségét a docker stats parancs jeleníti meg. Ebben leolvasható, hogy az unrestricted_linux memória limitje a rendszer teljes, 3.81GiB nagyságú területében van meghatározva, míg ennek értéke a restricted_linux esetében ez csak 512M.
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
e5961ae5f483 restricted_linux 0.00% 2.141MiB / 512MiB 0.42% 0B / 0B 0B / 0B 1
ebcdc01e10e3 unrestricted_linux 0.00% 2.324MiB / 3.81GiB 0.06% 0B / 0B 0B / 0B 1
A processzorra vonatkozó limitek itt nem láthatók, azokat a docker inspect paranccsal lehet ellenőrizni. Ennek kimenete egy JSON fájl, ami esetünkben ugyan nem túl kényelmes, de a --format paraméterrel, vagy a grep szűrővel csak a minket érdeklő, NanoCpus értéket fogjuk megjeleníteni. Az itt látható szám konkrét értéke nehezen értelmezhető, egymilliárd nanocpu felel meg egy CPU magnak. A restricted_linux esetében ez az érték éppen ennyi, az unrestricted_linux 0 értéke pedig azt jelenti, hogy arra nem vonatkozik ilyen típusú korlátozás.
koczka@columbo:~$ docker inspect restricted_linux | grep -i NanoCpus
"NanoCpus": 1000000000,
koczka@columbo:~$ docker inspect unrestricted_linux | grep -i NanoCpus
"NanoCpus": 0,
Végül, takarítsunk ki magunk után! Először állítsuk a konténereket, majd töröljük a hátra maradt példányokat. A felesleges fájlok eltávolításának érdekében töröljük a nem használat image-eket is.
koczka@columbo:~$ docker stop restricted_linux unrestricted_linux
restricted_linux
unrestricted_linux
koczka@columbo:~$ docker rm restricted_linux unrestricted_linux
restricted_linux
unrestricted_linux
koczka@columbo:~$ docker image prune --all -f
Deleted Images:
untagged: ubuntu:16.04
untagged: ubuntu@sha256:1f1a2d56de1d604801a9671f301190704c25d604a416f59e03c04f5c6ffee0d6
deleted: sha256:b6f50765242581c887ff1acc2511fa2d885c52d8fb3ac8c4bba131fd86567f2e
deleted: sha256:0214f4b057d78b44fd12702828152f67c0ce115f9346acc63acdf997cab7e7c8
deleted: sha256:1b9d0485372c5562fa614d5b35766f6c442539bcee9825a6e90d1158c3299a61
deleted: sha256:3c0f34be6eb98057c607b9080237cce0be0b86f52d51ba620dc018a3d421baea
deleted: sha256:be96a3f634de79f523f07c7e4e0216c28af45eb5776e7a6238a2392f71e01069
Total reclaimed space: 134.8MB
Összefoglalás¶
Az utolsó fejezetünk célja, hogy bevezető képet adjon a konténerek biztonságának jelentőségéről és a megfelelő védekezési technikákról. Ebben néhány, a konténerekkel kapcsolatos biztonsági kérdés tekintettünk át, fő célunk egy ízelítő nyújtása volt az alkalmazások biztonságos működésének és adatainak védelmével kapcsolatban. Bemutatásra került a konténerizáció előnyei mellett, néhány olyan gyakorlati módszer, amely hozzájárul a biztonságos működés javításához. Példákon keresztül láttunk, hogy a konténerek ellenőrizetlen használata komoly kockázatot jelenthet, a biztonsági sérülékenységek megjelenése mellett túlzott erőforráshasználat is bekövetkezhet, ami a teljes infrastruktúra működését is negatívan befolyásolhatja. A hozzáférés-korlátozás elengedhetetlen, ellenkező esetben sérül a bizalmasság elve. Az ismeretlen forrásból származó konténerek további veszélyeket hordoznak, kártékony kódokat és biztonsági réseket tartalmazhatnak, ezért a megfelelő felügyelet és ellenőrzés nélkülözhetetlen a biztonsági fenyegetések felismerése és kezelése érdekében. A konténerek futtatása során különös figyelmet kell fordítani a rendszergazdai jogkörökre, a konténerek használata során ezt feltétlenül kerülni kell. Az erőforrások védelmét a docker parancs különböző beállításaival szabályoztuk. Összességében a biztonsági intézkedések foganatosítása a konténer technológia használata esetén is különösen fontos szempont, amely nélkül az informatikai rendszerek stabilitása és integritása nem tartható fenn.
Kérdések, feladatok¶
Miért kiemelten fontos a konténerek biztonsága?
Milyen operációs rendszerek használhatók a Docker telepítéséhez?
Mi a legnagyobb kockázat, amit a felhasználók ellenőrizetlen konténerei jelenthetnek?
Milyen biztonsági intézkedések szükségesek a konténerek elindítása előtt?
Hogyan okozhat túlzott erőforráshasználatot egy konténer?
Milyen kockázatokat jelenthet az adathozzáférés tekintetében a konténerek indítása?
Miért jelenthetnek biztonsági kockázatot az ismeretlen forrású konténerek?
Miért szükséges a konténerek felügyelete és ellenőrzése?
Hogyan kerülhető el, hogy a konténer alkalmazások rendszergazdai jogkörrel fussanak?
Milyen Docker parancsokkal lehet korlátozni egy konténer erőforrásait?
Milyen paranccsal lehet egy konténert úgy elindítani, hogy a host gép /etc/shadow fájlja helyettesítse a konténerben lévőt?
Hogyan lehet elindítani egy Ubuntu 22.04 alapú konténert úgy, hogy az csak 1 CPU magot és 512M memóriát használhasson?
Milyen parancs használható annak ellenőrzésére, hogy mennyi memória érhető el az egyes konténerek számára?
Milyen Docker parancs segítségével ellenőrizhető egy konténer processzor limitje?