有人說DockerHub上三成的映象包含漏洞?扯嗎不是?

軒墨發表於2017-09-19
本文講的是有人說Docker Hub上三成的映象包含漏洞?扯嗎不是【編者的話】到底Docker Hub上是否三成的映象存在漏洞?通過漏洞計算發現確實有高比例漏洞,對於管方映象遵循Docker的安全指南,如若是自建立映象,可找源倉庫或自行處理。但我們發現,這些漏洞中大部分是老映象。面對漏洞映象,我們可以採取本地措施,還可用Web安全審查進行檢查,如果想讓Docker更加安全,建議用dockerbench來評估。文中額外闡述了容器究竟有什麼用。

這個數字太神奇了!並不是因為這個比例過高或者過低,而是因為居然存在這個比例。既然存在(相對容易地)計算出這個比例的可能性,也就意味著存在(相對容易地)改善這個比例的可能性。

宣告:我是Docker官方人員,然而我寫這篇文章並未受到公司批准,所以最好帶著批判的思維來讀本文。

這個數字來源於BanyanOps的部落格

漏洞的計算

首先,來看看怎麼才能計算出原文中的資料。這過程比較簡單:

  • 獲取Docker登錄檔的一個列表
  • 下載列表中的映象
  • 檢查映象中的漏洞


這步驟看起來似乎太簡單,我們稍微深入下細節。

列舉映象

列舉官方的映象是容易的。這些映象是基於一個叫bashbrew的自動化系統構建而來的,使用的都是公佈於眾的方法。順便一提,這意味著如果你想重建官方的映象,做起來也會很容易。(記住那些方法中涉及一些blobs或者tar包,是在啟動的時候用到的;因而有時你要多費一點力,重建這些blobs或者tarbal)。

構建官方映象的方法在Github上的docker-library倉庫可以找到。

要列出其他的映象(即屬非官方的使用者和機構所有的映象)要困難點。Docker Hub目前沒有提供什麼方法來列舉他們,所以一個暫時可行的方法是搜尋一個十分寬泛的關鍵字,然後對其結果進行提取。當然,這需要一些抓取的工作;抓取到的結果可能會漏掉一些使用者的資料,但是你拿到的結果已經會十分接近了。(雖然這麼做肯定可行, 我也聽說新的登錄檔介面有一些十分好的特性,可以讓這一步完成起來容易點)。

下載映象

下載映象是一個繁瑣的任務。如果你想安安靜靜的做這件事情,執行一個docker的守護者程式,然後執行docker pull username/imagename:tag即可。

如果你想拿到容器的檔案系統的一個tar包,也很容易:只需要執行docker export username/imagename:tag就行。(記得把標準輸出重定向到其他地方,否則你的終端會抓狂的)

如果你不十分相信Docker的守護者程式,你可以檢查registry的介面(v1v2)並且通過介面來下載層,然後把層檔案重組成映象檔案。一些細節我想留給你自己去做,但是層檔案只是普通的tar包,你只需要在彼此之上解包(需要保持正確的順序)就可以重組成映象檔案。沒有什麼特別難的步驟;唯一需要留心的地方就是“留白”(whiteout)。“留白”是特殊的標記檔案,用來表明“此處曾經有檔案存在於此,但目前沒有了”。換句話說,如果一個層包含檔案/etc/foo.conf,但是之上的層把其刪除了,上一層就會包含一個/etc/.wh.foo.conf檔案,並且foo.conf不會出現在容器裡面。這個檔案相當於被留白檔案加上了蒙板。

我後來發現,了不起的Tianon已經為此寫好了一個指令碼,如果感興趣你可以去看看。

檢查映象

在這個階段你有幾件事情需要做。細節繁瑣,本文無法全部敘述;但是在一個全面的安全檢查中,下面這些步驟你可能需要做:

  • 執行yum-security或者類似的命令,保證在此刻沒有安全更新;
  • 或者更好的做法是:列舉出所有安裝的包及其版本,然後檢查軟體包在該版本是否包含漏洞;
  • 計算系統中的每一個檔案的hash值,然後去跟已知的有漏洞的檔案的hash集合去做比較;
  • 執行自動化工具(如chkrootkit)尋找可疑的檔案;
  • 執行一定數量的專門為某些漏洞而打造的漏洞測試。這些測試的目標是嘗試利用某些漏洞,然後告訴你,“你的系統有漏洞,因為我已經設法利用了這個漏洞”或者“我無法利用這個漏洞,所以你的系統很可能沒有此漏洞”。


事情到了容器的環境中變得很有趣,因為用Docker來自動化這些步驟容易且便捷。例如,你可以將你的漏洞分析工具包放在/tmp/toolkit中,然後對於每一個映象$I,執行docker run -v /tmp/toolkit:/toolkit $I /toolkit/runall.sh

(注意:這裡假設你的工具包是靜態連結並且/或者是自包含的,如不依賴你容器映象中的任何地方,因為這又可能讓你的工具包收到矇騙。我這裡主要想說的是,如果你想用一系列的測試來檢查你的容器映象,你可以用容器讓這個步驟變得很簡單,並且整個過程會更加的快速,因為對於每一個測試你不需要單獨做一個檢查的機器的拷貝)

提升指標

那麼在我們執行完這些測試,然後發現出奇高比例的映象包含有漏洞的包。我們怎麼來改善這個指標呢?

對於官方的映象,最容易的方法是遵循Docker的安全指南。以後隨著官方映象數的增長,Docker也會改善這個機制,達到自動提示官方映象的上游安全列表的效果。

對於非官方的映象,你可以檢查映象中的Author欄位:

$ docker inspect --format `{{.Author}}` bin/ngrep
Jerome Petazzoni <jerome@docker.com>



如果該映象是自動構建出來的,你可以找到其來源的倉庫,並且直接聯絡他們。

如果你直接受到了漏洞的影響,想事情進展的更加快速,你可以自己重建映象,並且/或者研究怎麼才能修復這個漏洞,然後提交一個包含相應修復的PR。這裡的意圖不是把安全的責任推卸到映象的使用者身上,而是讓有意願和有能力修復這些漏洞的人能對Docker映象的安全做貢獻。

在將來,這些步驟會完善,並且流式化。會有自動化的過程構建出來減少需要聯絡相關機構的煩瑣,然後儘量降低釋出包含漏洞補丁版本的時間。

但是30%還是太高了,對不對?

30%的“有漏洞的映象”可能聽起來非常多。我第一次聽到也是這麼想。但是如果你細看,你會發現其中一大部分的映象是老的映象,它們是__故意不被更新__的。

什麼?__故意不被更新__?

是的,並且對此有一些好的解釋。第一個是(其中的一部分)照顧其他的媒介。有的發行版想XYZ想在CD/DVD,網路安裝,VM映象,和容器都保持一致。第二個原因是(這也解釋了第一個原因)可重複的構建。

設想你有一個伺服器跑著12.04,但是你用一個新的Ubuntu 12.04的版本(更別提14.04)卻重現不出來。在更加深入的研究後發現,這個問題只存在於那些在某特定時間安裝的機器,其版本是12.04.02。如果一個容器映象有12.04.02的版本,你可以重現出這個bug;否則,你得從其他地方得到這個特定版本。這就是為什麼Docker Hub有很多老的映象,它們保持著發行時的狀態 – 同時包含當時發行時的安全問題。儘管這麼說,我們已經放置了安全警示說“歷史的映象 – 保持遠離”,所以我們比較希望這些映象在計算出這些安全的指標的時候不應該被包含進去。

讓我們希望下次有人在計算安全指標的時候他們能意識到這一點。

在本地採取措施

我們可能跑著有漏洞的映象!求救!怎麼辦,怎麼辦?

事情沒有其看起來那麼糟。當你(或者其他人)做完對於這些映象(官方的,公開的,私有的)的審查,結果是一個映象的列表(以一個唯一的hash串),並且包含“PASS”或者“FAIL”的狀態。(對於“FAIL”的映象,你可能想知道一些其為何不通過的細節,如:“好像有ShellShock/CVE-2014-7187和其他漏洞”或者“包含軟體包OpenSSL 1.0.1c / CVE-2014-0160”。)

Web規模的安全審查

你可以拿著這個列表,然後與你本地的映象做比較。這裡就是事情變得有趣的地方。根據本地映象和這個列表做一個簡單而廉價的匹配結果,你就馬上能知道你是否執行著有漏洞的映象。這可以很容易的擴充套件到成千上百萬的主機。

這也意味著事情可以很好的解耦:你的安全審查員不需要訪問你的生產環境(甚至不需要訪問你的開發環境中的系統)。他們甚至不需要要知道你執行著什麼映象:他們只需大面積的對映象做分析,然後得出結果給你。你甚至可以從幾個安全公司那裡拿到結果然後比較他們的結果。

我的映象在建立後修改過怎麼辦?

對於新手,你不應該這麼做。如果你像更新容器中的某些東西,你應該建立一個新的映象然後執行該新的映象。好吧,但是我已經這麼做了該怎麼辦?

那真是什麼都說不準,但是至少我們能知道你這麼做了。安全審查的一部分,你可以在執行的容器上執行docker diff來知道是否他們被修改了。(通常docker diff是沒有結果的。注意你已經用shell啟動了一個容器,或者在容器內執行過docker exec,你可能會看到少許的更改。但是生產環境的容器不應該出現任何的更改結果。)

專業的Tip:你甚至可以防止更改,通過在容器中使用--read-only的標記來達到這一點。這會讓容器的檔案系統只讀,保證docker diff的結果為空。

如果你想用一條命令來檢查所有的容器,可以執行:

docker ps -q | xargs -I {} dockr diff {}


(感謝@diogomonica提供命令!)

我已經構建了自定義的容器怎麼辦

如果你構建了自己的容器,我建議你把他們上傳到一個倉庫裡面。如果這是一個公共的,我們就會到最初討論的情形。如果這是一個私有的,讓我們看下一個部分!

私有的映象和登錄檔該怎麼辦?

如果你上傳的是私有的映象怎麼辦?如果你上傳的地方是一個本地的登錄檔,或者Docker Hub的企業版怎麼辦?

事情顯然變得更加複雜了。你可能會看見有人告訴你“設想ABC有CVE-XYZ的漏洞”如果他們從來沒有看到過映象ABC。

這裡是一些可能會發生的事情:

  • 安全提供商可以提供映象的掃描器,你可以用在自己的映象上;
  • 安全提供商可以更進一步,將其整合到Docker的登錄檔中。這可以通過分配讀許可權(訪問Docker Hub上的私有映象)或者部署前置(on-prem)的安全掃描器(對於Docker Hub企業版的情形)來實現。在兩個情形中,都能達到一旦映象上傳就會被自動掃描的效果,並且立即報告任何可能包含的漏洞。


結論

有兩點我想強調,因為我相信這能在安全領域產生好的結果。

  1. 得出數字是好的。一旦我們得到了量化的資料,我們可以提升他們。Docker對於安全問題十分延嚴肅,你可以很肯定我們會和社群及映象的維護者一期來改善這些量化資料。
  2. 有類似這樣的圍繞著Docker和Docker Hub的生態環境和社群,讓他們成為一個樹立標準的地方。正如Soloman在一些keynote裡面指出的,Docker裡面最重要的一點不是技術,而是讓人在某事上達成一致。


後一點意味著Docker現在有足夠的批評群體來校正橫向的工具(包括安全審查)來讓這個生態環境受益。其結果會是更加完善的安全機制,讓每一個人受益。

Docker注重安全

如果有Docker公司不在乎安全的印象,那真相離你就太遠了。正如上面指出的,我們有一個負責的披露安全的政策,並且我們總是很快的解決我們意識到的問題。沒有哪個軟體是沒有bug的。Docker也是由人類編寫出來的,即時他們有些人十分的了優秀,但是還是會犯錯。重要的是我們對待安全報告的嚴肅態度如何,我們解決這些問題的速度如何;我想我們在這些方面都一直做的很好。

如果你想讓你的Docker的環境更加安全,我推薦你看下dockerbench。我參與了其編寫,該軟體包含了一個自動化的評估工具可以用來評估Docker的主機,使用的是CIS Docker 1.6 Benchmark。它會檢查很多事情(如是否SELinux和AppArmor是啟用了的)然後生成一個報告。

這是Docker會推出或者參與的一大批軟體的第一批,目的是讓你可以在沒有Docker容器安全方面的Ph.d的證書的情形下,或者在沒有聘請一個Taylor Swift的情形下,安全地執行Docker。

並且,我們鼓勵公開的討論,安全的擔憂也不例外。Docker Library的倉庫裡面有一個十分有趣的有關於這個話題的討論

額外的提示

有人問我闡釋下容器究竟為什麼有用,如果我們不反覆的檢查我們執行的所有的東西的來源。這裡是一些例子:

  • 容器讓我們可以在沙箱環境下測試一些危險的操作(如著名的curl ... | sh),並且可以檢視到底能產生結果,這得益與docker diff
  • 容器讓我們可以在沙箱環境下測試一些危險的操作(比如一個商用軟體的install.sh),並且可以檢視到底能產生結果,這得益與docker diff
  • 容器讓我們可以在沙箱環境下測試一些危險的操作(如安裝一個npm,pip,gem等等的包,但是我們不清楚其來源),並且可以檢視到底能產生結果,這得益與docker diff
  • 容器讓我們可以在沙箱環境下測試一些危險的操作(如安裝一個deb,rpm或者其他的發行版的包),並且可以檢視到底能產生結果,這得益與docker diff
  • 容器讓我們可以在沙箱環境下測試一些危險的操作(如安裝一個危險的squid包),並且可以檢視到底能產生結果,這得益與docker diff


我猜想你能看出這個模式。僅僅因為事情以一種熟悉的形式呈現給你並不代表它們是安全的。但是我們可以使用Docker來提升安全性。

原文連結:Someone said that 30% of the images on the Docker Registry contain vulnerabilities(翻譯:鍾最龍)

原文釋出時間為:kurtzhong
本文作者:kurtzhong
本文來自雲棲社群合作伙伴DockerOne,瞭解相關資訊可以關注DockerOne。
原文標題:有人說Docker Hub上三成的映象包含漏洞?扯嗎不是?


相關文章