Docker安全部署的17條建議
本文作者從Docker鏡像、網絡命名空間、日志和審核、守護進程特權、SELinux、二進制SUID/GUID、設備控制組、服務和應用、 Linux內核、用戶命名空間、libseccomp等方面給出了自己的建議,可以一讀。
當前持續增長的云計算市場對虛擬化技術有著強烈的需求。遺憾的是,大多數的虛擬化解決方案不夠靈活,無法滿足研發需求,且使用全虛擬化解決方案的潛在開銷變成了制約基礎設施擴展性的負擔。
Docker讓開發和運維人員能無縫地部署容器,用于運行業務所需的應用與服務,從而減少這類開銷。然而,因為Docker與宿主系統使用同一內核,配置不當的容器將造成重大安全隱患。
以下列表每一條在相關容器環境內對提高其安全性提出了建議。需要注意的是,這些方案僅適用于部署在Linux主機上的Docker容器,并使用最新的Docker版本(1.4.0,commit 4595d4f,日期 11/12/14)。
以下部分內容參考了Jér?me Petazzoni[1]和Daniel J Walsh[2]的文章。本文旨在對他們的建議進行補充,并說明如何在Docker具體實現。
注:大多數建議的命令行選項可以在Dockerfile中以類似的方式保存和使用,實現自動化鏡像構建。(譯者注:原文17項建議以表格形式呈現,由于編輯器原因,這里將改為列表形式表述)
1. Docker鏡像
Docker 1.3開始支持使用數字簽名[3]來驗證官方倉庫鏡像的來源和完整性。該功能仍在開發中,因此Docker只對(譯者注:沒有數字簽名的)鏡像發出警告信息但不會阻止其實際運行。此外,這點對非官方鏡像不適用。一般情況下,我們要確保只從受信任的庫中獲取鏡像,并且不要使用--insecure-registry=[]參數。
2. 網絡命名空間[4]
默認情況下,Docker守護進程暴露出來用于控制容器的REST API只能在本地通過Unix Domain Socket進行訪問。在一個TCP端口上運行Docker(比如,啟動Docker守護進程時使用-H選項強制綁定地址)將允許任何可以訪問該端口的人獲取容器的訪問權限,甚至在本地用戶屬于Docker組的某些情況下有可能獲得宿主的root權限。[5]
在允許通過TCP訪問守護進程時,確保通訊使用SSL加密[6]和權限控制能有效地防止未授權用戶與其進行交互。
可在Docker的標準網絡橋接接口docker0上啟用內核防火墻iptables規則,用于加強這些控制。
例如,可以使用以下iptables過濾器[7]限制Docker容器的源IP地址范圍與外界通訊。iptables -t filter -A FORWARD -s <source_ip_range> -j REJECT --reject-with icmp-admin-prohibited
3. 日志和審核
收集并歸檔與Docker相關的安全日志來達到審核和監控的目的。可以在宿主[8]上使用以下命令在容器外部訪問日志文件:docker run -v /dev/log:/dev/log <container_name> /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-enabled來啟用。
容器的標簽限制可使用新增的—-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有助于減少攻擊面和可能的宿主威脅。但是,這并不意味著運行守護進程時不需要root權限,在最新版本中這仍然是必須的。
啟動守護進程和容器的權限只能賦予受信任的用戶。
可通過使用-u選項弱化容器內訪問權限。例如:
docker run -u <username> -it <container_name> /bin/bash
Docker組的任何用戶部分可能最終從容器中的主機上獲得根源。
6. cgroups[10]
為了防止通過耗盡系統資源引發拒絕服務(DoS)攻擊,可使用特定的命令行參數被來啟用一些資源限制。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不支持。通過systemd暴露的BlockIO*特性可以在支持的操作系統中用來控制磁盤使用配額。
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/*)
如果需要,使用內置的--device選項(-v參數不要與--privileged一起使用)。此功能在1.2版本[12]引入。例如(使用聲卡):
docker run --device=/dev/snd:/dev/snd …
9. 服務和應用
如果Docker容器有可能被入侵,為了減少橫向運動的可能,應考慮隔離敏感服務(如在宿主或虛擬機上運行SSH服務)。此外,不要在容器內使用root權限運行不受信任的應用。
10. 掛載點
使用原生容器庫(如libcontainer)時,Docker會自動處理這項。但是,使用LXC容器庫時,敏感的掛載點最好以只讀權限手動掛載,包括:
/sys掛載權限應在之后移除,以防止重新掛載。
/proc/sys
/proc/sysrq-trigger
/proc/irq
/proc/bus
11. Linux內核
使用系統提供的更新工具(如apt-get、yum等)確保內核是最新的。過時的內核相比已公開的漏洞危險性更大。使用GRSEC或PAX來強化內核,例如針對內存破壞漏洞提供更高的安全性。
12. 用戶命名空間
Docker不支持用戶命名空間,但它是目前正在開發[13]的功能。現在,LXC驅動支持UID映射,但原生的libcontainer庫不支持。該功能允許Docker守護進程以非特權用戶身份運行在宿主上,但在容器內看起來像是以root運行。
13. libseccomp(和seccomp-bpf 擴展)
libseccomp庫允許基于白名單方法來限制Linux內核的系統調用程序的使用。最好禁用受攻擊容器中對于系統操作不是很重要的系統調用程序,以防止其被濫用或誤用。此功能目前正在開發中(LXC驅動中存在,但是現在默認的libcontainer中沒有)。使用LXC驅動程序[14]來重啟Docker程序:
docker -d -e lxc
如何生成seccomp配置的說明都在GitHub倉庫的“contrib”[15]文件夾。之后可用下面的命令來創建一個以LXC為基礎的Docker容器:
docker run --lxc-conf="lxc.seccomp=$file" <rest of arguments>
14. 能力[7]
盡可能降低Linux能力。Docker默認的能力包括:chown、dac_override、fowner、kill、setgid、setuid、setpcap、net_bind_service、net_raw、sys_chroot、mknod、setfcap、和audit_write`。在命令行啟動容器時,可以通過--cap-add=[]或--cap-drop=[]進行控制。
例如:
docker run --cap-drop setuid --cap-drop setgid -ti <container_name> /bin/sh
此功能在Docker 1.2版本引入[16]。
15. 多租戶環境
由于Docker容器內核的共享性質,無法在多租戶環境中安全地實現責任分離。建議將容器運行在沒有其它目的,且不用于敏感操作的宿主上。可以考慮將所有服務遷移到Docker控制的容器城。可能的話,設置守護進程使用--icc=false,并根據需要在docker run時指定-link,或通過—-export=port暴露容器的一個端口,而不需要在宿主上發布。
將相互信任的容器的組映射到不同機器上[17]。
16. 完全虛擬化
使用一個完全虛擬化解決方案來容納Docker,如KVM。如果容器內的內核漏洞被發現,這將防止其從容器擴大到宿主上。如同Docker-in-Docker工具[18]所示,Docker鏡像可以嵌套來提供該KVM虛擬層。
17. 安全審核
定期對你的宿主系統和容器進行安全核查,以找出可能導致系統被入侵的錯誤配置或漏洞。參考文獻:
[1] Docker, Linux Containers (LXC), and security (August, 2014). Jér?me Petazzoni. [presentation slides]
[2] Docker and SELinux (July, 2014). Daniel Walsh [video]
[3] Docker 1.3: Signed Images, Process Injection, Security Options, Mac shared directories (October, 2014). Scott Johnston
[4] Exploring LXC Networking (November, 2013). Milos Gajdos.
PaaS under the hood, episode 1: kernel namespaces (November, 2012). Jér?me Petazzoni.
Exploring networking in Linux containers (January, 2014). Milos Gajdos. [presentation slides]
[5] How to grant rights to users to use Docker in Fedora (October 2014). Daniel Walsh
[6] Running Docker with https. [Docker documentation]
[7] security suggestions when running malicious code, Google Groups (August, 2013). Jér?me Petazzoni
[8] Monitoring Images and Containers. [Red Hat documentation]
[9] Docker 1.3: Signed Images, Process Injection, Security Options, Mac shared directories (October, 2014). Scott Johnston
[10] Resource management in Docker (September, 2014). Marek Goldmann.
Gathering LXC and Docker Containers Metrics (October, 2013). Jér?me Petazzoni.
[11] Removing SUID and SGID flags off binaries (August, 2008). Eric Thern.
[12] Announcing Docker 1.2.0 (August, 2014). Victor Vieux.
[13] Having non-root privileges on the host and root inside the container #2918 (November, 2013). [GitHub issue]
Support for user namespaces #4572 (March 2014). [GitHub issue]
Proposal: Support for user namespaces #7906 (September, 2014). [GitHub issue]
Issue 8447: syscall, os/exec: Support for User Namespaces (July, 2014) [Google Code issue]
[14] Docker 0.9: Introducing Execution Drivers and libcontainer (March, 2014). Solomon Hykes
[15] A simple helper script to help people build seccomp profiles for Docker/LXC (November 2013). Martijn van Oosterhout.
https://github.com/docker/dock ... ample
[16] Announcing Docker 1.2.0 (August, 2014). Victor Vieux.
[17] Docker Container Breakout Proof-of-Concept Exploit (June, 2014). James Turnbull
[18] docker2docker GitHub repository. Jér?me Petazzoni.
原文:Docker Secure Deployment Guidelines (翻譯:吳錦晟 校對:梁曉勇)
===============================================
譯者介紹
吳錦晟,大連理工大學碩士研究生,就職于上海金橋信息股份有限公司技術中心。目前負責云計算、虛擬化、大數據及其信息可視化等方向的研究和應用。希望通過翻譯技術文章于DockOne社區為Docker的步道做出微薄貢獻。
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!