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