Az Docker hónapokig futhat produkciós környezetben látható probléma nélkül. A konténerek elindulnak, az alkalmazások válaszolnak, semmi nem omlik össze. Majd egyetlen nyitott port vagy egyetlen helytelen engedély biztosít behatolási lehetőséget, amelyért egy támadónak egyébként keményen meg kellett volna küzdenie. A legtöbb Docker biztonsági hiba nem tűnik hibának mindaddig, amíg valami rosszul nem lesz.
Ez a cikk azokat a konfigurációkat ismerteti, amelyek a konténer-környezeteket veszélyeztetik, hogy mit tesz lehetővé a támadónak, és egy ellenőrző listával zárul, amelyet még ma futtathat a saját rendszerén.
Miért Nehezebb a Docker Biztonság, Mint Gondolnák
A konténerek izolálnak. Elindítasz egyet, saját folyamattérben fut, és belülről a következő konténer nem létezik. Valóban kapsz izolálást, de csak részleges. A konténerek megosztják a gazdagép kernelét, ami azt jelenti, hogy a konténeren belüli folyamat specifikus feltételek mellett elérheti az egész gazdarendszert.
A Docker konténerek fejlesztői kényelemhez vannak konfigurálva, nem produkciós megerősítéshez. Root hozzáférés be van kapcsolva. Az összes port az összes interfészhez köthető. Nincs futásidejű monitorozás. A legtöbb fejlesztő elfogadja ezeket a beállításokat, kiadja a konténert, és halad tovább. Ez ésszerű megközelítés az elkezdéshez, de nem egy kész biztonsági háló.
Szerint A Red Hat 2024-es Kubernetes Biztonsági státuszjelentése, a szervezetek 67%-a késleltette vagy lassította az alkalmazás telepítéseit a konténer vagy Kubernetes biztonsági aggályok miatt. Ez a súrlódás általában nem támadásokból ered. Azokból az esetekből, amikor a csapatok felfedezik, hogy a konténer beállításaikat megerősíteni kellett volna, de ezt nem tették meg.
Gyakran látunk olyan konténereket produkciós környezetben, amelyek pontosan ugyanaz a konfiguráció, mint amit a fejlesztő helyi gépén használt. Itt szoktak a Docker biztonsági hibák halomra gyűlni csendesen, látható tünetek nélkül mindaddig, amíg valami átvizsgálásra kerül vagy meghiúsul.
Az ezeket az rést okozó hibák konkrétak, előrejelezhetetlenek és nagyrészt elkerülhetőek, a konfiguráció szintjétől kezdve.
Gyakori Docker Konfigurációs Hibák
A legtöbb konténer-behatolás nem nulladik napi exploittal kezdődik. Az első nap végén végzett konfigurációval kezdődik, gyakorlatilag anélkül, hogy gondolkodtak volna a hálózati kitettségről vagy a jogosultság köréről.
Az alapértelmezett Docker beállítások azért vannak, hogy működjenek. A működőképes és a biztonságos között van a szakadék, ahol a Docker konténer biztonsági kockázatok gyűlnek fel, főleg az önfinanszírozott, telepített és soha nem újravizsgált rendszerekben.
Ezt a mintát gyakran látjuk: konténerek nyilvános IP-szám szervereken, port kötésekkel, felhasználói beállításokkal és hálózati konfigurációkkal, pontosan úgy, ahogy az kezdeti telepítéskor voltak.
Konténerek Futtatása Root Felhasználóként
Amikor elindítasz egy Docker konténert felhasználó megadása nélkül, root felhasználóként fut. Ez azt jelenti, hogy a konténeren belüli bármely folyamat, beleértve az alkalmazást, root szintű jogosultságokkal rendelkezik a konténer névterén belül.

A konténeren belüli root nem ugyanaz, mint a root a gazdagépen, de az elkülönülés nem abszolút. A jogosultságeszkalációs exploitok a futtatókörnyezet ellen, mint a jól dokumentált runc CVE-2019-5736 és hasonló futtatókörnyezeti hiányosságok, gyakran egy root konténer folyamatot igényelnek a sikerhez.
A nem root konténerek eltávolítják a root folyamat követelményt, amelyre ezek az exploitok támaszkodnak, jelentősen szűkítve az ezt az osztályt célzó sérülékenységek támadási felületét, bár nem szüntetik meg teljesen a konténer escape kockázatát.
A USER direktíva hozzáadása a Dockerfilehoz megoldja ezt. Egyes hivatalos rendszerképek egy nem privilegizált felhasználóval szállnak, amelyet USER direktívával aktiválhat, de sok még mindig root alapértelmezettértékkel rendelkezik, felhasználó nélkül. Ebben az esetben a felhasználót a Dockerfilejében hozza létre, mielőtt átváltana. A legtöbb önfinanszírozott beállítás esetén ez az egyetlen változtatás egy egész osztályt szüntet meg az eszkalációs kockázatból.
Túl Sok Port Kitétettsége a Nyilvános Internetre
Amikor portot publikálsz a Docker-vel, a Docker saját iptables szabályokat ír közvetlenül. Ezek a szabályok a gazdagép szintű tűzfal szabályok előtt futnak. Ez egy a közösség által jól ismert viselkedés és a Docker csomagszűrési útmutatójában dokumentálva, nem helytelen konfiguráció, és azt jelenti, hogy az UFW és hasonló eszközök nem blokkolják azt, amit a Docker már megnyitott.

Az Docker közvetlenül az iptables-be ír, megkerülve az UFW és firewalld alapértelmezéseit számos Linux hoston. Ez azt jelenti, hogy egy 0.0.0.0-hoz kötött port nyilvánosan elérhető lehet, még akkor is, ha a tűzfal konfigurálva van. A felhő biztonsági csoportok és a DOCKER-USER lánc szabályai továbbra is blokkolhatják ezt a forgalmat, így a tényleges kitettség az adott hálózati beállításoktól függ.
Kösd a szolgáltatásokat a 127.0.0.1-hez, ahol csak lehetséges, és az internetre néző forgalmat fordított proxyn keresztül irányítsd. Csak azt közzé, amit valóban szükséges nyilvánosságra hozni. A fordított proxy a legmegbízhatóbb módja annak, hogy szabályozd, mit érhető el kívülről.
A Konténerek Közötti Hálózat Elkülönítésének Negligálása
Az adott hálózaton lévő bármely konténer elérhet bármelyik másik konténert korlátozás nélkül. Az alapértelmezett híd nem alkalmaz forgalom szűrést az azt megosztó konténerek között, és a legtöbb beállítás soha nem változtatja meg ezt a konfigurációt.

Ha egy konténer kompromittálódik, az ezt a nyílt kommunikációt laterális mozgási útként lehet használni. Az előtér konténer elérhet egy adatbázishoz, egy belső API-hez, vagy bármi máshoz ugyanazon az alapértelmezett híd hálózaton, még akkor is, ha ezt az hozzáférést soha nem szándékozták.
A felhasználó által definiált hálózatok explicit vezérlést adnak arról, mely konténerek kommunikálhatnak egymással, de egyetlen egyéni hálózat, amelyet az összes szolgáltatásod megoszt, még mindig lehetővé teszi az ingyenes konténer közötti forgalmat. A valódi elkülönítés megköveteli, hogy az olyan szolgáltatásokat, amelyeknek nem kellene beszélniük egymáshoz, külön hálózatokra helyezd. Az alapértelmezett híd kikapcsolása a kezdeti pont, nem a célszalag.
Az Docker Socket Figyelmen Kívül Hagyása
Az Docker socket a /var/run/docker.sock helyen az egész Docker motor vezérlő felülete. Ha becsatolod egy konténerbe, az a konténer közvetlen API hozzáféréssel rendelkezik a hoston futó démonhoz.

Ezzel a hozzáféréssel egy konténer új konténereket indíthat, gazda könyvtárakat csatolhat, futó konténereket ellenőrizhet és módosíthat, és gyakorlatilag vezérelheti a gépet. A támadási felület egyenértékű a host-on a root-tal, ezért minden olyan eszköz, amely socket hozzáférést igényel, gondos értékelést érdemel.
A legtöbb alkalmazásnál vannak biztonságosabb alternatívák: korlátozottan használható API-ek vagy Docker menedzsment eszközök amelyek nem igényelnek socket hozzáférést. A Docker-in-Docker megoldásnak saját biztonsági és működési kompromisszumai vannak, és nem egyenes helyettesítés.
A konfigurációs hibák teremtik meg a kezdeti kitettséget. A kép és függőség választásai azt határozzák meg, hogyan halmozódnak fel ezek a kitettségek az idő múlásával.
Kép és Titok Kezelési Hibák, Amelyek Túlélik a Konténert
Amikor leállítasz egy konténert, az abban lévő konfigurációs hibák vele szűnnek meg. Amikor olyan képből építsz újra, amely sebezhetőséget vagy rögzített jelszót tartalmaz, a probléma újraindul a konténerrel. A képszintű hibák nem állnak vissza az implementációk között.
Az obraza minden olyan környezetbe utaznak, amely lehúzza azt, minden regisztrációs adatbázishoz, amely tárcsálja, és minden csapattaghoz, aki futtatja. Ez az állékonyság a kép és titok kezelést egy külön kockázati kategóriává teszi, amely megérdemli az önálló auditálást a konfigurációtól elkülönítve.
Gyakran látjuk ezt a mintát: egy kép, amelyet a projekt kezdetén gondosan választottak ki, és azóta soha nem építették újra, fokozatosan eltávolodva attól a biztonsági alaptól, amelyet kezdetben képviselt.
Nem Megbízható vagy Elavult Képek Használata
A nyilvános regisztrációs adatbázisok nyitottak mindenki előtt. Rosszindulatú képeket terjesztettek a Docker Hub-on keresztül kriptobányász szoftverrel és hátsó ajtókkal, amelyeket a réteg története tartalmaz, és a konténer újraindítása után is megmaradnak. Az ellenőrzés a letöltés előtt fontos, különösen az ismeretlen vagy nem hivatalos kiadóktól származó képeknél.

Az elkülönített probléma az elavultság. Egy olyan hivatalos kép, amelyet hat hónapja húztál le, és azóta soha nem építetted újra, a Docker sebezhetőségeket halmozta fel minden egyes CVE közleménnyel, amelyet a csomagjaira közöltek. A kép nem törött. Egyszerűen már nem aktuális.
A Sonatype 2024-es State of the Software Supply Chain jelentése azt találta, hogy az idő 95%-ában, amikor egy sebezhetőséggel rendelkező komponenst felhasználnak, már elérhető egy javított verzió, és az alkalmazás függőségeinek 80%-a több mint egy évig nem frissül. Ez a minta a Docker alapképekre is vonatkozik, mivel azok ugyanazokra a nyílt forráskódú csomagokra támaszkodnak.
Hiteles kiadóktól származó hivatalos képeket használj, és konkrét verziójelzésekre hivatkozz ahelyett, hogy a "latest" címkére támaszkodnál. Dolgozz ki rendszeres frissítési ütemezést, hogy a képeid mindig naprakészek legyenek.
Titkok hardkódolása Docker-fájlokban és Compose-fájlokban
A Docker fájlba, ENV vagy ARG utasításba beírt hitelesítési adatok, a Compose környezeti blokkjában hardcoded értékek, build argumentumként átadott vagy verziókezelésbe commitolt .env fájlban tárolt jelszavak nem tűnnek el a container leállítása után. Megmaradnak a képréteg előzményeiben vagy a forráskódban, és bárki elérheti őket, aki hozzáfér valamelyikhez.

Ez az egyik leggyakrabban figyelmen kívül hagyott Docker biztonsági hiba, mert fejlesztés közben nem okoz látható problémákat. Az API kulcs az ENV utasításban megfelelően működik. Benne van a tárolóban, beépítve az képbe, és terjedésre kerül bárhova az képed utazik.
A modern Docker Compose natív titkosítási mechanizmust támogat, amely futásidőben csatolja be a hitelesítési adatokat anélkül, hogy azok a képbe kerülnének. A Docker titkosításai, az API és a külső titkosítási kezelők ugyanezt az elvet követik. Ezek az opciók biztosítják, hogy a hitelesítési adatok teljesen távol maradjanak a build-összeállítások és a véglegesített fájlok közül.
A futtatási környezeti változók jobb megoldás, mint a kódba égető hitelesítő adatok, de az Docker inspect kimenetén, naplókon és hibaösszesítéseken keresztül továbbra is láthatók. Előrelépés a beépített titkokhoz képest, de nem végső megoldás.
A konténer lemezképeket nem frissítik rendszeresen
Hónapok alatt ugyanazt a képet futtatni gyakori szokás. Minden egyes nap, amely egy új sebezhetőség nyilvánosságra kerülése és az újraépítés között eltelik, a tárolóid egy növekvő kitettség időszakot hordoznak, amely szemmel nem látható módon nő.
Hozz létre egy rendszeres frissítési ütemtervet. Ahol lehetséges, automatizáld ezt a folyamatot, és rendszeresen futtass sebezhetőségi vizsgálatot az aktuális image-eiden. A cél nem a tökéletesség. Hanem az, hogy csökkentsd az időt a patch kiadása és az üzembe helyezése között.
Gyors telepítések során az access control és monitoring könnyen háttérbe szorulhat. Pedig pont ezekben a területekben maradnak a biztonsági incidensek a legtovább észrevétlenül.
Hozzáférés-vezérlési és láthatósági hiányosságok
Miután egy konténer fut egy stabil konfigurációval és aktuális rendszerképekkel, két típusú hiba marad. Mindkettő rejtett: az hozzáférés-ellenőrzési problémákat nem fogod észrevenni, amíg valaki ki nem használja, és a monitorozási hiányosságokat nem fogod felfedezni, amíg nem kell vizsgálnod olyan tevékenységeket, amelyeket soha nem naplóztak.
Ugyanaz Red Hat 2024 kutatás azt találták, hogy az alapító csapatok 42%-ánál hiányoztak a megfelelő képességek a konténer biztonságának és kapcsolódó fenyegetéseknek a kezeléséhez.
A monitorozási hiányosságok jellemzően csak akkor derülnek fel, amikor balesetek történnek és utánanézünk, nem előtte. Amikor végül fontossá válik a láthatóság, már csak reagálunk valamire, nem pedig megelőzzük azt.
Gyenge hitelesítés és elérhető kezelési felületek
Egy nyilvános IP-cím és jelszó nélküli konténerkezelő irányítópult nem igényel kifinomult támadót. Elég, ha ismeri a címet. Ez alacsonyabb küszöb, mint amit a legtöbb csapat sejteni gondol.

Az önálló üzemeltetésű monitorozási és kezelési eszközöket általában webes felülettel szállítják, amely az összes hálózati interfészen elérhető. Ha ezeket nyilvános IP-cím mögött hagyja hitelesítés nélkül, az olyan, mintha egy admin panelt zárva hagyná az un containerekben.
Az autentikáció, a fordított proxy és a privát hálózati elhelyezés az alapvető követelmények. A hozzáférés-vezérlés egy konfigurációs lépés, amelyet bármilyen kezelőfelülethez hozzáadhat - nem egy alapértelmezetten engedélyezett funkció.
Ugyanez az elv vonatkozik erre: Docker CLI és GUI kezelés; a daemon-hoz való admin szintű hozzáférés ugyanekkora kockázattal jár, függetlenül az interfésztől.
Nincs rálátás arra, mit csinálnak a tárolóid
Ha egy konténer biztonsága megsérül, a támadó tevékenysége nyomot hagy: a folyamat viselkedése megváltozik, szokatlan hálózati kapcsolatok jönnek létre, és váratlan fájlmódosítások történnek. Naplógyűjtés nélkül ez a nyom olyan formában nem létezik, amelyre intézkedni tudnál.
A központosított naplógyűjtés, a konténer auditálása és a futásidőbeli monitorozási eszközök megadják az adatokat az abnormális tevékenység észleléséhez, mielőtt súlyosbodnék. A cél nem minden sor elemzése. Az a cél, hogy az adatok rendelkezésre álljanak, amikor vizsgálatot kell végezni.
A termelésben csendesen futó konténerbeállítások, naplócsatorna és riasztások nélkül nem könnyű karbantarthatóak. Ezek nincsenek felügyelve. Ez két különböző üzemeltetési állapot.
Miért fontos az infrastruktúra környezete is
A konténer biztonsága a konfigurációval kezdődik, de a konfiguráció az infrastruktúrára épül. Egy rosszul konfigurált hálózattal, megosztott erőforrásokkal vagy hálózati szintű szűrés nélküli gazdagép olyan feltételeket teremt, amelyek hatással vannak minden felette lévő konténerre. A konténerbeállítás helyes konfigurálása és a kiszolgáló konfigurációja helyes beállítása két külön feladat.
Számos Docker biztonsági hézag olyan körülmények által erősödik meg, amelyeket a konténerek maguk örökölnek:
- Megosztott konténer kiszolgáló hardveres izoláció nélkül a bérlők között
- Gazdagép kernel javítatlan állapotban
- Gazdagép hálózati szintű szűrés nélkül
Ez nem szünteti meg az előbbiekben ismertetett konfigurációs lépések szükségességét, mivel a megfelelő konténerizálás hardening az infrastruktúra szintjétől függetlenül fontos. Az elkülönített infrastruktúrán való indulás egy aggodalmat kiiktat az egyenletből.
Az Cloudzy-nál két lehetőséget kínálunk a beállítások igénye szerint:
- Linux VPS: tiszta környezet az Docker saját telepítéséhez és a cikkben ismertetett hardening lépések alkalmazásához
- Portainer VPS: egyetlen kattintásos megoldás az Portainer előtelepítettségével; a kiszolgáló elindul, és már az irányítópulton vagy.
Mindkét lehetőség ugyanazon az infrastruktúrán fut: KVM virtualizáció, AMD Ryzen 9 CPUs akár 5,7 GHz turbó órajellel, DDR5 memória, NVMe SSD tár, akár 40 Gbps hálózat, és ingyenes DDoS védelem a BuyVM szűrésén keresztül, 12 globális helyszínen 99,95%-os uptime SLA-vel.
Az Portainer futtatásáról egy VPS-n részletesebben egy dedikált cikkben foglalkozunk.
Praktikus biztonsági ellenőrzőlista Docker telepítésekhez
A fenti Docker biztonsági hibák többnyire egyetlen konfigurációs döntésből származnak, amelyet egyszer hoztak, majd soha nem vizsgáltak felül. Az ellenőrzőlista futtatása egy meglévő beállítás ellen megtalálja ezeket a hiányosságokat. Ez auditként működik, nem telepítési útmutatóként.
Ezek a Docker biztonsági gyakorlatok azt mutatják, hogyan lehet a Docker konténereket a fentebb ismertetett leggyakoribb konfigurációs hibák ellen védelemmel ellátni.
Rövid útmutató: Mind a 9 hiba
| Hiba | Kategória | Egysoros javítás |
| Root felhasználóként futtatva | Konfiguráció | Hozzáadás USER direktíva a Docker fájlhoz |
| Portok kötve a 0.0.0.0-hoz | Konfiguráció | Csatornázás 127.0.0.1-hez és forgalomirányítás fordított proxyn keresztül |
| Nincs hálózati elkülönítés | Konfiguráció | Szolgáltatások szétválasztása különálló, felhasználó által definiált hálózatokra az hozzáférési igények alapján. |
| Docker foglalat csatlakoztatva | Konfiguráció | Távolítsd el a csatlakoztatást; használj hatókörlimitált API-okat vagy alternatívákat |
| Nem megbízható vagy elavult rendszerképek | Kép | Használjon hivatalos rendszerképeket rögzített verziójelölésekkel |
| Bedrótozott titkos adatok | Kép | Helyezze át a hitelesítési adatokat futtatásidejű környezeti változókba vagy titokkezelőbe |
| Nincs rendszerkép-újraépítési ütemezés | Kép | Állítson be havi újraépítési gyakoriságot, ahol lehetséges, automatizálja |
| Hitelesítetlen irányítópultok | Hozzáférés | Adjon hozzá hitelesítést, és helyezze át a felügyeleti felületeket magánhálózatokra |
| Nincs tárolónapló-gyűjtés | Hozzáférés | Állítson be központosított naplózást és futtatásidejű megfigyelést |
Javasoljuk, hogy először futtassa végig a meglévő beállításokon, mivel ott a legnagyobb az esélye, hogy a hiányosságok már jelen vannak.
Tárolók futtatása nem root felhasználóként: Keresse meg a USER direktívát a Dockerfile-okban. Ha nem létezik, a tároló root-ként fut.
Portbindingek localhost-ra vagy proxyn keresztül korlátozottak: Futtassa a docker ps parancsot, és tekintse át a portbindingeket. A 0.0.0.0:PORT bejegyzés nyilvánosan elérhető lehet olyan gazdagépeken, ahol nincs upstream biztonsági csoport, külső tűzfal vagy DOCKER-USER lánc szabály, amely blokkolná.
Egyéni bridge hálózatok használata: A Docker alapértelmezett bridge-jén lévő tárolók szabadon kommunikálhatnak egymással. Az azonos, felhasználó által definiált bridge-en lévő tárolók továbbra is kommunikálhatnak, így ossza fel a szolgáltatásokat megbízhatósági határ alapján külön hálózatokra a valós elkülönítéshez.
Docker szoftvercsatorna nem csatlakoztatva a tárolókban: Ellenőrizze a Compose fájlokat és futtatási argumentumokat. Ha a /var/run/docker.sock kötetként jelenik meg, erősítse meg, hogy szükséges és szándékos.
Rendszerképek ellenőrzött közzétevőktől rögzített verziókkal: A FROM ubuntu:latest nem specifikált, potenciálisan elavult verziót kér le. Rögzítsen egy konkrét kiadásra.
Nincsenek titkok a Dockerfile-okban, Compose fájlokban vagy összeállítási argumentumokban: A rendszerkép réteg előzménye megőrzi a hitelesítési adatokat a tároló törlése után. Használja a Compose titkokat, Swarm titkokat, összeállítási titkos csatlakoztatásokat vagy egy külső titokkezelőt. A futtatásidejű környezeti változók jobb választás, mint a hardcoded értékek, de még mindig megjelennek az inspect kimeneten és a naplókban.
Rendszerkép-újraépítési ütemezés megadva: A régi rendszerképek felhalmoznak biztonsági réseket. A havi újraépítési gyakoriság kezelhetőre csökkenti az expozíciós időt a legtöbb beállítás esetén.
Felügyeleti felületek hitelesítés mögött: Bármely nyilvános IP-n lévő irányítópult hitelesítés nélkül nyitott belépési pont. A magánhálózat-elhelyezés előnyösebb, ahol lehetséges.
Konténer naplók gyűjtése: Log feldolgozás nélkül az incidensmegállapítás a látható rendszerhatásoktól függ. Ez késői jelzés az intézkedéshez.
Következtetés
Az Docker alapértelmezett konfigurációja a kényelemre, nem a biztonságra készült. A cikkben tárgyalt hibák többsége olyan beállításokhoz vezethető vissza, amelyeket soha nem módosítottak az iniziális telepítés után, nem pedig szofisztikált támadásokhoz.
A javítások túlnyomórészt egyszeri konfigurációs döntések: egy USER direktíva, egy portbinding-módosítás, egy egyéni hálózat, egy újraépítési ütemezés. Ezek közül egyik sem igényel új eszközöket a legtöbb telepítéshez.
A konténer konfigurációjának helyesítése az első feladat. Az infrastruktúra, amelyen fut, a második. Mindkettő számít, és egyik sem helyettesítheti a másikat.