陳 偉,涂俊亮
(中國(guó)電子科技集團(tuán)公司第三十研究所,四川 成都 610041)
云計(jì)算作為最近幾年計(jì)算機(jī)與互聯(lián)網(wǎng)界的焦點(diǎn),得到了眾多企業(yè)和科研機(jī)構(gòu)的青睞。虛擬化技術(shù)作為云計(jì)算的關(guān)鍵技術(shù)[1],隨著云計(jì)算的使用也得到了迅速發(fā)展。虛擬化,是指通過(guò)虛擬化技術(shù)將一臺(tái)計(jì)算機(jī)虛擬為多臺(tái)邏輯計(jì)算機(jī)[2]。虛擬化既可以通過(guò)硬件模擬來(lái)實(shí)現(xiàn),也可以通過(guò)操作系統(tǒng)來(lái)實(shí)現(xiàn)。目前主流的虛擬化技術(shù)如XEN、VMware 以及KVM 都是基于虛擬機(jī)的平臺(tái)虛擬化技術(shù)[3]。這些方案通常因?yàn)樘摂M機(jī)鏡像普遍較大、需要自己獨(dú)立的完整的操作系統(tǒng)(GuestOS)、占用的硬件資源多等特點(diǎn),對(duì)于大規(guī)模的集群部署適應(yīng)性較差。
Docker 是基于Go 語(yǔ)言實(shí)現(xiàn)的云開(kāi)源項(xiàng)目,誕生于2013 年初[4]。作為一種輕量級(jí)的虛擬化技術(shù),Docker 在運(yùn)行應(yīng)用上和傳統(tǒng)的虛擬機(jī)方式相比有顯著的優(yōu)勢(shì)[5]:①Docker 容器運(yùn)行很快,啟動(dòng)和停止可以在秒級(jí)實(shí)現(xiàn),相比傳統(tǒng)的虛擬機(jī)方式要快很多。②Docker 容器對(duì)系統(tǒng)的資源需求很少,一臺(tái)宿主機(jī)可以運(yùn)行多達(dá)數(shù)千個(gè)的容器,這在傳統(tǒng)虛擬機(jī)是不可想象的。③Docker 通過(guò)Dockerfile 配置文件來(lái)支持靈活的自動(dòng)化創(chuàng)建和部署機(jī)制,提高效率[6]。
隨著Docker 容器技術(shù)的大量使用,如何確保Docker 容器的安全被看做Docker 容器使用的關(guān)鍵。
Docker 是Linux 操作系統(tǒng)層面的虛擬化實(shí)現(xiàn),其本質(zhì)和運(yùn)行在Linux 上的進(jìn)程沒(méi)有區(qū)別。目前Docker 容器的安全性其本質(zhì)上依賴于Linux 系統(tǒng)本身[7]。Docker 的安全主要通過(guò)以下幾個(gè)方面實(shí)現(xiàn):①Linux內(nèi)核的命名空間機(jī)制提供的容器隔離安全。通過(guò)命名空間機(jī)制,可以使運(yùn)行在同一臺(tái)宿主機(jī)上的Docker 容器中的程序不會(huì)受到相互之間的影響,且有自己獨(dú)有的網(wǎng)絡(luò)棧不會(huì)被其他容器訪問(wèn)。②Linux 控制組機(jī)制對(duì)容器資源的控制能力安全。Linux 控制組機(jī)制可以確保同一臺(tái)宿主機(jī)上的容器公平地分配宿主機(jī)的CPU、磁盤和內(nèi)存等資源,控制組機(jī)制也會(huì)保證容器發(fā)生異常時(shí)不會(huì)影響宿主機(jī)和其他容器的正常運(yùn)行。③Linux 內(nèi)核的能力機(jī)制所帶來(lái)的操作權(quán)限安全。Linux 提供了更加粒度化的權(quán)限訪問(wèn)控制,為保證容器的安全,我們使用Docker 容器時(shí)將會(huì)對(duì)容器的權(quán)限做出嚴(yán)格的限制,限制其只能使用容器功能所需的最小權(quán)限。
雖然Docker 已經(jīng)在安全方面做出了諸多限制,但在使用中Docker 受制于自身缺陷存在以下幾大類的風(fēng)險(xiǎn)。
圖1 容器安全風(fēng)險(xiǎn)概括
Docker 鏡像是Docker 容器的靜態(tài)表現(xiàn)形式,容器運(yùn)行時(shí)的安全取決于Docker 鏡像的安全。Docker hub 作為Docker 官方鏡像倉(cāng)庫(kù),其中的Docker 鏡像對(duì)上傳者缺乏完善的監(jiān)管,其版本、質(zhì)量和安全對(duì)于使用者處于不可控狀態(tài)。
在Dockerfile 中如果不指定USER,Docker 將以root 權(quán)限運(yùn)行該容器,如果被攻擊可能會(huì)導(dǎo)致宿主機(jī)的root 權(quán)限被獲取。Dockerfile 中使用涉及密碼、密鑰等信息,一旦被攻擊將會(huì)導(dǎo)致數(shù)據(jù)泄露。
使用來(lái)源不安全的鏡像,將導(dǎo)致Docker 容器出現(xiàn)不可控的安全風(fēng)險(xiǎn)。
與傳統(tǒng)虛擬機(jī)相比,Docker 容器沒(méi)有獨(dú)立的資源配置,沒(méi)有在系統(tǒng)內(nèi)核層面進(jìn)行資源隔離,因此存在資源隔離與資源限制不徹底的潛在風(fēng)險(xiǎn)。
(1)容器隔離問(wèn)題
Docker 容器和宿主機(jī)共享操作系統(tǒng)內(nèi)核,Docker 容器與宿主機(jī)上其他容器或宿主機(jī)之間存在文件系統(tǒng)隔離、進(jìn)程隔離和進(jìn)程間通信隔離不到位的潛在風(fēng)險(xiǎn)。
Docker 容器隔離安全風(fēng)險(xiǎn)問(wèn)題主要存在以下兩種情況:①攻擊者直接攻擊操作系統(tǒng)內(nèi)核,造成宿主機(jī)上Docker 容器出現(xiàn)安全風(fēng)險(xiǎn)。②攻擊者通過(guò)控制某一個(gè)Docker 容器訪問(wèn)宿主機(jī)或其他容器非法獲取數(shù)據(jù)。
(2)容器逃逸問(wèn)題
容器逃逸攻擊指的是攻擊者通過(guò)非法手段獲取root 權(quán)限,獲得宿主機(jī)或其他容器某種權(quán)利下的命令執(zhí)行能力,影響宿主機(jī)或其他容器的運(yùn)行安全。
(3)拒絕服務(wù)攻擊
Docker 容器與宿主機(jī)共享CPU、內(nèi)存、磁盤空間等硬件資源,如果不對(duì)Docker 容器使用宿主機(jī)資源做出限制,攻擊者可通過(guò)挾持某個(gè)容器,使其耗盡宿主機(jī)的硬件資源達(dá)到使宿主機(jī)或其他容器暫停甚至死機(jī)的目的。
Docker 容器網(wǎng)絡(luò)安全一直是容器使用中面臨的巨大問(wèn)題之一。Docker 網(wǎng)絡(luò)由于其特殊的網(wǎng)絡(luò)環(huán)境,相比于傳統(tǒng)的網(wǎng)絡(luò)安全更加嚴(yán)峻。
(1)容器網(wǎng)絡(luò)攻擊
Docker 容器有多種組網(wǎng)模式,提供了容器間通信、跨主機(jī)容器間通信、容器集群網(wǎng)絡(luò)等功能。下面就幾種主流的組網(wǎng)模式分析其潛在的網(wǎng)絡(luò)安全風(fēng)險(xiǎn)。
橋接模式是Docker 默認(rèn)采用橋接網(wǎng)絡(luò)模式,橋接模式會(huì)在宿主機(jī)上創(chuàng)建一個(gè)docker0虛擬網(wǎng)橋,并將宿主機(jī)上所有采用這種模式的Docker 容器連接在docker0 網(wǎng)橋上,在這種模式下所有的Docker 容器都是互相可達(dá)的。橋接模式雖然對(duì)容器間互相訪問(wèn)提供了便利,但是由于缺乏安全的管理機(jī)制,攻擊者可通過(guò)廣播風(fēng)暴、嗅探、ARP 欺詐等攻擊手段,影響宿主機(jī)和其他容器的安全。
MacVLAN 是Docker 容器的網(wǎng)卡虛擬方案,在多租戶場(chǎng)景下,為每個(gè)租戶單獨(dú)虛擬出獨(dú)自的網(wǎng)絡(luò)從而達(dá)到隔離的目的。但由于同一虛擬網(wǎng)絡(luò)環(huán)境下Docker 容器之間沒(méi)有控制訪問(wèn)權(quán)限,攻擊者仍可以通過(guò)廣播風(fēng)暴、嗅探、ARP 欺詐等攻擊手段,影響宿主機(jī)和其他容器的安全。
Overlay 網(wǎng)絡(luò)作為目前最主流的跨主機(jī)數(shù)據(jù)傳輸和路由方案,主要用于搭建跨主機(jī)的容器集群網(wǎng)絡(luò)。和上面兩種組網(wǎng)模式一樣,由于缺乏訪問(wèn)權(quán)限控制,Overlay 仍然存在安全風(fēng)險(xiǎn)。
因此,不管使用哪種組網(wǎng)模式,都存在容器間互相攻擊的安全風(fēng)險(xiǎn)。
Docker 容器在提供服務(wù)時(shí)往往需要提供7×24的穩(wěn)定服務(wù),攻擊者可能會(huì)從Docker 容器外部以及內(nèi)部對(duì)服務(wù)發(fā)起攻擊,造成服務(wù)不可用。
(1)容器內(nèi)部服務(wù)穩(wěn)定問(wèn)題
Docker 容器內(nèi)部服務(wù)進(jìn)程,可能在受到自身程序穩(wěn)定或外界惡意攻擊時(shí)停止運(yùn)行,導(dǎo)致服務(wù)暫停,在生產(chǎn)環(huán)境中造成損失。
(2)容器運(yùn)行穩(wěn)定問(wèn)題
Docker 容器運(yùn)行在宿主機(jī)上時(shí),可能因?yàn)橥饨鐞阂夤舯魂P(guān)閉或者刪除掉,導(dǎo)致無(wú)法提供服務(wù)。
為保證Docker 容器鏡像的安全性,從官方鏡像倉(cāng)庫(kù)獲取到公共最小基礎(chǔ)鏡像后,需要使用安全掃描工具對(duì)下載的鏡像進(jìn)行安全掃描,目前使用較多的工具包括Docker Security Scanning、Clair 和Trivy 等,可檢測(cè)鏡像中軟件含有CVE 漏洞。
在生成可控的容器鏡像之后為方便鏡像的管理,需要搭建可控的私有鏡像倉(cāng)庫(kù)。需要確保鏡像倉(cāng)庫(kù)不被外界公網(wǎng)所訪問(wèn),在拉取鏡像過(guò)程中采用內(nèi)容校驗(yàn)機(jī)制解決中途容器鏡像被篡改。
為確保Docker 容器中可執(zhí)行文件和配置文件是可信的,在Docker 容器每次啟動(dòng)前對(duì)可執(zhí)行文件和配置文件進(jìn)行CRC32 校驗(yàn),只有校驗(yàn)成功才能啟動(dòng)Docker 容器。假設(shè)可執(zhí)行文件及關(guān)鍵配置文件分別為F1,F2,...Fn,Docker 容器程序部署好之后計(jì)算一次所有可執(zhí)行文件及關(guān)鍵配置文件的校驗(yàn)值C1,并對(duì)校驗(yàn)值進(jìn)行加密保存。Docker 容器啟動(dòng)前對(duì)所有可執(zhí)行文件及關(guān)鍵配置文件再次計(jì)算校驗(yàn)值C2,比對(duì)兩次的校驗(yàn)值。
流程設(shè)計(jì)如圖2 所示:
在容器架構(gòu)中,在已有的Cgroups、Namespace和內(nèi)核能力機(jī)制上可通過(guò)增強(qiáng)操作系統(tǒng)內(nèi)核層面的相關(guān)機(jī)制達(dá)到Docker 容器安全的資源管理。
(1)資源隔離與限制
Cgroups 對(duì)Docker 容器的CPU、內(nèi)存和磁盤I/O 速度等資源項(xiàng)已經(jīng)做出了限制,為防止某個(gè)容器耗盡宿主機(jī)上的硬件資源。在容器啟動(dòng)時(shí),可以使用CPU、Memory、Device 參數(shù)對(duì)CPU 使用率、內(nèi)存占用率、磁盤讀寫(xiě)速率進(jìn)行限制。
圖2 容器鏡像啟動(dòng)流程
對(duì)磁盤使用容量限制,為每個(gè)容器創(chuàng)建單獨(dú)用戶,限制每個(gè)用戶的磁盤使用量。使用XFS 等文件系統(tǒng)目錄進(jìn)行磁盤使用量限制。為每個(gè)容器創(chuàng)建固定大小的虛擬文件系統(tǒng)。
(2)強(qiáng)制訪問(wèn)控制
通過(guò)SELinux 機(jī)制實(shí)現(xiàn)Docker 容器對(duì)宿主機(jī)資源的訪問(wèn)限制,在啟動(dòng)Docker 容器時(shí)可通過(guò)docker daemon --selinux-enabled=true 命令啟動(dòng)SELinux。
(1)容器流量限制
在生產(chǎn)環(huán)境中宿主機(jī)通常會(huì)部署成百上千個(gè)Docker 容器為多租戶提供服務(wù),為避免個(gè)別容器搶占絕大部分的帶寬,導(dǎo)致其他Docker 容器服務(wù)不可用,采用Linux 的流量控制模塊traffic controller 對(duì)容器網(wǎng)絡(luò)進(jìn)行流量限制。
(2)白名單訪問(wèn)控制
為防止惡意的網(wǎng)絡(luò)攻擊,保證Docker 容器的網(wǎng)絡(luò)安全,可以通過(guò)配置白名單策略實(shí)現(xiàn)網(wǎng)絡(luò)訪問(wèn)控制。白名單的訪問(wèn)策略,可以由Linux 自帶的防火墻機(jī)制實(shí)現(xiàn)。
(3)禁止容器間通信
當(dāng)Docker 容器單獨(dú)提供服務(wù)而不需要多個(gè)Docker 容器組成微服務(wù)時(shí)。為防止Docker 容器間惡意攻擊需要禁止容器間通信,可通過(guò)命令dockerd--icc=false 完成設(shè)置。
Docker 容器最主要的功能就是提供健壯、穩(wěn)定的輕量級(jí)虛擬化服務(wù)。為保證Docker 容器內(nèi)服務(wù)程序的穩(wěn)定性,在容器內(nèi)可由看門狗程序進(jìn)行定期檢查。同時(shí),可以建立一個(gè)容器管理中心,定期接收容器內(nèi)心跳程序發(fā)來(lái)的心跳數(shù)據(jù),并根據(jù)接收情況進(jìn)行處理。
(1)看門狗程序
“看門狗”程序主要用作Docker 內(nèi)服務(wù)的啟動(dòng)和檢查工作。其主要工作流程如圖3 所示。
步驟1:?jiǎn)?dòng)容器內(nèi)服務(wù)程序。
步驟2:定期檢查服務(wù)程序的狀態(tài),發(fā)現(xiàn)服務(wù)程序掛掉后,上報(bào)記錄問(wèn)題到管理模塊,重新啟動(dòng)服務(wù)程序。
步驟3:等待下一次檢查。
(2)心跳程序
通過(guò)實(shí)現(xiàn)Docker 容器內(nèi)心跳進(jìn)程,向管理中心定期發(fā)送心跳和運(yùn)行數(shù)據(jù),達(dá)到容器內(nèi)資源監(jiān)聽(tīng)等目的。其主要流程如圖4 所示。
圖3 看門狗程序執(zhí)行流程
圖4 心跳處理流程
步驟1:Docker 容器內(nèi)心跳進(jìn)程,定期向管理中心發(fā)送Docker 容器CPU、內(nèi)存使用率等數(shù)據(jù)。
步驟2:管理中心接收Docker 發(fā)送的數(shù)據(jù),對(duì)數(shù)據(jù)進(jìn)行記錄,若容器CPU、內(nèi)存等數(shù)據(jù)長(zhǎng)期超過(guò)設(shè)定的安全值,則需要對(duì)該Docker 容器進(jìn)行檢查和資源重新分配。
步驟3:管理中心在超時(shí)時(shí)間內(nèi)未接收到Docker 容器內(nèi)心跳進(jìn)程發(fā)送的數(shù)據(jù)。發(fā)送ICMP 包到Docker 容器,若容器無(wú)返回,則通知宿主機(jī)刪除該容器并重新創(chuàng)建。
步驟4:ICMP 包返回,則進(jìn)一步通過(guò)IP 地址和端口執(zhí)行TCP 檢查,接收返回的檢查結(jié)果,若檢查結(jié)果成功則表示Docker 容器可用,否則通知宿主機(jī)刪除該容器并重新創(chuàng)建。
本文通過(guò)分析Docker 容器在使用中可能遇到的安全風(fēng)險(xiǎn),給出了解決方案。在Docker 容器生產(chǎn)部署時(shí),應(yīng)全面考慮可能出現(xiàn)的安全風(fēng)險(xiǎn),根據(jù)部署場(chǎng)景給出對(duì)應(yīng)的安全需求分析,并結(jié)合Docker容器的安全解決方案,形成容器安全應(yīng)用最佳實(shí)踐。