天天看點

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

在這系列的第一篇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安全性(二)——帶來了新的安全功能給DockerDocker安全性(二)——帶來了新的安全功能給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程序的控制權。

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

多類别安全(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的不與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容器。