在當(dāng)前不斷增長(zhǎng)的基于云計(jì)算的IT市場(chǎng),對(duì)虛擬化技術(shù)有大量的需求。遺憾的是大多數(shù)的虛擬化解決方案不足以去滿足研發(fā)需求,全虛擬化解決方案產(chǎn)生的費(fèi)用會(huì)變成可擴(kuò)展的基礎(chǔ)設(shè)施的隱含負(fù)擔(dān)。
Docker允許開發(fā)人員和系統(tǒng)管理員為解決服務(wù)實(shí)際業(yè)務(wù)需求所需的應(yīng)用和服務(wù)能夠無(wú)縫部署容器以減少開銷。無(wú)論怎樣,因?yàn)镈ocker利用同一內(nèi)核作為主系統(tǒng)以減少所需資源,容器如果沒有進(jìn)行充分配置則會(huì)明顯的暴露安全問題。
下面逐項(xiàng)表明的強(qiáng)化措施可以保證在各自環(huán)境中提高容器的安全性。需要注意本提出方案僅適用去Linux Docker容器的部署在基于Linux的主機(jī)上,在編寫本文時(shí)使用Docker最新的Release版本 (1.4.0, commit 4595d4f, dating 11/12/14)。
以下內(nèi)容摘自Jér?me Petazzoni [1]和 Daniel J Walsh [2]發(fā)布的ppt和視頻。本文的目標(biāo)是如何具體地在Docker中實(shí)施。
注:大多數(shù)建議的命令行選項(xiàng)可以在一個(gè)類似于Dockerfile中存儲(chǔ)并用于自動(dòng)化鏡像的構(gòu)建。
(譯者按:原文17項(xiàng)措施以表格形式呈現(xiàn),由于編輯器原因,這里將改為列表形式表述)
1.Docker鏡像
Docker 1.3 現(xiàn)在支持?jǐn)?shù)字簽名[3]來(lái)確認(rèn)官方倉(cāng)庫(kù)鏡像的起源和完整性。因該功能仍在開發(fā)中所以Docker將拋出警告但不會(huì)阻止鏡像的實(shí)際運(yùn)行。
通常確保鏡像只從受信庫(kù)中檢索并且不使用—insecure-registry=命令項(xiàng)。
2.網(wǎng)絡(luò)命名空間
在默認(rèn)情況下,Docker REST API用來(lái)控制容器通過(guò)系統(tǒng)Docker守護(hù)進(jìn)程是唯一能夠通過(guò)Unix域套接字的方式暴露出來(lái)。在Docker上開啟一個(gè)TCP端口(即 當(dāng)引導(dǎo)Docker守護(hù)進(jìn)程時(shí)必須使用 -H 選項(xiàng)綁定地址)將允許任何人通過(guò)該端口訪問容器,有可能獲得主機(jī)上的root訪問權(quán)限以及在某些場(chǎng)景下本地用戶所屬的Docker組。
3.日志和審核
收集和歸檔與Docker相關(guān)的安全日志來(lái)達(dá)到審核和監(jiān)督的目的。從host[8],可以使用下面的命令來(lái)訪問容器外的日志文件:
docker run -v /dev/log:/dev/log /bin/sh
使用Docker命令內(nèi)置:
docker logs ... (-f to follow log output)
日志文件也可以從持續(xù)存儲(chǔ)導(dǎo)出到一個(gè)使用壓縮包里面:
docker export ...
4.SELinux 或 AppArmor
Linux的內(nèi)部安全模塊,例如通過(guò)訪問控制的安全策略來(lái)配置安全增強(qiáng)型Linux(SELinux)和AppArmor,從而實(shí)現(xiàn)強(qiáng)制性的訪問控制(MAC)一套有限的系統(tǒng)資源的限制進(jìn)程,如果先前已經(jīng)安裝和配置過(guò)SELinux,那么它可以使用setenforce 1在容器中被激活。Docker程序的SELinux支持是默認(rèn)無(wú)效的,并且需要使用—selinux功能來(lái)被激活。通過(guò)使用新增的—security-opt來(lái)加載SELinux或者AppArmor的策略對(duì)容器的標(biāo)簽限制進(jìn)行配置。該功能已經(jīng)在Docker版本1.3[9]中介紹過(guò)。例如:
docker run --security-opt=secdriver:name:value -i -t centos bash
5.守護(hù)特權(quán)
不要使用--privileged命令行選項(xiàng)。這本來(lái)允許容器來(lái)訪問主機(jī)上的所有設(shè)備,并為容器提供一個(gè)特定的LSM配置(例如SELinux或AppArmor),而這將給予如主機(jī)上運(yùn)行的程序同樣水平的訪問。避免使用--privileged有助于減少主機(jī)泄露的攻擊面和潛力。然而,這并不意味著程序?qū)]有優(yōu)先權(quán)的運(yùn)行,當(dāng)然這些優(yōu)先權(quán)在最新的版本中還是必須的。發(fā)布新程序和容器的能力只能被賦予到值得信任的用戶上。通過(guò)利用-u選項(xiàng)盡量減少容器內(nèi)強(qiáng)制執(zhí)行的權(quán)限。例如:
docker run -u -it /bin/bash
Docker組的任何用戶部分可能最終從容器中的主機(jī)上獲得根源。
6.cgroups
為了防止通過(guò)系統(tǒng)資源耗盡的DDoS攻擊,可以使用特定的命令行參數(shù)被來(lái)進(jìn)行一些資源限制。
CPU使用率:
docker run -it --rm --cpuset=0,1 -c 2 ...
內(nèi)存使用:
docker run -it --rm -m 128m ...
存儲(chǔ)使用:
docker -d --storage-opt dm.basesize=5G
磁盤I/O:
目前不支持Docker。BlockIO*屬性可以通過(guò)systemd暴露,并且在支持操作系統(tǒng)中被用來(lái)控制磁盤的使用配額。
7.二進(jìn)制SUID/GUID
SUID和GUID二進(jìn)制文件不穩(wěn)定的時(shí)候容易受到攻擊,而這個(gè)時(shí)候是很危險(xiǎn)的,,導(dǎo)致任意代碼執(zhí)行(如緩沖區(qū)溢出),因?yàn)樗鼈儠?huì)進(jìn)程的文件所有者或組的上下文中運(yùn)行。如果可能的話,禁止SUID和SGID使用特定的命令行參數(shù)來(lái)降低容器的功能。
docker run -it --rm --cap-drop SETUID --cap-drop SETGID ...
另一選擇,可以考慮運(yùn)用通過(guò)安裝有nosuid屬性的文件系統(tǒng)來(lái)移除掉SUID能力。
最后一個(gè)選擇是從系統(tǒng)中徹底刪除不需要的SUID和GUID二進(jìn)制文件。這些類型的二進(jìn)制文件可以在Linux系統(tǒng)中運(yùn)行以下命令而找到:
find / -perm -4000 -exec ls -l {} ; 2>/dev/null
find / -perm -2000 -exec ls -l {} ; 2>/dev/null
可以使用類似于下面的[11]命令將SUID和GUID文件權(quán)限刪除然后:
sudo chmod u-s filename sudo chmod -R g-s directory
8.設(shè)備控制組(/dev/*)
如果需要,使用內(nèi)置的設(shè)備選項(xiàng)(不使用-v與--privileged參數(shù))。此功能在推出1.2版本[12]。
例如(聲卡使用):
docker run --device=/dev/snd:/dev/snd …
9.服務(wù)和應(yīng)用
如果一個(gè)Docker容器有可能被泄露,為了減少橫向運(yùn)動(dòng)的潛力,考慮隔離極易受影響的服務(wù)(如在主機(jī)或虛擬機(jī)上運(yùn)行SSH服務(wù))。此外,不要運(yùn)行容器內(nèi)不受信任的特許操作的應(yīng)用程序。
10.安裝項(xiàng)
當(dāng)使用本機(jī)容器庫(kù)時(shí)(即libcontainer)Docker就會(huì)自動(dòng)處理這個(gè)。
但是,使用LXC容器庫(kù)時(shí),敏感的安裝點(diǎn)最好通過(guò)運(yùn)用只讀權(quán)限來(lái)手動(dòng)安裝,其中包括:
/sys
/proc/sys
/proc/sysrq-trigger
/proc/irq
/proc/bus
安裝權(quán)限應(yīng)在以后刪除,以防止重新掛載。
11.Linux內(nèi)核
使用系統(tǒng)提供的更新工具來(lái)確保內(nèi)核是實(shí)最新的(如apt-get,yum,等)。過(guò)時(shí)的內(nèi)核可能更脆弱,并且被暴露一些漏洞。使用GRSEC或PAX來(lái)加強(qiáng)內(nèi)核,即例如對(duì)內(nèi)存破壞的漏洞來(lái)提供更高的安全性。
12.用戶命名空間
Docker不支持用戶的命名空間,但是目前的一個(gè)開發(fā)[13]功能。UID映射由LXC程序驅(qū)動(dòng),但在本機(jī)libcontainer庫(kù)中不被支持。該功能將允許Docker程序像一個(gè)沒有特權(quán)的用戶在主機(jī)上運(yùn)行,但顯示出來(lái)的是和在容器中運(yùn)行的一樣。
13.libseccomp(和seccomp-bpf 擴(kuò)展)
libseccomp庫(kù)允許在基于一個(gè)白名單的方法上限制Linux內(nèi)核的系統(tǒng)調(diào)用程序的使用。對(duì)于系統(tǒng)操作來(lái)說(shuō),不是很重要的系統(tǒng)調(diào)用程序,最好被禁用,以防止被破壞的容器被濫用或誤用。
此功能目前工作正在進(jìn)行中(LXC驅(qū)動(dòng)程序中已經(jīng)有了,但是在libcontainer中海沒有完成,雖然現(xiàn)在是默認(rèn)值)。使用LXC驅(qū)動(dòng)程序[14]來(lái)重啟Docker程序:
docker -d -e lxc
如何生成seccomp配置的說(shuō)明都在“的contrib”[15]文件夾中的Docker GitHub的資源庫(kù)。以后可以用下面的命令來(lái)創(chuàng)建一個(gè)基于Docker容器的LXC:
docker run --lxc-conf="lxc.seccomp=$file"
14.性能
只要可能,就將Linux性能降低到最小。Docker默認(rèn)的功能包括:chown, dac_override, fowner, kill, setgid, setuid, setpcap, net_bind_service, net_raw, sys_chroot, mknod, setfcap, and audit_write.
從控制行來(lái)啟動(dòng)容器時(shí),可以通過(guò)下述來(lái)進(jìn)行控制:
--cap-add= 或者--cap-drop=.
例如:
docker run --cap-drop setuid --cap-drop setgid -ti /bin/sh
15.多租環(huán)境
由于Docker容器內(nèi)核的共享性質(zhì),責(zé)任分離在多租戶環(huán)境中不能安全地實(shí)現(xiàn)。建議容器在那些沒有其它的目的,也不用于敏感操作的主機(jī)上運(yùn)行??伎梢詰]通過(guò)Docker控制來(lái)將所有服務(wù)移動(dòng)到容器中。如果可能的話,通過(guò)使用--icc= false將跨容器通信降到最低,并必要時(shí)指定-link與Docker運(yùn)行,或通過(guò)—export=port,不在主機(jī)上發(fā)布,而在容器上暴露一個(gè)端口。相互信任的容器的映像組來(lái)分離機(jī)器[17]。
16.完全虛擬化
使用一個(gè)完整的虛擬化解決方案包含Docker,如KVM。這將阻止一個(gè)內(nèi)核漏洞在Docker鏡像中被利用導(dǎo)致容器擴(kuò)為主系統(tǒng)。
Docker鏡像能夠嵌套來(lái)提供該KVM虛擬層,參考Docker-in-Docker utility [18]中所示。
17.安全審核
對(duì)你的主系統(tǒng)和容器定期進(jìn)行安全審核以查明錯(cuò)誤配置或漏洞,這些能使你的系統(tǒng)損壞。