Docker安全性(二)——帶來了新的安全功能給Docker

楊振平發表於2014-12-03

Docker安全性(二)——帶來了新的安全功能給Docker

本篇翻譯自Daniel J Walsh的一篇開源文章:http://opensource.com/business/14/9/security-for-docker

作者的演講視訊:http://v.youku.com/v_show/id_XODQwNjUwNTIw.html

在這系列的第一篇Docker的安全性,我寫了“容器中不包含”。在第二篇文章中,我將討論為什麼我們這樣做並且我們正在對它做什麼。

Docker,紅帽和開源社群正在共同努力,使Docker更安全。當我看到安全容器中,我期待防止容器內的程式主機,我也期待來保護彼此的容器。與Docker,我們使用的是分

層的安全方法,這是“結合多個緩解安全控制,以保護資源和資料的做法。”

基本上,我們希望把儘可能多的安全屏障,儘可能防止爆發。如果特權程式可以突破的一個容納機制,我們希望下一個阻止他們。與Docker,我們要採取的Linux儘可能多的

安全機制的優勢。

幸運的是,紅帽企業版Linux(RHEL)7,我們得到了大量的安全功能。

檔案系統保護

只讀掛載點

一些Linux核心檔案系統必須被安裝在容器中的環境或過程將無法執行。幸運的是,大多數這些檔案系統可被安裝為“只讀”。大多數應用程式不應該需要寫入這些檔案系統。

Docker掛載這些檔案系統放入容器中的“只讀”的掛載點。

 . /sys
 . /proc/sys
 . /proc/sysrq-trigger
 . /proc/irq
 . /proc/bus

通過安裝這些檔案系統為只讀,特權容器程式不能給他們寫信。它們不能影響主機系統。當然,我們也阻擋特權容器程式的能力,重新裝入檔案系統的讀/寫。我們阻止安裝

任何檔案系統的所有內部容器的能力。我將解釋我們如何阻止掛載,當我們到達的能力。

寫入時複製的檔案系統

Docker使用寫入時複製檔案系統。這意味著容器中可以使用相同的檔案系統映像為基準,為容器。當容器的內容寫入到影像,它被寫入到一個容器特定的檔案系統。這樣可

以防止一個容器無法看到,即使他們寫信給同一個檔案系統映像另一個容器的變化。同樣重要的是,一個容器不能改變影像內容,以實現該程式中的另一容器中。

能力

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_ADMIN一個容器,容器程式不能修改系統網路,這意味著分配IP地址的網路裝置,建立路由規則,修改iptables的

所有的網路是由容器設定的開始前的Docker守護程式。可以從容器以外,但尚未內部管理容器中網路介面。

CAP_SYS_ADMIN是特殊的能力。我相信這是核心包羅永珍的能力。當核心工程師設計新的功能到核心中,他們應該選擇最匹配的是什麼功能允許的能力。或者,他們應該建立

一個新的能力。問題是,原本有32只的能力插槽可用。如有疑問核心工程師也只是回落到使用CAP_SYS_ADMIN。這是事物的列表,根據CAP_SYS_ADMIN所允

許:/usr/include/linux/capability。

讓安全注意鍵配置 允許隨機裝置的管理
允許檢查和磁碟配額的配置 允許設定的域名
允許設定主機名 允許呼叫的bdflush()
允許裝載()和umount(),建立新的SMB連線 允許一些autofs的root的ioctl
讓nfsservctl 允許VM86_REQUEST_IRQ
允許讀取字母/寫PCI配置 允許irix_prctl在MIPS(setstacksize)
讓沖洗的m68k的(sys_cacheflush)的所有快取 允許刪除訊號燈
用來代替CAP_CHOWN為“CHOWN”IPC訊息佇列,訊號量和共享記憶體 允許共享記憶體段鎖定/解鎖
允許在/套接字憑據關 允許偽造的PID通過轉掉期
允許設定預讀和沖洗緩衝塊裝置上 允許設定幾何軟盤驅動器
允許開/關在XD驅動 允許MD裝置施用轉動的DMA(主要是上述情況,但一些額外的ioctl)
允許訪問到NVRAM裝置 允許apm_bios的管理,序列和BTTV(TV)裝置
允許ISDN CAPI支援驅動程式製造商的命令 允許讀取PCI配置空間非標準化的部分
允許在SBPCD驅動DDI除錯的ioctl 允許設定串列埠
允許傳送原始QIC-117命令 允許啟用/禁用標記排隊的SCSI控制器和傳送任意的SCSI命令
允許設定加密金鑰對迴檔案系統 允許設定區回收政策
允許調整IDE驅動程式

兩個最重要的特性,從容器中取出CAP_SYS_ADMIN確實是停止從執行安裝系統呼叫或修改名稱空間的程式。你不想讓你的容器程式掛載隨機檔案系統或重新安裝只讀檔案系統

–cap-add –cap-drop

Docker來說也有一個特點,你可以調整你的容器需要的功能。這意味著你可以刪除功能的容器不需要。例如,如果你的容器不需要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的所有功能。

名稱空間

一些Docker設定為程式的名稱空間來執行也提供了一些安全。

PID名稱空間

該PID名稱空間隱藏的是,除了那些在當前容器中執行的系統上執行的所有程式。如果你不能看到其他程式,這使得它更難攻擊的過程。你不能輕易strace的或ptrace的他們

。而且,殺程式的名稱空間的PID1會自動容器,這意味著管理員可以很容易地阻止容器內殺死所有的程式。

網路空間

網路名稱空間可用於實現安全性。管理員可以設定在容器的網路路由規則和iptables使得容器內的程式,只能使用特定的網路。我能想象的人設定了三個過濾容器:
•一個只允許在公共網際網路上溝通。
•一個只允許專用Intranet通訊。
•一個連線到其他兩個集裝箱,郵件中繼來回容器中之間,但阻止不適當的內容。

cgroup中

一種型別的系統上的攻擊可以被描述為一個拒絕服務。這是一個過程的過程或組使用的所有資源的系統上,以防止其他程式的執行。 cgroup中可以使用的控制資源的任何

Docker容器可以使用的量,以減輕此。例如,CPU cgroup中可以設定這樣,管理員仍然可以登入到一個系統,其中一個Docker容器試圖主宰CPU和殺死它。新的cgroup正在研

發中,以幫助控制過程,使用過多的資源,如開啟的檔案或程式數。Docker將這些cgroup的優勢,因為他們成為可用。

裝置的cgroup

Docker採用特殊的cgroup,使您可以指定哪些裝置節點可以在容器內使用的優勢。它的塊的處理,從建立和使用可用於攻擊的主機裝置的節點。

裝置節點允許程式改變核心的配置。控制該裝置的節點可用controlls什麼一個過程是能夠做到在主機系統上。

下面的裝置節點都在容器中預設建立。
/dev/console,/dev/null,/dev/zero,/dev/full,/dev/tty*,/dev/urandom,/dev/random,/dev/fuse

該Docker影像也安裝為nodev,這意味著,即使一個裝置節點被影像中的預先建立的,它不能被用於由程式容器內進行通話的核心。

注意:裝置節點的建立也可以阻止通過除去CAP_MKNOD能力。Docker已經選擇不這樣做,以允許程式建立一組裝置節點的限制。在期貨部分,我將提–opt命令列選項,我想

用它來消除這種能力。

AppArmor

AppArmor中可以Docker容器中上支援它的系統。但我用RHEL和Fedora,不支援AppArmor的,所以你必須在其他地方進行調查這一安全機制。 (此外,我使用SELinux的你很

清楚。)

SELinux

首先,一些關於SELinux的:
•SELinux的是一個標籤制度
•每個程式都有一個LABEL
•每個檔案,目錄和系統物件有一個LABEL
•標記過程和標記物件之間的策略規則控制訪問
•核心強制執行的規則

SELinux的實現了強制訪問控制系統。這意味著一個物件的業主無法控制或自由裁量權的訪問物件。核心強制執行強制訪問控制。我描述瞭如何SELinux的執法工作在視覺引

導SELinux策略執行(以及隨後,SELinux的圖畫書)。

我會用一些從該文章中的漫畫來描述我們如何使用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,不會容器程式被允許在攻擊其他容器中擁有其他容器和內容正在執行的程式?
這是多類別安全執法進來,如下所述。

另一種型別

請注意,我們在型別標籤使用的“網”。我們這是用來表示這種型別的可以使用完整的網路。我工作的一個補丁,以Docker,以允許使用者指定替代型別的用於容器。例如,你

可以指定喜歡的東西:

docker run -ti –security-opt label:type:lxc_nonet_t rhel7 /bin/sh

然後在容器內的程式將不會被允許使用任何網路埠。同樣,我們可以很容易地編寫一個Apache的政策,將只允許在容器上的Apache埠上偵聽,但不允許連線出任何埠

。使用這種型別的政策,你可以防止你的容器成為垃圾郵件的殭屍,即使它被破解,而黑客獲得容器內的Apache程式的控制權。

多類別安全執法

多類別安全(MCS)保護其他容器中一個容器

多類別安全性是基於多級安全(MLS)。 MCS需要SELinux的標籤MLS場的最後一個元件的優勢。的MCS執行保護彼此容器。當容器被推出Docker守護選擇一個隨機的MCS標籤,

例如S0:C1,C2,分配給該容器。Docker守護標籤的所有與本MCS標籤在容器中的內容。當守護程式啟動容器過程中,它告訴核心來標記具有相同MCS標籤的過程。核心只允

許容器程式讀/只要處理的MCS標籤檔案系統內容的MCS標籤匹配寫自己的內容。從讀/寫內容的核心模組容器程式標有不同的MCS標籤。

防止了黑客攻擊容器程式攻擊不同的容器。Docker守護程式負責保證沒有容器使用相同的MCS標籤。這是一個視訊我做了展示會發生什麼,如果一個OpenShift容器能夠獲得

root的系統。相同的基本策略用於限制Docker容器。

正如我上面提到的,我工作的一個補丁Docker,讓不同的SELinux內容的規範。我將允許管理員指定容器的標籤。

docker run –ti –rm –label-opt level:TopSecret rhel7 /bin/sh

這讓人們開始在多級安全(MLS)的環境中執行容器中,這可以為那些需要MLS環境是有益的

SELinux的陷阱

檔案系統支援

目前,SELinux的將只與裝置對映器後端的工作。 SELinux的不與BTFS工作。 BTRFS不支援背景下掛載標籤的是,防止了SELinux的重新標記的所有內容,當容器,通過mount

命令啟動。核心工程師們正在為這個和潛在Overlayfs一個修復,如果它被合併到容器中。

卷掛載

因為型別增強只允許容器程式中讀取容器中/寫svirt_sandbox_file_t,卷安裝可能是一個問題。卷掛載是一個目錄只是一個繫結掛載放入容器內,那裡的目錄的標籤不改變

。為了使容器程式讀/寫的內容,你需要改變的型別標籤svirt_sandbox_file_t。

卷掛載在/var/lib/myapp
 chcon -Rt svirt_sandbox_file_t /var/lib/myapp

我寫了一個補丁Docker尚未合併上游來自動設定這些標籤。隨著補丁,你將Docker重新標記捲到任何一個自有品牌“Z”或共享的標籤,“Z”自動。

docker run -v /var/lib/myapp:/var/lib/myapp:Z …
docker run -v /var/lib/myapp:/var/lib/myapp:z …

希望這將很快得到合併。

底線

我們已經增加了很多安全機制,使Docker容器中不是執行在裸機上應用程式更安全,但你仍然需要保持良好的安全做法,因為我對這個問題的第一篇文章中談到。
•僅執行來自可靠來源應用程式
•一個企業質量主機上執行的應用程式
•定期安裝更新
•刪除的許可權盡快
•非root儘可能執行
•注意你的日誌
•setenforce1

我對Docker的安全下一篇文章將介紹我們正在努力的將是什麼,以進一步保護Docker容器。

本篇翻譯自Daniel J Walsh的一篇開源文章:http://opensource.com/business/14/9/security-for-docker


相關文章