得物容器安全技術探索與落地實踐
1、前言
得物服務早期主要是運行在ECS上,隨著容器技術的日趨成熟,容器在降本增效、易于部署、靈活性等方面的優(yōu)勢開始顯現(xiàn)。目前,得物已基本完成全域容器化,容器已成為支撐得物技術發(fā)展的重要基礎設施。
隨著基礎設施發(fā)生變化,業(yè)務在集成、交付、編排等方面都會與過往存在明顯的不同,同時會伴隨新的安全風險。如何發(fā)現(xiàn)和應對這些新的安全風險,本文將從技術和實踐兩個角度與讀者進行分享和交流。
2、容器是基礎設施
容器化應用在大體上可以分為兩部分:構建時、運行時。
2.1 容器虛擬化技術與其他虛擬化技術的主要差別
容器是典型的“操作系統(tǒng)級虛擬化”,它沒有獨立的虛擬硬件,也不需要安裝guest OS,這是它跟其他虛擬化技術的主要區(qū)別。
全虛擬化:在Server OS之上會有一層hypervisor來實現(xiàn)虛擬化,然后由hypervisor虛擬化出虛擬硬件,用戶再在虛擬硬件之上安裝guest OS。典型的像:vmware workstation、kvm。
裸金屬:沒有Server OS,只有hypervisor。上電后,系統(tǒng)引導過了BIOS之后,將直接引導到hypervisor,將對硬件的控制權交由hypervisor,由hypervisor虛擬化出虛擬硬件,用戶再在虛擬硬件之上安裝guest OS。典型的像:vmware ESXi。
操作系統(tǒng)級虛擬化:多個容器共用一個kernel,沒有獨立的虛擬硬件也不用安裝guest OS,容器間通過cgroup以及namespace來分別實現(xiàn)資源限制(例如:將某個容器的cpu、內(nèi)存的閾值限定住)和資源隔離(例如:不同容器內(nèi)的應用程序都可以bind同一個端口、不同容器內(nèi)的ps看到的進程列表都是從1開始。在容器內(nèi)的應用程序看來,就好像自己獨占這臺機器一樣)。典型的像:docker、lxc、openVZ。
2.2 鏡像結構
- Linux運行基礎
首先,需要先掌握兩個基礎知識:Linux的bootfs和rootfs
Linux系統(tǒng)要啟動運行,至少需要兩個文件系統(tǒng):
bootfs:包含boot-loader、kernel、grub。bios過了之后bios會拉起內(nèi)核(bootfs),并將對硬件的控制權轉交給操作系統(tǒng)。用戶一般不會去修改bootfs,但也有例外,例如用戶自己編譯內(nèi)核并用新內(nèi)核啟動。
rootfs:包含經(jīng)典的Linux目錄結構:
不同的系統(tǒng)組件、應用程序、lib文件、配置文件,都是包含在rootfs中。不同的Linux發(fā)行版的區(qū)別,主要是集中在rootfs。
- 鏡像文件結構基礎
對于同一臺宿主機上的不同容器來說,容器間共享kernel,但各容器內(nèi)包含的發(fā)行版以及應用程序卻可以是不同的,也就是說:bootfs相同,但rootfs卻是可以不同。我們通過dockerfile構建不同的鏡像,實際上就是在控制rootfs的內(nèi)容,讓不同的容器運行不同的程序。
docker hub上有很多基礎鏡像,我們可以基于基礎鏡像疊加我們自己的應用,然后再生成一個新的鏡像。實際上當我們使用dockerfile去構建新的鏡像時,就是在基礎鏡像的基礎上再增加一層,也就是layer,這個layer里包含的是你的應用相關的內(nèi)容,例如:你的應用程序、配置文件、環(huán)境變量等。
- 剖析舉例
此處以一個docker鏡像為例進行說明。
先通過docker pull?命令拉取一個鏡像,然后使用docker save命令將鏡像保存為tar.gz文件,最后再解壓tar.gz,得到鏡像里的文件列表。
拉取鏡像:
保存并解壓鏡像:
分析鏡像:
從manifest.json中可以看出,該鏡像一共由4層組成。
第一層,即1288696addccc4013c5bcf61c1b6c38128a7214a0942976792918b51912d90f7/layer.tar解壓出來的內(nèi)容如下,可見都是最最基礎的,諸如cp、基礎庫:(因篇幅原因,只展示該layer.tar解壓出來的部分文件列表)
第二層,即
f8ce18fff435609b86079966a73814c1fe976422930ad0e6b3d27725baff4bab/layer.tar解壓出來的內(nèi)容如下:
第三層,即f40081c28f00b0f31720fad1c99acaee5186173be08f060ac420f5358a870e16/layer.tar解壓出來的內(nèi)容如下:(因篇幅原因,只展示該layer.tar解壓出來的部分文件列表)
第四層,即4261ff25d711bed03d33a361482aeacff23027596d9d1c18f7223e1c4c87b42c/layer.tar解壓出來的內(nèi)容如下:
能夠看到,從第一層到第三層解壓出來的文件,都是基礎bash、運行時依賴庫、配置文件、證書等。第四層解壓出來的,才是最終的應用程序。
3.新技術帶來的挑戰(zhàn)
相較于之前的ECS部署方式,容器部署方式帶來了很多的優(yōu)點:降本增效、資源隔離、資源限制、易于部署等。但新引入的基礎設施,例如:鏡像倉庫、鏡像/dockerfile、k8s宿主機、k8s、docker運行時、容器,也會隨之帶來新的安全風險,例如:鏡像投毒、不安全鏡像、k8s宿主機/k8s/docker不合規(guī)、k8s宿主機/k8s/docker高危漏洞、容器逃逸等。
3.1 鏡像投毒
什么是鏡像投毒?
大家知道,docker有個好處就是“開箱即用”,比如說:我要一個mysql的環(huán)境,在沒有docker之前呢,我們一般是找臺機器,然后把mysql裝上,改配置,最后啟動。現(xiàn)在不用這樣了,直接拉取一個mysql鏡像,然后把容器運行起來,兩條命令就可以搞定。是不是很高效?
正是基于這種“開箱即用”帶來的便利性,我們在下載到鏡像后很少有人會去檢查下這個鏡像是不是安全的,大部分開發(fā)同學都是直接使用。黑客正是通過對開發(fā)同學的這種心理活動的揣摩和利用,會上傳一些攜帶漏洞、病毒、后門、挖礦程序的鏡像到dockerhub,這個過程就叫做鏡像投毒。只要你下載了帶毒的鏡像并創(chuàng)建容器,就會在不知不覺中引入安全風險。舉幾個例子:
例子一:黑客裝個挖礦程序到鏡像內(nèi),并設置成autorun,那么你在不知不覺中就成了黑客的礦機。
例子二:黑客裝個后門程序到鏡像內(nèi),并設置成autorun,那么黑客就可以隨時隨地控制你的容器,更嚴重的甚至可以通過一些高危漏洞實現(xiàn)容器逃逸而進一步控制你的宿主機。
想想都挺可怕。那怎么破呢?
下載帶OFFICIAL標志的,表明是經(jīng)過官方認證的。同時做好常態(tài)化的鏡像風險掃描工作,及時發(fā)現(xiàn)并清除安全風險。
如果找不到帶OFFICIAL標志的,則可以看STARS數(shù),選擇STARS數(shù)大的。
3.2 不安全鏡像
鏡像內(nèi)可能會攜帶弱點:漏洞、病毒/木馬/后門、敏感信息泄漏、弱口令、dockerfile不合規(guī)等安全風險。
有些弱點是系統(tǒng)自帶的(例如:python run-time漏洞),有些弱點是我們自己無意間引入的(例如:使用了不安全的fastjson版本、被投毒鏡像攜帶的病毒、敏感信息明文等),有些漏洞是新報出來的。
3.3 k8s宿主機/k8s/docker不合規(guī)
什么是合規(guī)?可以理解成“符合規(guī)范”,符合國家(國標)或行業(yè)(行標)對網(wǎng)絡安全的規(guī)范要求。
k8s宿主機,基本上采用的都是Linux系統(tǒng),所以可以采用Linux等級保護L2/L3的檢測規(guī)范。
k8s/docker,采用CIS benchmark居多。
docker參考:https://www.cisecurity.org/benchmark/docker
k8s參考:https://www.cisecurity.org/benchmark/kubernetes
3.4 k8s宿主機/k8s/docker高危漏洞
是軟件就難免會有漏洞,不管是OS kernel,亦或是組件庫,還是應用程序。
k8s&docker的安全漏洞:
3.5 容器逃逸
什么是逃逸?簡單來說就是:容器獲得了它本不該擁有的容器宿主機系統(tǒng)資源的訪問權限。
容器內(nèi)的應用,由于Linux kernel namespace機制的限制,是訪問不到宿主機的系統(tǒng)資源(進程、/proc、網(wǎng)絡信息、文件系統(tǒng)等)的。但通過一些漏洞或者錯誤配置,則可以實現(xiàn)容器逃逸,等同于提權,危害可想而知。
4.如何應對這些新的安全挑戰(zhàn)
大體上可以分為兩部分:構建時、運行時。
4.1 構建時
這個階段覆蓋的資產(chǎn)主要有鏡像倉庫以及鏡像。
主要的目的是要確保:
(1)無高危且易于利用的漏洞
(2)無病毒/后門/木馬
(3)合規(guī)
(4)無敏感信息泄漏(例如明文密碼、token)
(5)無弱口令配置
落地實踐:
鏡像掃描器與鏡像倉庫聯(lián)動。當鏡像PUSH時,會對鏡像進行實時掃描。
對鏡像倉庫上的所有鏡像進行日常常態(tài)化掃描。
安全核心能力方面:
提供漏洞掃描能力。支持對web漏洞、系統(tǒng)漏洞的檢測。
提供病毒/木馬/后門掃描能力。支持對Linux病毒、Windows病毒的檢測。
提供敏感信息檢測能力。
提供弱口令檢測能力。
提供IaC檢測能力。支持對dockerfile、k8s yaml進行安全掃描。
4.2 運行時
這個階段覆蓋的資產(chǎn)主要有k8s宿主機、k8s&docker、容器。
主要的目的是要確保:
1、能加固的都盡量加固掉。包括:漏洞、不合規(guī)項、弱口令
2、要能及時發(fā)現(xiàn)黑客的入侵行為。
為什么是這兩個目的?黑客沒來攻擊之前,我們要盡可能地把系統(tǒng)加固得更牢固,抬高黑客的攻擊難度;倘若還是被黑客突破進來了,那黑客肯定會執(zhí)行些命令,黑客一般來說會有以下幾個滲透攻擊階段的典型行為,通過事先對黑客進行行為建模,只要某個用戶在系統(tǒng)上的行為落在“黑客行為模型”內(nèi),就判定為入侵行為。
運行時整體框架:
會在每臺k8s宿主機上,以daemonset方式啟動一個安全容器并掛在k8s下。這個安全容器內(nèi)部跑兩個引擎:
引擎一:基線檢測引擎。它主要負責漏洞掃描、合規(guī)檢測、本地爆破,最終目的是為了給運營同學進行系統(tǒng)加固提供依據(jù)。同時,該引擎也支持事中SCA(軟件成份分析),能夠根據(jù)軟件供應鏈漏洞快速梳理出受影響的容器資產(chǎn),以應對頻發(fā)的軟件供應鏈安全事件。
引擎二:入侵檢測引擎。它主要負責采集系統(tǒng)上的關鍵指標(進程信息、進程樹、文件變更事件、網(wǎng)絡連接、fd、歷史命令、用戶登錄等信息),然后由平臺側的Flink任務進行預處理,最后進模型匹配。最終目的是為了發(fā)現(xiàn)黑客入侵行為,為及時止血提供線索。
由于是部署在k8s宿主機上,需要安全容器具備較高的穩(wěn)定性,避免出現(xiàn)資損。
穩(wěn)定性方面:
以平行容器方式托管在k8s下,通過Linux namespace和cgroup來實現(xiàn)資源隔離和資源限制。cpu使用率通過k8s睿頻技術進行動態(tài)調(diào)配,例如:reqeust=0.02c limit=2c,安全容器默認只占0.02c,當業(yè)務容器不使用cpu時,則此時安全容器最多可以使用2c的cpu;而當業(yè)務容器需要cpu資源時,安全容器會主動釋放cpu時間片。
版本更新借助k8s框架實現(xiàn)。灰度升級時使用nodeSelect+打標,實現(xiàn)分批升級。
完善監(jiān)控指標,觸發(fā)門限后進行告警。
定期進行穩(wěn)定性演練。
5、思考和總結
總體指導方針。圍繞“重檢測、輕管控、快響應”的九字方針開展工作,在效率和安全之間尋求平衡,在為業(yè)務保駕護航的同時,盡可能小地影響業(yè)務。
安全能力實戰(zhàn)化。攻防是一個持續(xù)博弈和對抗的過程,每年都會有新的威脅、新的攻擊手法出現(xiàn),通過定期的實戰(zhàn)化演練(例如:紅藍對抗、白帽滲透測試)來檢驗安全能力的水位。跳出容器來看容器,多方思考和學習,才能拿到理想的結果。未知攻,焉知防?;其實反過來看,也同樣成立:未知防,焉知攻?。最終需要做到既知攻,亦知防,才能把事情做到自己認知范圍內(nèi)的最好程度。?