本文將簡介Docker技術,說明Docker的背景知識和安全議題。並在此介紹Docker映像檔檢測工具Anchore Engine,藉由模擬演練讓大家了解如何運用Anchore Engine抓出Docker映像檔潛在安全問題,使系統安全得以獲得保障。
在2014年時,Docker的出現提供了使用者更為輕量化的虛擬機器環境,不但可透過虛擬機器技術來減少應用程式因環境不同而無法運用的窘境,還能降低對硬體資源的需求。此外,Docker具備部署效率高、可攜性高等特性也深受開發者的愛戴,同時也是目前熱門的微服務(Microservices)架構能夠實現的重要推手之一。在軟體開發的架構上,「微服務架構」將一個架構中每個元件和服務所要做的工作切分得很精密,然而,在過去建置不易的微服務架構,隨著Docker技術的出現,也得以降低門檻。
然而,看似優點多多的Docker亦有難以避免的安全問題。例如,部分Docker映像檔中所包含的應用程式版本含有已知的漏洞資訊或是被有心人士植入惡意的程式等,一旦這些有問題Docker映像檔被實際部署到各系統上,將會是管理者與使用者的惡夢。
Docker背景知識說明
接著,介紹Docker、Docker與虛擬機器的比較,以及Docker的基本物件和運作方式。
什麼是Docker
自從Linux之父Linus Torvalds於2013年將Linux核心3.8版(Linux Kernel 3.8)正式釋出後,在這個版本中所強化的Cgroup和Namespace兩項Linux核心技術為未來十年的IT架構立下重要的變革,而這一切的變革不只是Linus Torvalds釋出核心版本,還有於2014年成立的Docker公司所打造的容器標準化平台。
Docker公司所打造的容器標準化平台其實是Docker的前身dotCloud這間公司和Red Hat所開發的OpenShift平台進行共同整合後釋出的開源專案,在這之後,dotCloud也將公司名稱更改為Docker。
Docker為輕量級的虛擬化技術,它的基本哲學為「Build and Ship any Application Anywhere」,也就是可以建置任何應用程式並運行在任何地方。Docker允許開發者將程式執行的基礎建設進行分離,好處是讓開發者能夠更專注於開發讓一般人可以使用的應用程式,而不用花太多時間在安裝及環境的設定。
Docker與虛擬機器的比較
在Docker技術中真正實現虛擬化並運行應用程式環境的部分,稱之為容器(Container),然而,在虛擬化技術的世界中,除了Docker容器外,虛擬機器也是常常被討論的技術,且兩者時常被提出來比較。因此,以下針對容器和虛擬機器列出四個比較項目,如表1所示,分別為占用宿主機之空間、運作方式、部署時間以及運作思維。另外,也提供虛擬機器與容器的分層架構圖,分別如圖1和圖2所示。
容器和虛擬機器在運作的思維截然不同,容器是以應用程式為中心,虛擬機器是以作業系統為中心。此外,容器不像虛擬機器會將使用虛擬機器監視器(Hypervisor)來虛擬化硬體、軟體及韌體等,而是基於其「宿主機(Host Machine)」的核心去運行。在部署時間和占用之宿主機空間的表現上,容器部署時間更快且占用之空間較少,反之,虛擬機器則是較慢且占用的空間較龐大。
Docker的基本物件和運作流程
關於Docker的基本物件和運作流程,說明如下:
Docker利用容器(Container)來執行應用程式,為Docker的關鍵技術。容器是從映像檔中執行出來的實例,每個容器都是相互隔離的。可以把容器想像成簡易版的Linux環境,包括網路、使用者空間和root權限。
每一個容器會對應到一個映像檔(Image),映像檔可說是容器建立的範本。容器中所需要的環境配置、相關套件庫或程式碼都會被包在映像檔中。此外,映像檔可以被存放到遠端的儲存庫(Registry),並提供其他人下載使用。
映像檔可透過Dockerfile檔案產生,映像檔中所包含的環境配置檔、相關套件庫及程式碼等內容,這些內容都可以在Dockerfile中被定義。在定義完成後,可透過指令將Dockerfile打包成映像檔。
儲存庫(Registry)可以想像成是集中存放映像檔的資料庫,可以分為公開和私人的兩種,目前最大的公開儲存庫為Docker公司所維護的儲存庫Docker Hub,網址為「https://hub.docker.com/」,任何人都可以將產生的映像檔放到Docker Hub做儲存並提供大家下載使用,反之,也可以從Docker Hub下載需要的映像檔資源。Docker Hub的概念與軟體程式碼代管服務平台GitHub(網址為https://github.com/),有著異曲同工之妙。
容器被停止或刪除後,原本在容器中的資料也會被一概清除,然而,有的時候會運行如資料庫服務的容器,作為資料庫沒有理由當容器被停止或刪除後資料就不見,因此卷(Volume)的概念是讓容器可以將資料保留,不會因為容器停止或刪除後而資料跟著遺失。
Docker主要是從如Docker Hub等遠端儲存庫透過指令下載映像檔,再將映像檔透過指令變成真正執行應用程式的容器,在使用上可說是十分便利,僅需要簡單幾個步驟便能將應用程式啟動完成。使用者只要有安裝Docker,並知道要從何處取得映像檔,就能透過指令「docker pull」取得映像檔,並使用指令「docker run」啟動容器來執行映像檔。但是,在這過程中缺乏資安檢測,當有惡意的映像檔或有問題的程式套件庫或程式碼被寫入Dockerfile並被打包成映像檔,最後被執行成為容器時,將可能是使用者的惡夢。
Docker安全與工具檢測
容器為Docker技術中實現虛擬化技術的方式,然而,各種技術都會有其一定程度的風險存在,容器也不例外,以下將帶大家了解Docker本身和真正實現虛擬化技術的容器可能存在的安全風險,以及如何透過Anchore Engine這個容器檢測工具去檢測容器的安全性。
Docker與容器安全性問題
Docker與容器安全主要可以分為三類:
Docker本身也是一種應用程式,舉凡是應用程式多多少少都會存在些許的漏洞,與Docker相關的CVE(Common Vulnerabilities and Exposures)漏洞編號就超過30個。因此,確保在使用Docker時無安全疑慮的最好方式是,定期將版本更新至最新版本,來降低安全的風險。
Docker技術的運作原理是,會在一台主機上安裝Docker引擎,以便在Docker引擎上啟動多個容器服務,因此提供安裝Docker引擎的這台主機便被稱為「宿主機(Host Machine)」。Docker引擎會與宿主機共享作業系統的「核心(Kernel)」來存取系統的硬體資源。若系統核心有漏洞時,駭客就有機會透過在容器中的一些操作來取得操作宿主機之作業系統核心的權限,站在資安的角度來看,這是相當不安全的一個事件。
關於Docker映像檔來源,可從三方面來做說明:
‧駭客上傳有問題的映像檔:如果有駭客將有問題的映像檔,例如在映像檔中寫入後門程式等,並上傳至公開的儲存庫(如Docker Hub)供大家下載,只要使用者下載並使用該映像檔來啟動容器,便有可能導致系統上的嚴重資安問題。例如,在2021年3月就有資安研究人員發現,有些下載次數超過千萬次的映像檔竟內含挖礦程式。
‧映像檔中含有過期的軟體套件版本:容器中所啟動的服務皆取決於映像檔在建立時所寫入的軟體套件或程式碼,然而,經常發生在映像檔中所包含的軟體套件版本沒有被更新,還可檢測出CVE漏洞,進而導致啟動出來的容器也運行著有漏洞的服務。
‧中間人攻擊竄改映像檔之內容:「中間人攻擊(Man in the Middle Attack)」是資訊安全中很常見的攻擊手法,駭客在網路傳輸中將傳送方傳送的內容攔截並竄改後再交到接收方手上,此時接收方收到的內容就會是被竄改過而非原始的內容。在將映像檔上傳至公開儲存庫或者下載至使用者的本地端時,都須要透過網路傳輸,中間人攻擊就有可能會發生。
常見的容器檢測工具
容器的安全從表1中可以發現,大部分都是來自於映像檔,因為一個容器就是由映像檔去啟動而成的,因此確保每一次啟動容器時所使用的映像檔是乾淨的,就成為一個很重要的議題。目前在市面上有許多種的檢測映像檔的工具,以下列出並說明最常被使用的三種檢測工具,分別為Clair、Trivy以及Anchore Engine。
Clair為容器作業系統公司CoreOS所釋出的映像檔安全分析引擎,透過掃描映像檔的方式來監控容器的安全性。主要的掃描對象為映像檔中與作業系統相關的漏洞。該專案的GitHub網址為「https://github.com/quay/clair」。然而,Clair的缺點在於安裝較複雜,而易用的Clair-cli工具已多年未更新。
Trivy為2015年成立的Aqua Security公司所釋出的容器檢測工具,特點是易於安裝與使用,使用者可快速上手。該專案的GitHub網址為「https://github.com/aquasecurity/trivy」。
Anchore Engine為容器安全公司Anchore所管理,在功能方面比Trivy來得更豐富,且亦可使用Docker來安裝。此外,其主要的掃描對象比起Clair專注在映像檔中與作業系統相關的漏洞外,還多了「非作業系統(non-OS)」相關的掃描,並會回傳掃描之映像檔的CVE漏洞資訊,該專案的GitHub網址為「https://github.com/anchore/Anchore Engine」。
Docker是否安全有一大部分是取決於映像檔,因此這裡將仰賴檢測工具輔助判斷Docker映像檔是否安全。從上段檢測工具介紹中可以發現,Anchore Engine比起另外兩種工具,多了一項「非OS相關套件」的掃描功能,在掃描能力上略顯突出。因此,接下來將以Anchore Engine為範例,從安裝到掃描及評估映像檔,一步一步了解Anchore Engine的功能和實際操作方式。
安裝Anchore Engine 並實際操作
本次操作步驟皆以Ubuntu Linux為範例,先安裝再說明常用指令。
安裝Docker和Docker-compose
因啟動Anchore Engine服務時需要搭配資料庫Postgres等多個服務,因此使用Docker-Compose方式來啟動這些服務。Docker的安裝方式,可參照其官網教學,網址為「https://docs.docker.com/engine/install/ubuntu/」。安裝Docker-Compose則可參照Docker官網網址(https://docs.docker.com/compose/install/),並請參考使用curl下載安裝檔、apt或使用Python的pip3方式來安裝。
安裝Anchore Engine
首先,執行指令「sudo curl -O https://engine.anchore.io/docs/quickstart/docker-compose.yaml」,下載Anchore官方的docker-compose.yaml檔。然後,執行「sudo docker-compose up -d」指令,啟動Anchore Engine等相關服務。
緊接著,輸入指令「sudo docker-compose ps」,確認是否執行成功。若看到狀態欄state部分皆為up (healthy)就表示都有啟動成功,如圖3所示。
Anchore Engine常用指令
安裝完成後,就可以透過Anchore Engine提供的指令與其互動。在Anchore Engine提供的參數操作中,表2中的三個最常被使用,以下操作為加入一個映像檔並得知其可能存在的漏洞資訊,最後利用evaluate指令查看這個映像檔是否通過檢查機制。
STEP 1:執行指令「sudo docker-compose exec api anchore-cli system status」,檢查Anchore Engine的狀態,如圖4所示。
STEP 2:然後執行指令「sudo docker-compose exec api anchore-cli system feeds list」以同步漏洞資料庫,若右邊數字都大於0即表示同步完成,如圖5所示。
STEP 3:當漏洞資料庫同步完成後,便可加入欲分析的映像檔,在此以nginx的1.11.1版本的映像檔為範例,執行指令「sudo docker-compose exec api anchore-cli image add docker.io/library/nginx:1.11.1」。
STEP 4:在映像檔被加入後,Anchore Engine便會開始進行分析,可透過指令「sudo docker-compose exec api anchore-cli image wait docker.io/library/ nginx:1.11.1」查看目前分析狀態,此映像檔顯示的結果為「analyzed」(已分析)。
STEP 5:執行指令「sudo docker-compose exec api anchore-cli image content docker.io/library/ nginx:1.11.1」,查看映像檔內容,如圖6所示。
STEP 6:若要顯示漏洞資訊,可選擇「全部顯示(all)」、「僅顯示作業系統(os)相關」和「僅顯示非作業系統(non-os)相關」之漏洞。只須在指令「sudo docker-compose exec api anchore-cli image vuln docker.io/library/nginx:1.11.1 all」中選擇將最後的all改為os或non-os即可。執行後若有包含CVE漏洞,將會回傳CVE編號,如圖7所示。
STEP 7:可透過指令「sudo docker-compose exec api anchore-cli evaluate check docker.io/library/nginx:1.11.1」檢查該映像檔是否通過檢查,如未通過檢查,代表此執行此映像檔可能會帶來嚴重的安全問題,將顯示status:fail(狀態未通過)。反之,若有通過安全檢查,則顯示status:pass(狀態通過)。
模擬情境演練
小冠為北央公司的DevOps工程師,平時的業務範圍是協助公司做開發和部署,也因為工作的關係,他對於容器有相當程度的了解和興趣。然而,當小冠對於容器技術的了解越來越深入後,漸漸意識到容器並非完全的安全,在這之中也存在一些安全問題,因此小冠決定研究關於容器的安全問題。
小冠清楚地知道一個容器是由一個映像檔所啟動而成,所以一個容器是否安全有很大程度上取決於啟動該容器的映像檔是否安全,因此小冠決定以檢測映像檔為出發點。
俗話說「工欲善其事,必先利其器」。為了解映像檔是否安全,小冠於資安社團中請教了解容器安全的朋友,得知有幾款檢測容器映像檔的工具,包括Clair、Trivy和Anchore Engine,小冠發現Anchore Engine的功能較符合需求,因此他決定使用Anchore Engine並拿自己的部落格來檢測其映像檔的安全性。
小冠的部落格是使用目前連美國白宮(網址為「https://www.whitehouse.gov/」)都使用的內容管理系統WordPress。他是使用docker-compose自行建立在自己的伺服器上,其中包含MySQL和WordPress兩個映像檔,因此,以下步驟使用Anchore Engine針對這兩個映像檔做安全檢測。
首先,先檢查Anchore Engine的系統狀態,以及是否已將漏洞資訊都同步到本地端的資料庫,指令與圖4和圖5一致。事實上,映像檔也有版本之分,不同的版本因其包含的內容不一樣,檢測出來的結果可能不太一樣。小冠使用的是MySQL 5.7版和WordPress最新版的映像檔,因此使用「sudo docker-compose exec api anchore-cli image add docker.io/library/mysql:5.7」和「sudo docker-compose exec api anchore-cli image add docker.io/library/wordpress:latest」指令,將這兩個版本的映像檔加到Anchore Engine的檢測佇列中。
接著,執行「sudo docker-compose exec api anchore-cli image wait docker.io/library/mysql:5.7」和「sudo docker-compose exec api anchore-cli image wait docker.io/library/wordpress:latest」指令,檢查目前這兩個映像檔的檢測狀態。當映像檔檢測完成後,其Analysis Status(檢測狀態)欄位會顯示analyzed。
下一步確認這兩個映像檔已檢測完成後,就可以檢查這兩個映像檔中含有哪些的CVE漏洞資訊。事實上,漏洞有分等級,最高的為Critical(極為重要),次之的則為High(高),通常這兩個等級較容易影響一個映像檔是否通過檢測結果的依據。因此,先檢查MySQL 5.7版映像檔是否含有等級為Critical和High的漏洞,指令為「sudo docker-compose exec api anchore-cli image vuln docker.io/library/mysql:5.7 all | grep “Critical\|High”」,可以發現系統皆未回傳任何與Critical和High相關的漏洞資訊,指令和檢測結果如圖8所示。
接著,針對WordPress最新版的映像檔,執行指令「sudo docker-compose exec api anchore-cli image vuln docker.io/library/wordpress:latest all | grep “Critical\|High”」,從檢測結果中發現其有包含3個等級為Critical和10個等級為High的漏洞資訊,如圖9所示。
最後,執行「sudo docker-compose exec api anchore-cli evaluate check docker.io/library/mysql:5.7」和「sudo docker-compose exec api anchore-cli evaluate check docker.io/library/wordpress:latest」指令,檢查這兩個映像檔是否通過Anchore Engine工具的檢查。從檢測結果中可以發現,MySQL的5.7版本的映像檔檢測結果為通過(pass),而WordPress最新版本(latest)的映像檔檢測結果為未通過(fail)。
然而,因檢測結果不如小冠預期的兩個映像檔皆通過,小冠思考後過後認為,因WordPress的映像檔可能包含了3個等級為Critical和5個等級為High的漏洞。然而,Anchore Engine其實在功能上可以區分為檢測作業系統與非作業系統相關之漏洞,而在圖8和圖9的步驟中,小冠僅大範圍地針對全部的漏洞去做查找,因此,要確認這總共8個等級為High以上的漏洞資訊是屬於作業系統或非作業系統相關。
為此,小冠輸入「sudo docker-compose exec api anchore-cli image vuln docker.io/library/wordpress:latest os | grep Critical」和「sudo docker-compose exec api anchore-cli image vuln docker.io/library/wordpress:latest os | grep High」這兩個指令來檢測作業系統相關之漏洞。另外,也藉由指令「sudo docker-compose exec api anchore-cli image vuln docker.io/library/wordpress:latest non-os」檢測非作業系統相關之漏洞。
經指令回傳的結果發,現這個WordPress最新版映像檔的3個等級為Critical和5個等級為High的CVE漏洞皆與作業系統相關。反之,並無發現與非作業系統相關之漏洞。
透過這次的操作,小冠不僅了解Anchore Engine這個工具的基本操作外,也意外地發現自己使用的WordPress最新版本之映像檔原來存在一些CVE漏洞。然而,雖然經過Anchore Engine檢測後WordPress最新版本的映像檔因作業系統相關的套件庫包含Critical和High等級的漏洞資訊而未通過檢測,但是在非作業系統相關的套件庫的檢測卻沒有發現任何的CVE漏洞資訊。因此,小冠認為WordPress本身確定沒有漏洞,其作業系統的漏洞與實際上運行的WordPress服務並無直接相關,所以映像檔依然可以使用,與作業系統相關的漏洞在之後修補即可。
<本文作者:社團法人台灣E化資安分析管理協會(ESAM, https://www.esam.io/)令客思科技有限公司於2018年成立,由負責人蔡旻嶧率領成員們致力於台灣科技產業的發展,其服務項目包括雲端相關技術的開發與整合、GIS圖學技術、大型系統開發等等。>