李鵬超,周 凱
(1.重慶警察學(xué)院 信息安全系,重慶 401331;2.西南大學(xué) 計算機與信息科學(xué)學(xué)院,重慶 400715)
目前,虛擬化技術(shù)已廣泛應(yīng)用于服務(wù)器中,Docker虛擬化技術(shù)[1-3]因其提供了輕量化的虛擬環(huán)境,與其他虛擬化工具相比更具優(yōu)越性.但Docker虛擬化技術(shù)使用過程中還有諸多問題需進一步解決[4].例如,當(dāng)Docker環(huán)境遭受人為破壞或攻擊時,取證人員所進行的基于Docker環(huán)境的數(shù)據(jù)調(diào)查取證問題,目前尚未見對Docker取證技術(shù)進行深入研究的報道.取證人員為了解在一個Docker主機上發(fā)生的真實情況,除利用現(xiàn)有的主機調(diào)查取證方法外,還需要一種基于Docker環(huán)境下的特殊化取證方法.因此,本文在對Dokcer原理及相關(guān)技術(shù)分析的基礎(chǔ)上,提出一種基于Docker主機的調(diào)查取證模型,并根據(jù)該取證流程各環(huán)節(jié)中Docker主機所處的不同狀態(tài)制定有針對性的數(shù)字取證方法.
圖1為傳統(tǒng)虛擬機與Docker對比的示意圖.由圖1可見,傳統(tǒng)虛擬機宿主主機操作系統(tǒng)上層是管理程序,管理程序上層是客戶操作系統(tǒng),最后在客戶操作系統(tǒng)上運行應(yīng)用程序.而在Docker環(huán)境中,宿主主機操作系統(tǒng)上層為Docker引擎,Docker在引擎上構(gòu)建一個相互隔離的容器,在容器內(nèi)運行應(yīng)用程序.
Docker與傳統(tǒng)虛擬技術(shù)的區(qū)別為Docker上不安裝客戶操作系統(tǒng),只設(shè)置服務(wù)器的程序和庫,且Docker引擎共享宿主機操作系統(tǒng)資源[5].
Docker中的鏡像可提供服務(wù)器所需的程序、可編譯執(zhí)行文件等所有文件系統(tǒng)資源.而容器是Docker由鏡像構(gòu)成的特定可運行隔離環(huán)境.鏡像以分層的形式組成,根據(jù)不同存儲數(shù)據(jù)和存儲庫的使用方式,構(gòu)成鏡像的方式也不同.如Docker可通過dockerfile文件生成鏡像,dockerfile是一個可自動化生成鏡像的文件.按照dockerfile的擬定規(guī)則創(chuàng)建文件后,在該文件所屬的路徑中通過“docker build-t khs/Whserver:v2.”命令編譯并生成鏡像.在Docker中以特定的鏡像為對象組成一個容器,如圖2所示.

圖1 傳統(tǒng)虛擬機與Docker對比示意圖Fig.1 Schematic diagram of comparison between traditional virtual machine and Docker

圖2 Docker分層結(jié)構(gòu)Fig.2 Layered structure of Docker
容器中存儲的數(shù)據(jù)會隨著容器的消失一起被刪除.而數(shù)據(jù)卷的存在與容器無直接關(guān)系,因此用戶可將需永久保存的數(shù)據(jù)或與其他容器和主機需共享保存的數(shù)據(jù)存儲在數(shù)據(jù)卷中.Docker也支持?jǐn)?shù)據(jù)卷功能.數(shù)據(jù)卷是指在容器掛載的宿主主機文件系統(tǒng)上的目錄或文件[3].配置容器時使用“-v主機內(nèi)目錄:容器內(nèi)的目錄”命令將主機內(nèi)的相應(yīng)路徑作為數(shù)據(jù)卷并映射到容器目錄內(nèi).在數(shù)據(jù)卷上保存的文件或目錄并不是存儲在容器內(nèi)的文件系統(tǒng)中,而是直接保存在宿主主機的相應(yīng)目錄內(nèi),即在容器內(nèi)的數(shù)據(jù)卷上接觸到的行為與容器本身的文件存儲沒有關(guān)系.
通過“docker commit”命令將容器生成為鏡像,但數(shù)據(jù)卷內(nèi)的數(shù)據(jù)不包含在鏡像中,數(shù)據(jù)卷中的文件和目錄即使在容器被刪除后也依然存在.此外,還可使用特定的容器作為數(shù)據(jù)卷,這種方式稱為數(shù)據(jù)卷容器[6].數(shù)據(jù)卷容器先通過命名的容器掛載數(shù)據(jù)卷,然后其他容器通過掛載該容器實現(xiàn)數(shù)據(jù)共享.
Docker還支持多種網(wǎng)絡(luò)配置模式,包括單主機內(nèi)的跨容器網(wǎng)絡(luò)模式和跨多主機間的網(wǎng)絡(luò)模式.
1.4.1 單主機內(nèi)容器間網(wǎng)絡(luò)模式 當(dāng)Docker進入安裝時會在主機上創(chuàng)建一個名為docker0的虛擬網(wǎng)橋,該主機上啟動的Docker會連接到虛擬網(wǎng)橋[7].主機上的所有容器都通過虛擬網(wǎng)橋連接在一個二層網(wǎng)絡(luò)中,用戶可以通過使用網(wǎng)橋連接網(wǎng)絡(luò)命令“docker network create-d bridge網(wǎng)橋名”創(chuàng)建新的虛擬網(wǎng)絡(luò).此外,容器組成時指定了“-network=網(wǎng)絡(luò)名稱”選項,可將相應(yīng)的容器連接到特定網(wǎng)絡(luò).雖然容器可同時連接多個網(wǎng)絡(luò),但容器僅能在網(wǎng)絡(luò)內(nèi)通信,不能跨網(wǎng)絡(luò)通信.此外,還可以在容器組織中指定“-link容器或id:連接時使用的別稱”,這樣構(gòu)成的網(wǎng)絡(luò)在容器間不僅可以使用IP地址通信,而且還可以通過指定的別稱進行通信.如果使用link選項,所有相關(guān)DNS的信息會反映在相關(guān)內(nèi)容中,可用于調(diào)查取證.
1.4.2 多主機中容器組成的網(wǎng)絡(luò)
1) Ambassador跨主機間容器通信技術(shù).針對不同主機上的兩個容器間通信,Docker通過Ambassador模式實現(xiàn)[8].圖3為使用Ambassador模式實現(xiàn)兩個不同主機上容器間的網(wǎng)絡(luò)連接模型.

圖3 Ambassador網(wǎng)絡(luò)模式Fig.3 Network pattern of Ambassador
不同主機的容器建立連接還需借助socat程序?qū)CP連接傳達到另一個容器,實現(xiàn)步驟如下:
① 主機A創(chuàng)建使用端口號x的服務(wù)端容器;
② 使用“docker run-d -link A: servercontainer -nameambassadorforserver -p端口(x): 端口(x)服務(wù)端ambassador”命令啟動服務(wù)端Ambassador容器;
③ 在另一臺客戶端主機上使用“docker run -d-name ambassadorforclient -expose 端口(y)-e SERVER_PORT_TCP=tcp://A主機IP地址: 端口(x)服務(wù)端ambassador”命令,在客戶端主機B上啟動另一個客戶端Ambassador容器;
④ 通過“-link客戶端Ambassador容器: 別稱”命令連接在主機B上的客戶端容器.
通過以上4步可實現(xiàn)Docker間的Ambassador模式網(wǎng)絡(luò)連接.
2) Overlay網(wǎng)絡(luò)模式.Overlay網(wǎng)絡(luò)是不同主機間容器實現(xiàn)通信的網(wǎng)絡(luò)[9].Docker自帶的Swarm是一種Docker集群的管理和編排模式[10].Swarm將在多個主機上創(chuàng)建容器并實現(xiàn)容器間的跨主機通信.集群分管理節(jié)點和工作節(jié)點兩部分,一般的操作在管理節(jié)點上執(zhí)行.Swarm模式運行步驟如下:
① 管理節(jié)點主機使用“docker swarm init -advertise -addr主機IP地址”命令初始化集群,節(jié)點間相互通信的IP地址為主機IP地址,默認(rèn)端口為2377;
② 工作節(jié)點主機使用命令“docker swarm join -token 步驟①中使用的IP地址: 2377端口”加入到初始化的集群中;
③ Swarm集群組成后,管理節(jié)點主機使用“docker service create -name Websever -replicas 3 -publish 8080:80 Nginx”命令在Swarm集群中發(fā)布應(yīng)用服務(wù),并將容器中的80端口映射到Swarm集群的8080端口,此時Swarm內(nèi)的節(jié)點中端口被公開,可通過Swarm技術(shù)操作提供服務(wù).
通過上述方式Docker實現(xiàn)了在集群模式下的網(wǎng)絡(luò)連接.
在對Docker進行調(diào)查取證時,可能會出現(xiàn)部署在Docker容器中的一個網(wǎng)站服務(wù)器受到惡意攻擊的情形.例如,某企業(yè)為了提供服務(wù),需要一個服務(wù)器提供全部周期更新的服務(wù),該服務(wù)器可能受到攻擊,使調(diào)查人員提取到可能出現(xiàn)惡性程序的鏡像.此外,作為基礎(chǔ)設(shè)施提供服務(wù)的主機自身也可能受到攻擊.這種情形下,取證人員在進行取證過程中不僅要分析主機自身,還要調(diào)查提供服務(wù)的Docker環(huán)境.
在對Docker主機進行取證過程中,存在Docker守護進程啟動或停止兩種情形.前者可通過使用基本指令進行取證;后者如果允許重啟Docker服務(wù)也可使用基本命令進行調(diào)查.但如果出現(xiàn)以下情形時,取證人員則需利用Docker相關(guān)的技術(shù)和方法提取證據(jù):
1) 將Docker的宿主主機硬盤復(fù)制后,用克隆硬盤重新運行Docker服務(wù),由于當(dāng)時各服務(wù)的運行情形已不存在,因此需要對當(dāng)時情形提供的信息進行調(diào)查取證;
2) 將特定容器文件系統(tǒng)中存儲的已刪除文件以傳統(tǒng)取證工具恢復(fù)后進行調(diào)查取證;
3) 為取證先克隆宿主主機的文件系統(tǒng),然后利用存在主機內(nèi)的容器進行快速調(diào)查取證.
取證人員在調(diào)查取證過程中如果出現(xiàn)以上3種情形,就需要收集相關(guān)Docker服務(wù)留下的痕跡信息并掌握其含義.在調(diào)查取證過程中,取證人員不但要掌握使用Docker的主機及其間的網(wǎng)絡(luò)信息,還要掌握各主機內(nèi)容器的實際運行信息.本文針對Docker環(huán)境取證的特殊情形,有針對性地提出了Docker取證流程.無論Docker服務(wù)運行正常與否,取證人員對基礎(chǔ)主機的Docker取證過程都如圖4所示.

圖4 基于Docker主機的取證流程Fig.4 Forensics process based on Docker host
取證人員在取證調(diào)查時,不但要了解多主機組成網(wǎng)絡(luò)所提供的Docker服務(wù),也要掌握在單一主機上運行的Docker所提供的服務(wù).在前者情形下,取證人員先要掌握基礎(chǔ)主機Docker間的網(wǎng)絡(luò)結(jié)構(gòu),然后再進行單主機Docker的調(diào)查取證.
取證人員首先分析基于Docker網(wǎng)絡(luò)間的連接方式.如果連接方式來自O(shè)verlay網(wǎng)絡(luò),則可在調(diào)查對象主機上利用“docker network”命令顯示容器的Overlay網(wǎng)絡(luò)ID,并分析相同Overlay網(wǎng)絡(luò)其他主機內(nèi)的容器是否屬于同一網(wǎng)絡(luò).如果所有主機都是以Swarm模式進行網(wǎng)絡(luò)連接,且在調(diào)查過程中使用“docker info”命令檢測到Swarm的狀態(tài)信息顯示為Active,則在對Swarm模式分析時還要掌握該集群所提供的服務(wù)信息,因此需要查找管理節(jié)點,這是因為Swarm的信息查詢命令只在管理節(jié)點有作用.在管理節(jié)點上以“docker service ls”命令顯示在Swarm中執(zhí)行的服務(wù)內(nèi)容,并通過“docker service ps服務(wù)名”命令顯示提供服務(wù)的進程列表.取證人員可以用“docker service inspect服務(wù)名”命令掌握該服務(wù)的詳細(xì)內(nèi)容.此外,取證人員也可以在管理節(jié)點上以“docker&ls”命令顯示該Swarm內(nèi)所有的目錄狀態(tài)并以“docker node inspect節(jié)點名稱”命令顯示特定節(jié)點的詳細(xì)信息.因此,取證人員可通過執(zhí)行上述命令,在Docker的網(wǎng)絡(luò)環(huán)境中提取重要信息和證據(jù).
如果取證人員所調(diào)查的Docker環(huán)境處于Inactive狀態(tài),則需要在“/var/lib/docker/container/”的目錄內(nèi)查詢Config.v2.json文件以確定容器Overlay模式的網(wǎng)絡(luò)信息.如果是Swarm模式,則需要確定主機所屬Swarm執(zhí)行的服務(wù)信息和應(yīng)用程序.可以在主機的“/var/docker/swarm/docker-state.json”文件內(nèi)查看管理節(jié)點、工作節(jié)點的本地IP地址及管理節(jié)點的遠(yuǎn)程IP地址信息.取證人員還可通過advertiseaddr命令監(jiān)聽IP地址和端口的狀態(tài),以獲取Docker在Inactvie時的網(wǎng)絡(luò)情形和信息.
取證人員在掌握了多主機間的網(wǎng)絡(luò)連接信息后,即可進行單主機的Docker調(diào)查取證工作.
2.2.1 分析容器基本信息 取證人員需要收集相關(guān)主機內(nèi)Docker容器的基本信息,以判斷Docker的運行情形.取證人員可先通過“docker version”命令獲取Docker的版本信息,然后使用“docker info”命令調(diào)查Docker上的容器數(shù)量、鏡像數(shù)量、存儲驅(qū)動程序、網(wǎng)絡(luò)模式等基本信息,最后以“docker stats”命令獲取各容器的主機資源使用信息.特別是在Docker服務(wù)Active的情形下“docker info”命令可以提供給取證人員關(guān)于Docker的整體信息.
2.2.2 主機內(nèi)Docker網(wǎng)絡(luò)調(diào)查取證 在單主機內(nèi)也可以組成各容器間的網(wǎng)絡(luò)連接,因此需要調(diào)查其網(wǎng)絡(luò)狀態(tài).與多主機間的網(wǎng)絡(luò)結(jié)構(gòu)調(diào)查部分類似,取證人員先使用“docker network ls”命令列出網(wǎng)絡(luò)結(jié)構(gòu)包括跨Swarm多主機網(wǎng)絡(luò),然后利用“docker network inspect網(wǎng)絡(luò)名”命令調(diào)查該網(wǎng)絡(luò)的詳細(xì)信息,最后得到在相關(guān)網(wǎng)絡(luò)上連接的正在運行的容器相關(guān)信息.取證人員在取證過程中如果發(fā)現(xiàn)容器創(chuàng)建了一個網(wǎng)橋且掛載為docker0,則可進一步分析在網(wǎng)絡(luò)上連接的容器功能.因此,取證人員需要利用“docker port”命令或“docker ps”命令掌握容器和主機的映射端口信息.
如果Docker的服務(wù)處于Inactive狀態(tài),則取證人員可在“/var/lib/docker/contaiers”目錄內(nèi)分析config.v2.json文件的相關(guān)信息.通過對config.v2.json文件內(nèi)容進行分析可獲取容器的bridge network信息,并知道該容器及其主機的端口狀態(tài).在同一路徑的hosts文件內(nèi),容器建立時使用的“-link選項”提供了容器的相關(guān)信息,以“l(fā)inks: [連接容器名稱: 指定別稱]”形式存在.通過指定別稱還可獲取連接到其他容器的關(guān)鍵信息,所以取證人員可以此進行深入取證分析.
2.2.3 鏡像及容器的調(diào)查取證 基于Docker的容器和鏡像分析是Docker主機取證研究的核心部分.取證人員獲取鏡像和容器的狀態(tài)信息后,與上文所獲取的網(wǎng)絡(luò)取證結(jié)果相結(jié)合,不僅能查明主機的作用而且可以在存儲相關(guān)內(nèi)容的文件系統(tǒng)中獲得更直接的證據(jù).
1) 鏡像和容器基本信息調(diào)查.Docker在Active的情形下,取證人員可以使用“docker images”命令查詢已存在的鏡像信息,使用“docker ps”命令獲取在激活狀態(tài)下的容器信息.如果取證人員想查詢主機上被指定的容器信息,可以使用“docker ps -a”命令.如果需要進一步收集各個鏡像或容器的詳細(xì)信息,則需要使用“docker inspect鏡像或容器名”命令.
2) 特定容器的取證分析.在基于Docker主機的取證過程中關(guān)鍵是要掌握容器在執(zhí)行時的服務(wù)信息.取證人員可利用“docker top”命令掌握特定容器內(nèi)運行的進程信息,用“docker attach容器名”命令獲取當(dāng)前容器中輸出的內(nèi)容.為了檢查在現(xiàn)有鏡像上進行容器實例化后文件結(jié)構(gòu)是否發(fā)生更改,取證人員可使用“docker diff 容器名”命令查看文件結(jié)構(gòu)的更改信息,其中A表示增加,C表示變更,D表示被刪除的文件或目錄[11].如果在刪除文件中發(fā)現(xiàn)需要深入分析的文件,則可使用“dockercopy 容器路徑:容器名 主機路徑”命令復(fù)制相應(yīng)目錄或文件到宿主主機后再進行分析.最后,取證人員還可通過調(diào)查容器內(nèi)的進程和文件結(jié)構(gòu)的變更事項,發(fā)現(xiàn)該容器的運行是否有異常.
3) 文件系統(tǒng)信息調(diào)查.在Docker服務(wù)Active的狀態(tài)下,取證人員可對鏡像或容器的文件系統(tǒng)以文件為單位進行提取分析.取證人員可利用“docker save -o文件名.tar鏡像名”命令將特定的鏡像提取成tar文件后,在其他主機的Docker中使用“docker load文件名.tar”命令將該鏡像重新加載分析.如果把需要進一步調(diào)查的容器原樣地提取,則需要使用“docker export容器名稱>文件名.tar”命令,然后使用“cat文件名.tar|docker import-指定的名稱”命令在本地重新生成容器.但即使將容器的文件系統(tǒng)重新裝入到Docker內(nèi),在此狀態(tài)下鏡像內(nèi)存在的被刪除文件或容器形成后被刪除文件仍然無法恢復(fù).因此,為了恢復(fù)在特定容器內(nèi)被刪除的文件,取證人員需使用其他方法提取文件系統(tǒng)中被刪除的文件信息.根據(jù)Docker使用存儲驅(qū)動程序的不同恢復(fù)容器內(nèi)被刪除文件的方法有差異[12].
調(diào)查鏡像和容器的文件系統(tǒng)后發(fā)現(xiàn)有些文件不被保存在相應(yīng)的文件系統(tǒng)中,因此需進行對容器創(chuàng)建的數(shù)據(jù)卷進行調(diào)查.數(shù)據(jù)卷用于容器間的數(shù)據(jù)共享,其本身存儲的信息與容器無關(guān),因此對數(shù)據(jù)卷保存的信息需另外進行調(diào)查取證.在容器處于Active狀態(tài)下,取證人員使用“docker volume ls”命令和“docker volume inspection卷名”命令可獲得數(shù)據(jù)卷的信息.
如果取證人員需要在Docker處于Inactive狀態(tài)中確認(rèn)特定容器使用的數(shù)據(jù)卷文件,則可通過“/var/lib/docker/containers/”目錄內(nèi)config.v2.json文件中的sha256值確認(rèn)容器名稱,然后從同一文件內(nèi)容中查詢mount的sha256值即可獲取要進一步分析的文件信息.此外,取證人員還可以從“/var/lib/docker/volumes/”中查看該容器在數(shù)據(jù)卷上留下的文件或目錄.
關(guān)于容器內(nèi)各種行為軌跡的信息調(diào)查,以時間為調(diào)查主線可獲取更多的線索.因此,要了解各時間段在容器內(nèi)的操作痕跡,必須分析其操作日志信息.容器在生成時以“-log-driver”選項指定了日志方式,記錄了容器在運行過程輸出的數(shù)據(jù)信息.取證人員可通過“docker logs容器名稱”命令查看容器的日志信息.
如果容器處于Inactive狀態(tài),則可以通過查詢“/var/lib/docker/containers/container-jsonlog”命令獲取相關(guān)的日志信息.如果登錄驅(qū)動程序不是默認(rèn)選項,而是被指定為另一個主機,則被指定容器的“docker logs”無法使用,要調(diào)查登錄另一個主機.日志驅(qū)動程序選項“gelf,fluentd,awslogs,splunk,etwlogs,gcplogs”可作為外部主機傳送的選項[13-14].在此情形下,取證人員需掌握登錄主機的位置和運行原理提取該容器的日志.由于日志對容器具有標(biāo)準(zhǔn)輸入輸出記錄,因此可通過日志調(diào)查該系統(tǒng)的系統(tǒng)管理器在容器內(nèi)部進行的活動,得到關(guān)于一個惡意行為以及應(yīng)用程序發(fā)生錯誤的相關(guān)線索.
綜上所述,本文以Docker容器的數(shù)據(jù)存儲原理和網(wǎng)絡(luò)環(huán)境分析為基礎(chǔ),針對Docker作為服務(wù)環(huán)境的主機在受到惡意攻擊或破壞時,取證人員應(yīng)以何種角度進行取證進行了研究.通過建立切實有效的取證模型和工作流程,闡述了在Docker守護進程處于活動時,取證人員可根據(jù)取證模型并通過使用Docker守護進程的相關(guān)命令完成對Docker的調(diào)查取證工作.