A Dockert akár hónapokig is futtathatja éles állapotban látható probléma nélkül. A konténerek elindulnak, az alkalmazások válaszolnak, semmi sem törik el. Ezután egy szabad port vagy egy rosszul konfigurált engedély olyan támaszt jelent, amelyet a támadónak nem kellett megszereznie. A legtöbb Docker biztonsági hiba addig nem tűnik hibának, amíg valami elromlik.
Ez a cikk bemutatja azokat a konkrét konfigurációkat, amelyek veszélybe sodorják a konténerkörnyezeteket, és azt, hogy mindegyik mit tesz lehetővé a támadó számára, és egy ellenőrzőlistával zárul, amelyet még ma futtathat a saját beállításával szemben.
Miért nehezebb a Docker Security, mint amilyennek látszik?
A konténerek elszigeteltnek érzik magukat. Ha elindít egyet, az lefuttatja a saját folyamatterét, és a belsejéből a következő tároló nem létezik. Elszigetelődik, de ez csak részleges. A tárolók megosztják a gazdagép kernelt, ami azt jelenti, hogy a tárolón belüli folyamat bizonyos feltételek mellett teljes egészében elérheti a gazdagép rendszert.
A dokkolóhajók a fejlesztők kényelmét szolgálják, nem pedig a gyártási keményítést. Root hozzáférés bekapcsolva. Minden port minden interfészhez köthető. Nincs futásidejű megfigyelés. A legtöbb fejlesztő elfogadja ezeket a beállításokat, szállítja a tárolót, és továbblép. Ez egy ésszerű megközelítés az induláshoz; ez nem egy kész biztonsági testtartás.
Szerint A Red Hat 2024-es Kubernetes biztonsági állapotjelentése, a szervezetek 67%-a késleltette vagy lelassította az alkalmazások telepítését konténer vagy Kubernetes biztonsági aggályok miatt. Ez a súrlódás általában nem támadásokból származik. Olyan csapatoktól származik, akik felfedezték, hogy a konténerbeállításaikat meg kell erősíteni, amit nem építettek be.
Gyakran látjuk, hogy a konténerek éles környezetben futnak ugyanazzal a konfigurációval, mint a fejlesztő helyi gépén. Itt a Docker biztonsági hibái általában csendesen, látható tünetek nélkül bonyolódnak, amíg valami nem auditálódik vagy meghibásodik.
Az ezeket a hiányosságokat okozó hibák specifikusak, megjósolhatók és többnyire elkerülhetők, a konfiguráció szintjétől kezdve.
Gyakori Docker konfigurációs hibák
A legtöbb konténer megsértése nem nulladik napi kizsákmányolással kezdődik. Az első napon beállított konfigurációval kezdik, anélkül, hogy sokat gondolkodnának a hálózatról vagy a jogosultságokról.
Az alapértelmezett Docker-beállítások működnek. A funkcionális és a biztonságos közötti szakadék az a hely, ahol a Docker-tároló biztonsági kockázatai felhalmozódnak, különösen a saját üzemeltetésű beállításoknál, amelyeket telepítenek, és soha nem keresnek fel újra.
Gyakran látjuk ezt a mintát: a nyilvános IP-kiszolgálókon lévő tárolók port-összerendelésekkel, felhasználói beállításokkal és hálózati konfigurációkkal pontosan olyanok, mint a kezdeti üzembe helyezéskor.
Tárolók futtatása gyökérként
Ha egy Docker-tárolót felhasználó megadása nélkül indít el, az rootként fut. Ez azt jelenti, hogy a tárolón belüli bármely folyamat, beleértve az alkalmazást is, gyökér szintű jogosultságokkal rendelkezik a tároló névterében.

A tárolón belüli gyökér nem ugyanaz, mint a gazdagépen lévő gyökér, de az elválasztás nem abszolút. A futtatókörnyezetet célzó jogosultság-eszkalációs kihasználások, például a jól dokumentált CVE-2019-5736 runc és a hasonló futásidejű hibák, gyakran gyökértároló-folyamatot igényelnek a sikerhez.
A nem gyökértárolók megszüntetik a gyökérfolyamat követelményét, amelytől ezek a kizsákmányolások függnek, jelentősen leszűkítve a támadási felületet az adott sérülékenységi osztály számára, bár nem szüntetik meg teljes mértékben a konténerek elkerülésének kockázatát.
Ha USER direktívát ad hozzá a Dockerfile-hoz, ez megoldja ezt. Egyes hivatalos képeket egy privilegizált felhasználóval szállítják, amelyet USER direktívával aktiválhat, de sok továbbra is alapértelmezés szerint root, és nincs kész alkalmazásfelhasználó. Ilyen esetekben a felhasználót a Dockerfile-ban hozza létre, mielőtt átváltana rá. A legtöbb saját üzemeltetésű beállításnál ez az egyetlen módosítás eltávolítja az eszkaláció kockázatának egy egész kategóriáját.
Túl sok port kitétele a nyilvános internet számára
Amikor közzétesz egy portot a Dockerrel, a Docker közvetlenül írja meg saját iptables-szabályait. Ezek a szabályok a gazdagép szintű tűzfalszabályok előtt futnak. Ez a a közösség által beszámolt jól ismert viselkedés és dokumentálva a Docker csomagszűrési útmutatójában, nem hibás konfiguráció, és ez azt jelenti, hogy az UFW és a hasonló eszközök nem blokkolják azt, amit a Docker már megnyitott.

A Docker közvetlenül az iptables-ba ír, megkerülve az UFW és a tűzfal alapértelmezett beállításait számos Linux-gazdagépen. Ez azt jelenti, hogy a 0.0.0.0-hoz kötött port nyilvánosan elérhető akkor is, ha a tűzfal konfiguráltnak tűnik. A felhőalapú biztonsági csoportok és a DOCKER-USER láncszabályok továbbra is blokkolhatják ezt a forgalmat, így a tényleges kitettség az adott hálózati beállítástól függ.
Ha lehetséges, kapcsolja össze a szolgáltatásokat a 127.0.0.1-gyel, irányítsa a nyilvános forgalmat fordított proxyn keresztül, és csak azt tegye közzé, ami valóban külső hozzáférést igényel. A fordított proxy a legmegbízhatóbb módja annak, hogy a gazdagépen kívülről mi jelenjen meg.
A konténerek közötti hálózati leválasztás figyelmen kívül hagyása
A hálózat bármely tárolója korlátozás nélkül elérheti a rajta lévő többi tárolót. Az alapértelmezett híd nem alkalmaz forgalomszűrést az azt megosztó tárolók között, és a legtöbb beállítás soha nem módosítja ezt a konfigurációt.

Ha egy konténer veszélybe kerül, ez a nyitott kommunikáció oldalirányú mozgási útvonalgá válik. A frontend tároló elérheti az adatbázist, egy belső API-t vagy bármi mást ugyanazon az alapértelmezett hídhálózaton, még akkor is, ha ez a hozzáférés nem volt szándékos.
A felhasználó által definiált hálózatok kifejezetten szabályozzák, hogy mely tárolók kommunikálhatnak, de az összes szolgáltatás által megosztott egyetlen egyéni hálózat továbbra is lehetővé teszi a szabad konténerek közötti forgalmat. A valódi elszigeteltség megköveteli, hogy a szolgáltatásokat külön hálózatokon helyezzék el, amelyeknek nem szabad beszélniük egymással. Az alapértelmezett híd kikapcsolása a kiindulópont, nem a célvonal.
Kilátással a Docker Socketre
A /var/run/docker.sock címen található Docker-foglalat a teljes Docker-motor vezérlőfelülete. Ha egy tárolóba csatlakoztatja, a tároló közvetlen API-hozzáférést biztosít a gazdagépen futó démonhoz.

Ezzel a hozzáféréssel a tároló új tárolókat indíthat, gazdagép könyvtárakat csatlakoztathat, ellenőrizheti és módosíthatja a futó tárolókat, és hatékonyan vezérelheti a gazdagépet. A támadási felület egyenértékű a gazdagépen található root értékkel, ezért minden olyan eszköz, amelyhez socket-hozzáférésre van szükség, alapos értékelést érdemel.
A legtöbb felhasználási esetre vannak biztonságosabb alternatívák: hatályos API-k vagy Docker menedzsment eszközök amelyekhez nincs szükség aljzathoz való hozzáférésre. A Docker-in-Docker saját biztonsági és működési kompromisszumokkal rendelkezik, és nem egyszerűen helyettesíthető.
A konfigurációs hibák létrehozzák a kezdeti expozíciót. A kép- és függőségi választások határozzák meg, hogy az expozíció hogyan alakul az idő múlásával.
Kép és titkok hibák, amelyek túlmutatnak a konténeren
Amikor leállít egy tárolót, a benne lévő konfigurációs hibák leállnak vele. Ha egy biztonsági rést vagy merevkódolt hitelesítő adatot tartalmazó lemezképből épít újra, a probléma a tárolóval újraindul. A képszintű hibák nem állnak vissza a telepítések között.
A képpel minden olyan környezetbe utaznak, amely lekéri, minden rendszerleíró adatbázisba, amely tárolja, és minden csapattagba, aki futtatja. Ez a kitartás a kép- és titokkezelést külön kockázati kategóriává teszi, amelyet érdemes a konfigurációtól elkülönítve ellenőrizni.
Gyakran látjuk ezt a mintát: egy kép, amelyet gondosan választottak ki a projekt kezdetekor, és azóta sem építették újra, lassan elsodródva az eredeti biztonsági alapvonaltól.
Nem megbízható vagy elavult képek használata
A nyilvános nyilvántartások bárki számára nyitva állnak. Rosszindulatú képeket terjesztettek a Docker Hubon keresztül, amelyek titkosítási bányászokat és rétegelőzményekbe ágyazott hátsó ajtókat tartalmaznak, amelyek a konténerek újraindításakor is megmaradnak. Ellenőrzés az ügy levonása előtt, különösen a nem hivatalos vagy ismeretlen kiadók képei esetében.

A külön probléma az állottság. Egy hivatalos kép, amelyet hat hónappal ezelőtt készítettél, és azóta soha nem építettél újjá, felhalmozódott a kijavított Docker sebezhetősége, és minden egyes CVE-t felfedtek a csomagjai ellen. A kép nem törött. Egyszerűen már nem aktuális.
A Sonatype 2024-es, a szoftverellátási lánc állapotáról szóló jelentése azt találta, hogy az esetek 95%-ában egy sérülékeny összetevőt használnak fel, már elérhető egy fix verzió, és az alkalmazásfüggőségek 80%-a több mint egy évig frissítés nélkül marad. Ez a minta a Docker alapképekre is vonatkozik, mivel ugyanazokra a nyílt forráskódú csomagokra támaszkodnak.
Használja az ellenőrzött kiadók hivatalos képeit, és rögzítsen konkrét verziócímkéket, ahelyett, hogy a „legújabb”-ra hagyatkozna. Építsen fel rendszeres újjáépítési ütemet, hogy képei naprakészek legyenek.
Hardcoding titkok a Docker- és Compose Files-ban
A Dockerfile ENV- vagy ARG-utasításba írt, a Compose-környezeti blokkba keménykódolt, összeállítási argumentumokként átadott vagy a verzióvezérlésnek alárendelt .env-fájlban tárolt hitelesítő adatok nem tűnnek el, amikor leállítja a tárolót. A képréteg előzményeiben vagy a forrásvezérlésben maradnak, és bárki számára elérhetők, aki bármelyiket eléri.

Ez az egyik leginkább figyelmen kívül hagyott Docker biztonsági hiba, mert nem okoz látható problémákat a fejlesztés során. Az API-kulcs az ENV-utasításban megfelelően működik. A tárhelyedben is megtalálható, a képedbe süllyesztve, és terjesztve, bárhová is kerül a kép.
A modern Docker Compose támogatja a natív titkosítási mechanizmust, amely futás közben rögzíti a hitelesítési adatokat anélkül, hogy a képbe beépítené azokat. A Docker's Secrets API és a külső titokkezelők ugyanazt az elvet követik. Ezek azok a lehetőségek, amelyek a hitelesítési adatokat teljes mértékben távol tartják az építési műtermékektől és a véglegesített fájloktól.
A futásidejű környezeti változók javulást jelentenek a merevkódolt hitelesítő adatokhoz képest, de továbbra is elérhetők a Docker vizsgálati kimenetén, naplóin és összeomlási kiíratásain keresztül. Egy lépést jelentenek a besütött titkokhoz képest, nem pedig kész megoldást.
Nem frissítik rendszeresen a tárolóképeket
Gyakori szokás, hogy hónapokig ugyanazt a képet futtassuk. Minden nap, amely eltelik egy új sérülékenység nyilvánosságra hozatala után, de az újraépítés előtt a tárolók tartalmaznak egy expozíciós ablakot, amely látható változás nélkül növekszik.
Állítson össze következetes újraépítési ütemtervet. Lehetőség szerint automatizálja ezt a folyamatot, és rendszeresen futtasson egy sebezhetőségi szkennert az aktuális képei ellen. A cél nem a tökéletesség. Leszűkíti a javítás kiadása és telepítése közötti időt.
A hozzáférés-szabályozás és a felügyelet a gyors üzembe helyezés során prioritás nélkülivé válhat. Ezek azok a kategóriák is, ahol az incidenseket a legtovább észlelik.
Beléptető és láthatósági rések
Miután egy tároló szilárd konfigurációval és jelenlegi képfájlokkal fut, két hibakategória marad fenn. Mindkettő természeténél fogva láthatatlan: nem fog észrevenni egy gyenge hozzáférés-szabályozási problémát, amíg valaki nem használja, és nem vesz észre felügyeleti rést, amíg nem kell kivizsgálnia a soha nem naplózott tevékenységet.
Ugyanaz Red Hat 2024 kutatás azt találta, hogy a csapatok 42%-a nem rendelkezik elegendő képességgel a konténerbiztonság és a kapcsolódó fenyegetések kezelésére.
Azt tapasztaljuk, hogy a megfigyelési hiányosságok jellemzően az incidensek kivizsgálása során jelentkeznek, korábban nem. Mire a láthatóság prioritássá válik, gyakran reagál valamire, nem pedig megakadályozza azt.
Gyenge hitelesítés és nyílt kezelési irányítópultok
A hitelesítés nélküli nyilvános IP-címen lévő tárolókezelési irányítópulthoz nincs szükség kifinomult támadóra. Ehhez tudniuk kell a címet. Ez alacsonyabb léc, mint a legtöbb csapat gondolná.

A saját üzemeltetésű felügyeleti és felügyeleti eszközöket általában minden hálózati interfészen elérhető webes felülettel együtt szállítják. A nyilvános IP-címen lévőket hitelesítés nélkül hagyni előttük, az egyenértékű az adminisztrációs panel zárolatlan hagyásával.
A hitelesítés, a fordított proxy és a magánhálózati elhelyezés az alap. A hozzáférés-vezérlés egy konfigurációs lépés, amelyet bármely felügyeleti felülethez hozzá kell adni, nem pedig olyasvalami, amelyet engedélyezve szállítanak.
Ugyanez az elv vonatkozik rá Docker CLI és GUI kezelés; a démonhoz való adminisztrátori szintű hozzáférés ugyanazt a kockázatot hordozza, függetlenül a felülettől.
Nem figyeli a konténerek tevékenységét
Ha egy tárolót feltörnek, a támadó tevékenysége nyomokat hoz létre: folyamat viselkedésének változásai, szokatlan hálózati kapcsolatok és váratlan fájlmódosítások. Ha nincs naplógyűjtemény, ez a nyomvonal nem létezik olyan formában, amelyen cselekedhet.
A központosított naplógyűjtés, a konténer-naplózás és a futásidejű megfigyelő eszközök olyan adatokat biztosítanak, amelyek segítségével észlelheti a rendellenes tevékenységet, még mielőtt az összetett. A cél nem minden sor elemzése. Rendelkezésre állnak az adatok, amikor ki kell vizsgálnia.
Azok a konténerbeállítások, amelyek csendesen futnak a termelésben, naplózási folyamat és riasztások nélkül, nem igényelnek kevés karbantartást. Ellenőrizetlenek. Ez két különböző működési állapot.
Miért számít az infrastrukturális környezet is?
A tárolóbiztonság a konfigurációval kezdődik, de a konfiguráció az infrastruktúra tetején fut. A rosszul konfigurált hálózattal, megosztott erőforrásokkal vagy hálózati szintű szűréssel nem rendelkező gazdagép olyan feltételeket hoz létre, amelyek minden felette lévő tárolót érintenek. A tároló beállításának és a kiszolgáló konfigurációjának helyes beállítása két külön feladat.
Sok Docker biztonsági rést felerősítenek azok a feltételek, amelyeket maguk a konténerek örökölnek:
- Megosztott bérbeadású kiszolgáló a bérlők közötti hardveres elkülönítés nélkül
- Javítás nélkül futó gazdagép kernel
- Beépített hálózati szintű szűrés nélküli gazdagép
Ez nem szünteti meg a fenti konfigurációs lépések szükségességét, mivel a megfelelő tárolóedzettség az infrastruktúra rétegtől függetlenül számít. Az elszigetelt infrastruktúráról való indulás eltávolítja az egyenletből az aggodalom egy rétegét.
A Cloudzy két utat kínál attól függően, hogy mit igényel a beállítás:
- Linux VPS: tiszta környezet a Docker saját maga üzembe helyezéséhez és az ebben a cikkben ismertetett keményítési lépések végrehajtásához
- Portaine VPS: egy kattintásos lehetőség előre telepített Portainerrel; a szerver elindul, és máris az irányítópulton van
Mindkét lehetőség ugyanazon az infrastruktúrán fut: KVM virtualizáció, AMD Ryzen 9 CPU-k akár 5,7 GHz-es boost órajellel, DDR5 memória, NVMe SSD tárhely, akár 40 Gbps hálózat és ingyenes DDoS védelem BuyVM-szűréssel, 12 globális helyen, 99,95%-os rendelkezésre állási SLA-val.
A Portainer VPS-en való futtatásának alaposabb megismeréséhez egy külön cikkben foglalkozunk vele.
Gyakorlati biztonsági ellenőrzőlista a Docker-telepítésekhez
A fenti Docker biztonsági hibák többnyire egyszeri konfigurációs döntésekből származnak, amelyeket soha nem vizsgáltak meg. Ha ezt az ellenőrzőlistát egy meglévő beállítással futtatja, akkor ezek a hiányosságok megszűnnek. Auditként működik, nem pedig telepítési útmutatóként.
Ezek a Docker biztonsági bevált gyakorlatok lefedik a Docker-tárolók védelmét a fent leírt leggyakoribb konfigurációs hibák ellen.
Gyorsreferencia: Mind a 9 hiba
| Hiba | Kategória | Egysoros javítás |
| Rootként fut | Konfiguráció | Hozzáadás FELHASZNÁLÓ utasítást a Dockerfile-hoz |
| A portok 0.0.0.0-hoz vannak kötve | Konfiguráció | Csatlakozzon a 127.0.0.1-hez, és irányítson egy fordított proxyn keresztül |
| Nincs hálózati szigetelés | Konfiguráció | A szolgáltatások felosztása különálló, felhasználó által meghatározott hálózatokra a hozzáférési igények alapján. |
| Docker aljzatra szerelve | Konfiguráció | Távolítsa el a tartót; hatókörű API-kat vagy alternatívákat használjon |
| Nem megbízható vagy elavult képek | Kép | Használjon hivatalos képeket rögzített verziócímkékkel |
| Kemény titkok | Kép | Helyezze át a hitelesítési adatokat a futásidejű env vars-ba vagy egy titokkezelőbe |
| Nincs kép-újraépítési ütemterv | Kép | Állítsa be a havi újraépítési ütemet; lehetőség szerint automatizálni |
| Hitelesítetlen műszerfalak | Hozzáférés | Adjon hozzá hitelesítést és helyezzen át felügyeleti felhasználói felületeket a magánhálózatokra |
| Nincs konténernaplógyűjtés | Hozzáférés | Központosított naplózás és futásidejű figyelés beállítása |
Javasoljuk, hogy először futtassa le a meglévő beállításokkal, mivel valószínűleg ott vannak már a hiányosságok.
Nem rootként futó tárolók: Ellenőrizze a Docker-fájlokat, hogy keres-e USER utasítást. Ha nem létezik, a tároló rootként fut.
Portkötések helyi gépre vagy proxyra korlátozva: Futtassa a docker ps-t, és tekintse át a portkötéseket. A 0.0.0.0:PORT bejegyzés nyilvánosan elérhető lehet azokon a gazdagépeken, ahol nem blokkolja a felsőbb szintű biztonsági csoport, külső tűzfal vagy DOCKER-USER láncszabály.
Egyedi hídhálózatok használatban: A Docker alapértelmezett hídján lévő konténerek szabadon elérhetik egymást. Az ugyanazon a felhasználó által definiált hídon lévő tárolók továbbra is kommunikálhatnak egymással, ezért a tényleges elkülönítés érdekében a szolgáltatásokat bizalmi határok alapján ossza fel külön hálózatok között.
Docker aljzat nem konténerbe szerelve: Jelölje be a Fájlok létrehozása és az argumentumok futtatása. Ha a /var/run/docker.sock kötetként jelenik meg, erősítse meg, hogy szükséges és szándékos.
Ellenőrzött megjelenítőktől származó alapképek rögzített verziókkal: A FROM ubuntu:latest egy meghatározatlan, potenciálisan elavult verziót vesz elő. Rögzítés egy adott kiadáshoz.
Nincsenek titkok a Dockerfiles-ben, a fájlok létrehozásában vagy az argumentumépítésben: A képréteg előzményei a tároló törlése után is megőrzik a hitelesítő adatokat. Használja a Titkok írása, a Swarm Secrets funkciót, a titkos rögzítők létrehozását vagy a külső titokkezelőt. A futásidejű környezeti változók jobbak, mint a keménykódolt értékek, de továbbra is megjelennek az ellenőrzési kimenetben és a naplókban.
Kép-újraépítési ütemterv meghatározva: A régi képek sebezhetőséget halmoznak fel. A havi újraépítési ütem a legtöbb beállításnál kezelhetővé teszi az expozíciós ablakot.
A hitelesítés mögötti kezelőfelületek: A nyilvános IP-címen hitelesítés nélküli bármely irányítópult nyitott belépési pont. Lehetőség szerint előnyösebb a magánhálózati elhelyezés.
Gyűjtött konténernaplók: Naplócső nélkül az incidensek észlelése a látható rendszerhatástól függ. Ez egy késői jelzés a cselekvésre.
Következtetés
A Docker alapértelmezett konfigurációja a kényelem, nem pedig a biztonság érdekében készült. A cikkben tárgyalt hibák többsége olyan beállításokra vezethető vissza, amelyeket a kezdeti üzembe helyezés után soha nem módosítottak, nem pedig kifinomult támadásokra.
A javítások többnyire egyszeri konfigurációs döntések: USER direktíva, portkötés módosítása, egyéni hálózat, újraépítési ütemezés. Egyikük sem igényel új szerszámot a legtöbb beállításhoz.
Az első feladat a tárolókonfiguráció megfelelő beállítása. Az infrastruktúra, amelyen fut, a második. Mindkettő számít, és egyik sem helyettesíti a másikat.