丁 攀 張小梅 郭新海 劉 安
中國聯(lián)通研究院 北京 100048
云計算是一種基于互聯(lián)網(wǎng)的計算方式,通過這種方式,共享的軟硬件資源和信息可以按需提供給計算機和其他設備。NIST指出云計算由一個可配置的共享資源池組成,該資源池提供網(wǎng)絡、服務器、存儲、應用和服務等多種硬件和軟件資源,資源池具備自我管理能力,用戶只需少量參與,就可以方便快捷地按需獲取資源[1]。經(jīng)過十幾年的發(fā)展,云計算作為數(shù)字化轉型的重要基礎設施,已經(jīng)由“面向云遷移應用”的階段演進到“面向云構建應用”的階段,即由“以資源為中心”演進到“以應用為中心”的云原生基礎設施階段,云原生的代表技術包括容器、服務網(wǎng)格、微服務、不可變基礎設施和聲明式API[2]。
在云原生應用和服務平臺構建過程中,Docker技術憑借其輕量、秒級部署、易于移植、彈性伸縮和活躍強大的社區(qū)支持,成為了云原生等應用場景下的重要支撐技術。Docker是以Docker容器為資源分隔和調度的基本單位,封裝整個軟件運行時環(huán)境,用于構建、發(fā)布和運行分布式應用的平臺。Docker可以在容器內(nèi)部快速自動化地部署應用,并通過操作系統(tǒng)內(nèi)核技術為容器提供資源隔離與安全保障。
2.1.1 容器功能及其架構
與虛擬機相比,Docker平臺將資源的抽象從硬件級別上移到了操作系統(tǒng)級別,虛擬機抽象整個硬件服務器,而容器抽象操作系統(tǒng)的內(nèi)核。這是一種完全不同的虛擬化方法,虛擬機和容器對比如圖1所示。
圖1 Docker和傳統(tǒng)虛擬化方式對比
Docker體系結構使用客戶端—服務器模型,并且由Docker客戶端、Docker主機、網(wǎng)絡和存儲組件以及Docker Registry/Hub組成,Docker架構如圖2所示[3]。
圖2 Docker架構圖
Docker客戶端實現(xiàn)與Docker Daemon進行交互,它們可以部署在同一臺主機上,也可以獨立部署。Docker主機提供了執(zhí)行和運行應用程序的完整環(huán)境,它由Docker Daemon、鏡像、容器、網(wǎng)絡和存儲組成。
Docker主要的操作對象包括鏡像、容器、網(wǎng)絡和存儲,鏡像用于存儲和運送應用程序,可以單獨使用鏡像來構建容器,也可以對其進行自定義以添加其他元素來擴展當前配置。Docker以應用程序驅動的方式實現(xiàn)網(wǎng)絡功能,在Docker網(wǎng)絡中,host網(wǎng)絡實現(xiàn)共享主機的網(wǎng)絡棧功能,bridge網(wǎng)絡實現(xiàn)創(chuàng)建網(wǎng)關和IP子網(wǎng)功能。Docker可以將數(shù)據(jù)存儲在storage driver管理的容器層中,也可以存儲在容器上掛載的文件系統(tǒng)中。
2.1.2 實現(xiàn)容器的核心技術
Docker容器本質上是宿主機上的進程,Docker通過cgroups實現(xiàn)了資源限制,通過Namespace實現(xiàn)資源隔離,通過寫時復制(copy-on-write)實現(xiàn)高效的文件操作[4]。
Linux操作系統(tǒng)通過cgroups可以設置進程使用CPU、內(nèi)存和磁盤IO資源的限額,通過優(yōu)先級讓一些組優(yōu)先得到更多的CPU等資源。Namespace管理主機中全局唯一的資源,實現(xiàn)資源間的隔離,進程在彼此隔離的Namespace運行時不可見,并且認為自己是獨占系統(tǒng)的。Docker鏡像采用寫時復制策略,實現(xiàn)多個容器之間共享鏡像,每個容器在啟動的時候不需要單獨復制一份鏡像,只需要將所有鏡像層以只讀方式掛載,只有在系統(tǒng)文件發(fā)生變化時,才會把變化的內(nèi)容記錄在可讀寫層,以此減少磁盤空間占用和容器啟動時間。
無論是硬件的虛擬化還是操作系統(tǒng)的虛擬化,兩者都需要寄生于主機操作系統(tǒng)上,所以操作系統(tǒng)的安全是虛擬化安全的前提條件。雖然容器提供了功能強大的軟件級別的隔離機制,但使用共享內(nèi)核無疑會導致相對于虛擬機管理器甚至容器專用操作系統(tǒng)而言更大的攻擊面。Docker在主機操作系統(tǒng)面臨的風險包括主機操作系統(tǒng)漏洞風險、共享內(nèi)核安全風險、用戶訪問權限不當風險、Docker版本及安裝環(huán)境風險、篡改主機操作系統(tǒng)文件風險等[5]。
Docker Daemon是容器服務的核心,為了理清Docker Daemon存在哪些方面的安全風險,我們從Docker Daemon的工作流程圖來詳細分析[6],如圖3所示。
圖3 Docker Daemon的工作流程圖
用戶是使用Docker Client與Docker Daemon建立通信,Docker Daemon首先提供HTTP Server的功能,使其可以接受Docker Client的請求。Engine執(zhí)行Docker內(nèi)部的一系列工作,每一項工作都是以一個Job的形式存在。Job通過鏡像管理驅動graphdriver將下載鏡像、通過網(wǎng)絡管理驅動networkdriver創(chuàng)建并配置Docker容器網(wǎng)絡環(huán)境、通過execdriver來完成限制Docker容器運行資源或執(zhí)行用戶指令。libcontainer是一項獨立的容器管理包,networkdriver以及execdriver都是通過libcontainer來實現(xiàn)具體對容器進行的操作。
Docker Daemon負責所有與容器相關的操作,Docker Daemon方面的安全風險包括客戶端配置、容器網(wǎng)絡配置、容器鏡像配置、容器存儲配置等方面。一方面我們需要關注攻擊面暴露的重要參數(shù)的配置,另一方面還需要關注配置這些敏感參數(shù)的系統(tǒng)文件。
鏡像是容器運行的基礎,容器引擎服務通過使用不同的鏡像來啟動容器。鏡像是按層封裝好的文件系統(tǒng)和描述鏡像的元數(shù)據(jù)構成的文件系統(tǒng)包,包含應用所需要的系統(tǒng)、環(huán)境、配置和應用本身。分層存儲是容器鏡像的主要特點之一,每個鏡像都是由一系列的“鏡像層”組成。當需要修改鏡像內(nèi)的某個文件時,只會對最上方的讀寫層進行改動,不會覆蓋下層已有文件系統(tǒng)的內(nèi)容。當提交這個修改生成新的鏡像時,保存的內(nèi)容僅為最上層可讀寫文件系統(tǒng)中被更新過的文件,這樣就實現(xiàn)了在不同的容器鏡像間共享鏡像層的效果。
基于Dockerfile創(chuàng)建鏡像是最常見的鏡像的構建方式,比如現(xiàn)在構建一個新的鏡像,Dockerfile文件內(nèi)容為:
FROM debian #①
RUN apt-get install emacs#②
RUN apt-get install apache2#③
CMD [“/bin/bash”]#④
上述指令的信息為:①基于debian base構建鏡像,②安裝emacs編輯器,③安裝apache2,④容器啟動時運行bash。圖4展示的是使用Dockerfile文件構建的鏡像,最上層是有讀寫屬性的容器層,剩余的是有只讀屬性的鏡像層。倉庫是集中存放鏡像文件的場所,倉庫分為公開倉庫和私有倉庫,目前,全世界最大的倉庫是Docker官方的 Docker Hub。
圖4 容器的鏡像結構
通過上述容器構建及存儲的過程,我們在使用鏡像的過程中所面臨的風險包括基礎鏡像的安全風險、鏡像安全配置風險、Dockerfile文件使用風險和鏡像倉庫使用風險等。
第2.3節(jié)討論的容器守護進程存在的安全風險,是基于運行在主機上的所有容器進行考慮的,是服務系統(tǒng)級別的安全實踐。本節(jié)所討論的容器運行時的安全風險,是針對具體運行的容器存在的安全風險,是容器實例維度級別的安全實踐。在守護進程中進行配置后,也可以根據(jù)具體的容器定制化的配置需求,在容器啟動時配置對應參數(shù),覆蓋容器服務的默認配置。
容器是以進程的形式運行在主機上的,運行的容器進程是隔離的,彼此之間有獨立的文件系統(tǒng)、網(wǎng)絡以及主機進程樹。使用docker run指令來定義容器運行時的資源,我們需要合理地配置docker run的參數(shù)來保障運行時的容器安全。
詳細的docker run參數(shù)可以參考Docker Commandline Reference[7],其中安全相關的參數(shù)配置大致可以分為四大類,如表1所示。
表1 docker run安全相關配置參數(shù)
因為容器使用及注銷便捷,導致鏡像和容器的泛濫?;诎踩珜嵺`的建議包括:不要在同一主機上使用太多的鏡像、不要在主機上運行過多的容器、通過標簽的方式區(qū)分舊的可能存在漏洞的鏡像。
關于Docker的安全配置核查或者最佳實踐,具有較大影響力的是CIS Docker Benchmark[8],它基于各行業(yè)、各職位專家所達成的共識。但是,CIS的每個測試條目是相互獨立的,內(nèi)在的關聯(lián)性也不明確。所以,我們希望根據(jù)容器所存在的安全風險,梳理歸并相關的安全配置方案,使得Docker的安全配置方案便于科研人員理解。
通過梳理,主機、Docker Daemon、容器鏡像、運行時的容器、容器操作的安全配置方案分別如表2、表3、表4、表5、表6所示。
表2 主機安全配置方案
表3 Docker Daemon安全配置方案
表4 容器鏡像安全配置方案
表5 運行時容器的安全配置方案
表6 容器操作安全配置方案
容器安全的防護應該覆蓋到容器的整個生命周期,包括容器的構建、分發(fā)和運行三個階段。容器安全基線配置涉及到容器生命周期的各個階段,對于容器安全起到至關重要的作用。應對Docker容器生命周期里的安全問題,需要可操作、可執(zhí)行的Docker安全基線檢查清單,這個清單除了需要清晰、可查、可維護,以供在生產(chǎn)環(huán)境中執(zhí)行基礎架構的安全檢查和審計之外,還需要系統(tǒng)可理解。本文在梳理容器面臨的安全風險的基礎之上,總結歸納了CIS Docker Benchmark五個大類二十個小類單機版容器的安全配置需求,使得Docker的安全配置方案更具條理性,更便于容器安全研究人員系統(tǒng)的理解容器安全配置。