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