本篇翻譯自Daniel J Walsh的1篇開源文章:http://opensource.com/business/14/9/security-for-docker
作者的演講視頻:http://v.youku.com/v_show/id_XODQwNjUwNTIw.html
在這系列的第1篇Docker的安全性,我寫了“容器中不包括”。在第2篇文章中,我將討論為何我們這樣做并且我們正在對它做甚么。
Docker,紅帽和開源社區正在共同努力,使Docker更安全。當我看到安全容器中,我期待避免容器內的進程主機,我也期待來保護彼此的容器。與Docker,我們使用的是分
層的安全方法,這是“結合多個減緩安全控制,以保護資源和數據的做法。”
基本上,我們希望把盡量多的安全屏障,盡量避免爆發。如果特權進程可以突破的1個容納機制,我們希望下1個禁止他們。與Docker,我們要采取的Linux盡量多的
安全機制的優勢。
榮幸的是,紅帽企業版Linux(RHEL)7,我們得到了大量的安全功能。
只讀掛載點
1些Linux內核文件系統必須被安裝在容器中的環境或進程將沒法運行。榮幸的是,大多數這些文件系統可被安裝為“只讀”。大多數利用程序不應當需要寫入這些文件系統。
Docker掛載這些文件系統放入容器中的“只讀”的掛載點。
. /sys
. /proc/sys
. /proc/sysrq-trigger
. /proc/irq
. /proc/bus
通過安裝這些文件系統為只讀,特權容器進程不能給他們寫信。它們不能影響主機系統。固然,我們也阻擋特權容器進程的能力,重新裝入文件系統的讀/寫。我們禁止安裝
任何文件系統的所有內部容器的能力。我將解釋我們如何禁止掛載,當我們到達的能力。
寫入時復制的文件系統
Docker使用寫入時復制文件系統。這意味著容器中可使用相同的文件系統映像為基準,為容器。當容器的內容寫入到圖象,它被寫入到1個容器特定的文件系統。這樣可
以避免1個容器沒法看到,即便他們寫信給同1個文件系統映像另外一個容器的變化。一樣重要的是,1個容器不能改變圖象內容,以實現該進程中的另外一容器中。
Linux的能力是在他們的主頁很好地解釋了:
對履行權限檢查的目的,傳統的UNIX實現辨別兩類進程:特權進程(其有功效戶ID為0,被稱為超級用戶或root)和非特權進程(其有效的UID不為零)。特權進程繞過所
有內核權限檢查,同時非特權進程遭到完全權限基于進程的憑證檢查(通常是:有效的UID,有效的GID,并補充組列表)。內核2.2開始,Linux的劃分與傳統的超級用戶相
關的成不同的單元,被稱為功能,可以獨立啟用和禁用的權限。能力是每一個線程屬性。
刪除功能可能會致使利用程序突破,這意味著我們有功能性,可用性和安全性之間的平衡在Docker。下面是功能,Docker使用當前列表:CHOWN,dac_override,fowner,殺
,setgid的,setuid的,setpcap,net_bind_service,net_raw,sys_chroot,mknod的,setfcap和audit_write。
它是不斷爭辯來回哪些功能應當被允許或默許謝絕。Docker允許用戶操控默許列表與Docker運行命令行選項。
Docker中刪除幾個這樣的功能,包括以下內容:
CAP_SETPCAP修改進程的能力
CAP_SYS_MODULE插入/刪除內核模塊
CAP_SYS_RAWIO修改內核內存
CAP_SYS_PACCT配置進程記帳
CAP_SYS_NICE修改優先流程
CAP_SYS_RESOURCE覆蓋資源限制
CAP_SYS_TIME修改系統時鐘
CAP_SYS_TTY_CONFIG配置tty裝備
CAP_AUDIT_WRITE寫審計日志
CAP_AUDIT_CONTROL配置審計子系統
CAP_MAC_OVERRIDE疏忽內核MAC政策
CAP_MAC_ADMIN配置MAC配置
CAP_SYSLOG修改內核的printk行動
CAP_NET_ADMIN配置網絡
CAP_SYS_ADMIN捕獲所有
讓我們來看看在表中更接近在過去幾個。通過刪除CAP_NET_ADMIN1個容器,容器進程不能修改系統網絡,這意味著分配IP地址的網絡裝備,建立路由規則,修改iptables的
。
所有的網絡是由容器設置的開始前的Docker守護進程。可以從容器之外,但還沒有內部管理容器中網絡接口。
CAP_SYS_ADMIN是特殊的能力。我相信這是內核包羅萬象的能力。當內核工程師設計新的功能到內核中,他們應當選擇最匹配的是甚么功能允許的能力。或,他們應當創建
1個新的能力。問題是,本來有32只的能力插槽可用。如有疑問內核工程師也只是回落到使用CAP_SYS_ADMIN。這是事物的列表,根據CAP_SYS_ADMIN所允
許:/usr/include/linux/capability。
讓安全注意鍵配置 允許隨機裝備的管理
允許檢查和磁盤配額的配置 允許設置的域名
允許設置主機名 允許調用的bdflush()
允許裝載()和umount(),建立新的SMB連接 允許1些autofs的root的ioctl
讓nfsservctl 允許VM86_REQUEST_IRQ
允許讀取字母/寫PCI配置 允許irix_prctl在MIPS(setstacksize)
讓沖洗的m68k的(sys_cacheflush)的所有緩存 允許刪除信號燈
用來代替CAP_CHOWN為“CHOWN”IPC消息隊列,信號量和同享內存 允許同享內存段鎖定/解鎖
允許在/套接字憑據關 允許捏造的PID通過轉掉期
允許設置預讀和沖洗緩沖塊裝備上 允許設置幾何軟盤驅動器
允許開/關在XD驅動 允許MD裝備施用轉動的DMA(主要是上述情況,但1些額外的ioctl)
允許訪問到NVRAM裝備 允許apm_bios的管理,串行和BTTV(TV)裝備
允許ISDN CAPI支持驅動程序制造商的命令 允許讀取PCI配置空間非標準化的部份
允許在SBPCD驅動DDI調試的ioctl 允許設置串口
允許發送原始QIC⑴17命令 允許啟用/禁用標記排隊的SCSI控制器和發送任意的SCSI命令
允許設置加密密鑰對回文件系統 允許設置區回收政策
允許調劑IDE驅動程序
兩個最重要的特性,從容器中取出CAP_SYS_ADMIN確切是停止從履行安裝系統調用或修改名稱空間的進程。你不想讓你的容器進程掛載隨機文件系統或重新安裝只讀文件系統
。
--cap-add --cap-drop
Docker來講也有1個特點,你可以調劑你的容器需要的功能。這意味著你可以刪除功能的容器不需要。例如,如果你的容器不需要setuid和setgid可以刪除此訪問履行:
docker run --cap-drop setuid --cap-drop setgid -ti rhel7 /bin/sh
你乃至可以刪除所有功能或添加他們都:
docker run --cap-add all --cap-drop sys-admin -ti rhel7 /bin/sh
此命令會增加,除SYS-admin的所有功能。
1些Docker設置為進程的命名空間來運行也提供了1些安全。
PID命名空間
該PID命名空間隱藏的是,除那些在當前容器中運行的系統上運行的所有進程。如果你不能看到其他進程,這使得它更難攻擊的進程。你不能輕易strace的或ptrace的他們
。而且,殺進程的命名空間的PID1會自動容器,這意味著管理員可以很容易地禁止容器內殺死所有的進程。
網絡空間
網絡名稱空間可用于實現安全性。管理員可以設置在容器的網絡路由規則和iptables使得容器內的進程,只能使用特定的網絡。我能想象的人設置了3個過濾容器:
?1個只允許在公共互聯網上溝通。
?1個只允許專用Intranet通訊。
?1個連接到其他兩個集裝箱,郵件中繼來回容器中之間,但禁止不適當的內容。
cgroup中
1種類型的系統上的攻擊可以被描寫為1個謝絕服務。這是1個進程的進程或組使用的所有資源的系統上,以避免其他進程的履行。 cgroup中可使用的控制資源的任何
Docker容器可使用的量,以減輕此。例如,CPU cgroup中可以設置這樣,管理員依然可以登錄到1個系統,其中1個Docker容器試圖主宰CPU和殺死它。新的cgroup正在研
發中,以幫助控制進程,使用過量的資源,如打開的文件或進程數。Docker將這些cgroup的優勢,由于他們成為可用。
裝備的cgroup
Docker采取特殊的cgroup,使您可以指定哪些裝備節點可以在容器內使用的優勢。它的塊的處理,從創建和使用可用于攻擊的主機裝備的節點。
裝備節點允許進程改變內核的配置。控制該裝備的節點可用controlls甚么1個進程是能夠做到在主機系統上。
下面的裝備節點都在容器中默許創建。
/dev/console,/dev/null,/dev/zero,/dev/full,/dev/tty*,/dev/urandom,/dev/random,/dev/fuse
該Docker圖象也安裝為nodev,這意味著,即便1個裝備節點被圖象中的預先創建的,它不能被用于由進程容器內進行通話的內核。
注意:裝備節點的創建也能夠禁止通過除去CAP_MKNOD能力。Docker已選擇不這樣做,以允許進程創建1組裝備節點的限制。在期貨部份,我將提--opt命令行選項,我想
用它來消除這類能力。
AppArmor
AppArmor中可以Docker容器中上支持它的系統。但我用RHEL和Fedora,不支持AppArmor的,所以你必須在其他地方進行調查這1安全機制。 (另外,我使用SELinux的你很
清楚。)
SELinux
首先,1些關于SELinux的:
?SELinux的是1個標簽制度
?每一個進程都有1個LABEL
?每一個文件,目錄和系統對象有1個LABEL
?標記進程和標記對象之間的策略規則控制訪問
?內核強迫履行的規則
SELinux的實現了強迫訪問控制系統。這意味著1個對象的業主沒法控制或自由裁量權的訪問對象。內核強迫履行強迫訪問控制。我描寫了如何SELinux的執法工作在視覺引
導SELinux策略履行(和隨后,SELinux的圖畫書)。
我會用1些從該文章中的漫畫來描寫我們如何使用SELinux的控制允許Docker容器進程的訪問。我們使用兩種類型的SELinux執法的Docker容器。
類型強迫保護從進程主機在容器內
我們使用運行Docker容器的默許類型是svirt_lxc_net_t。運行所有容器進程與這類類型。
在容器內的所有內容都標有svirt_sandbox_file_t類型。
svirt_lxc_net_t被允許管理標記svirt_sandbox_file_t任何內容。
svirt_lxc_net_t也能讀/在/ usr履行大多數標簽的主機上。
流程運行witht他svirt_lxc_net_t都不允許打開/寫入系統上的任何其他標簽。它不允許讀取/ var,/root,/家庭等任何默許標簽
基本上,我們希望允許進程讀取/履行系統的內容,但我們希望不是允許它使用任何“數據”在系統上,除非它是在容器中,默許情況下。
問題
如果所有的容器進程都運行與svirt_lxc_net_t,所有的內容都標有svirt_sandbox_file_t,不會容器進程被允許在攻擊其他容器中具有其他容器和內容正在運行的進程?
這是多種別安全執法進來,以下所述。
另外一種類型
請注意,我們在類型標簽使用的“網”。我們這是用來表示這類類型的可使用完全的網絡。我工作的1個補釘,以Docker,以允許用戶指定替換類型的用于容器。例如,你
可以指定喜歡的東西:
docker run -ti --security-opt label:type:lxc_nonet_t rhel7 /bin/sh
然后在容器內的進程將不會被允許使用任何網絡端口。一樣,我們可以很容易地編寫1個Apache的政策,將只允許在容器上的Apache端口上偵聽,但不允許連接出任何端口
。使用這類類型的政策,你可以避免你的容器成為垃圾郵件的僵尸,即便它被破解,而黑客取得容器內的Apache進程的控制權。
多種別安全(MCS)保護其他容器中1個容器
多種別安全性是基于多級安全(MLS)。 MCS需要SELinux的標簽MLS場的最后1個組件的優勢。的MCS履行保護彼此容器。當容器被推出Docker守護選擇1個隨機的MCS標簽,
例如S0:C1,C2,分配給該容器。Docker守護標簽的所有與本MCS標簽在容器中的內容。當守護程序啟動容器進程中,它告知內核來標記具有相同MCS標簽的進程。內核只允
許容器進程讀/只要處理的MCS標簽文件系統內容的MCS標簽匹配寫自己的內容。從讀/寫內容的內核模塊容器進程標有不同的MCS標簽。
避免了黑客攻擊容器進程攻擊不同的容器。Docker守護進程負責保證沒有容器使用相同的MCS標簽。這是1個視頻我做了展現會產生甚么,如果1個OpenShift容器能夠取得
root的系統。相同的基本策略用于限制Docker容器。
正如我上面提到的,我工作的1個補釘Docker,讓不同的SELinux內容的規范。我將允許管理員指定容器的標簽。
docker run --ti --rm --label-opt level:TopSecret rhel7 /bin/sh
這讓人們開始在多級安全(MLS)的環境中運行容器中,這可以為那些需要MLS環境是有益的
文件系統支持
目前,SELinux的將只與裝備映照器后真個工作。 SELinux的不與BTFS工作。 BTRFS不支持背景下掛載標簽的是,避免了SELinux的重新標記的所有內容,當容器,通過mount
命令啟動。內核工程師們正在為這個和潛伏Overlayfs1個修復,如果它被合并到容器中。
卷掛載
由于類型增強只允許容器進程中讀取容器中/寫svirt_sandbox_file_t,卷安裝多是1個問題。卷掛載是1個目錄只是1個綁定掛載放入容器內,那里的目錄的標簽不改變
。為了使容器進程讀/寫的內容,你需要改變的類型標簽svirt_sandbox_file_t。
卷掛載在/var/lib/myapp
chcon -Rt svirt_sandbox_file_t /var/lib/myapp
我寫了1個補釘Docker還沒有合并上游來自動設置這些標簽。隨著補釘,你將Docker重新標記卷到任何1個自有品牌“Z”或同享的標簽,“Z”自動。
docker run -v /var/lib/myapp:/var/lib/myapp:Z ...
docker run -v /var/lib/myapp:/var/lib/myapp:z ...
希望這將很快得到合并。
我們已增加了很多安全機制,使Docker容器中不是運行在裸機上利用程序更安全,但你依然需要保持良好的安全做法,由于我對這個問題的第1篇文章中談到。
?僅運行來自可靠來源利用程序
?1個企業質量主機上運行的利用程序
?定期安裝更新
?刪除的權限盡快
?非root盡量運行
?注意你的日志
?setenforce1
我對Docker的安全下1篇文章將介紹我們正在努力的將是甚么,以進1步保護Docker容器。
本篇翻譯自Daniel J Walsh的1篇開源文章:http://opensource.com/business/14/9/security-for-docker