柯研
(工業(yè)和信息化部電子第五研究所,廣東 廣州 511370)
容器正在改變應(yīng)用程序的運(yùn)行、設(shè)計(jì)、開發(fā)和部署方式。其提供了一種簡單的方法,可以打包應(yīng)用程序,并從開發(fā)到測試系統(tǒng)無縫地傳輸?shù)缴a(chǎn)系統(tǒng)。其還有助于確保不同環(huán)境(包括物理服務(wù)器、虛擬機(jī)、公共或私有云)之間的一致性。
隨著容器的普及,許多企業(yè)在選擇時(shí)都會(huì)考慮基于容器的PaaS云平臺(tái)。從安全的角度來看,容器提供了一些優(yōu)勢(shì),但它們也面臨一些自身的安全挑戰(zhàn)。當(dāng)使用基于容器的PaaS云平臺(tái)時(shí),安全性問題尤為重要[1]。
通常,部署到PaaS云平臺(tái)的應(yīng)用程序的每個(gè)實(shí)例都在自己獨(dú)立的環(huán)境中運(yùn)行,即容器。這個(gè)容器使用操作系統(tǒng)特性和部署PaaS云平臺(tái)的虛擬和物理基礎(chǔ)結(jié)構(gòu)的特性隔離進(jìn)程、內(nèi)存和文件系統(tǒng)[2]。
PaaS云平臺(tái)通過將內(nèi)核資源劃分成不同命名空間實(shí)現(xiàn)容器隔離。隔離的級(jí)別設(shè)置為防止同一主機(jī)的多個(gè)容器檢測到對(duì)方。每個(gè)容器包括一個(gè)私人的根文件系統(tǒng),包括進(jìn)程ID、名稱空間、網(wǎng)絡(luò)的命名空間、命名空間和安裝。
PaaS云平臺(tái)使用OverlayFS以如下方式創(chuàng)建容器文件系統(tǒng)。
a)只讀基本文件系統(tǒng)
該文件系統(tǒng)具有最低限度的操作系統(tǒng)包集和所有容器所共有的特定于安全性的修改。容器可以共享相同的只讀基本文件系統(tǒng),因?yàn)樗械膶懭攵紤?yīng)用于讀寫層。
b)一個(gè)特定于容器的讀寫層
該層每個(gè)容器是唯一的,其大小受XFS項(xiàng)目配額的限制。配額防止讀寫層溢出到未分配的空間中。
資源控制使用Linux控件組進(jìn)行管理。將每個(gè)容器與其自己的cgroup或作業(yè)對(duì)象關(guān)聯(lián),限制了容器可能使用的內(nèi)存量。與其他容器的相對(duì)CPU份額相比,Linux cgroup還要求容器使用公平的CPU份額。
每個(gè)容器都放在自己的cgroup中。cgroup使每個(gè)容器相對(duì)于其他容器使用公平的CPU份額。這防止了主機(jī)VM上的過度訂閱,即其中一個(gè)或多個(gè)容器占用CPU,而沒有為其他容器留下計(jì)算資源。
cgroup基于共享的方式分配CPU時(shí)間。CPU共享并不是CPU總使用率的直接百分比,而是在給定的時(shí)間窗口中,相對(duì)于其他容器持有的共享??梢栽赾group中總體分配的CPU總量是主機(jī)VM中可能運(yùn)行的其他進(jìn)程留下的。
一般來說,cgroup提供了兩種限制CPU使用的可能性:CPU核綁定和CPU帶寬,后者在PaaS云平臺(tái)中使用。
a)CPU核綁定
它由將cgroup綁定到特定CPU核組成。cgroup可以消耗的CPU周期的實(shí)際數(shù)量僅限于綁定CPU核上可用的部分。
b)CPU帶寬
使用進(jìn)程調(diào)度程序設(shè)置cgroup的權(quán)重。進(jìn)程調(diào)度器根據(jù)每個(gè)cgroup所持有的共享,相對(duì)于其他組所持有的共享在cgroup之間劃分可用的CPU周期。
例如:考慮兩個(gè)cgroup,一個(gè)持有兩個(gè)共享份額,另一個(gè)持有4個(gè)。假設(shè)進(jìn)程調(diào)度程序可以管理60個(gè)CPU周期,第一個(gè)擁有兩個(gè)共享份額的cgroup將獲得這些可用CPU周期的1/3,因?yàn)樗钟姓麄€(gè)共享份額的1/3。同樣,第二個(gè)cgroup將獲得40個(gè)周期,因?yàn)樗钟?/3的共享份額。
根據(jù)可用CPU總功率的百分比計(jì)算CPU使用率是相當(dāng)復(fù)雜的,并且隨著各種容器的CPU需求的波動(dòng)而定期執(zhí)行。具體來說,cgroup獲得的CPU周期百分比可以通過將它持有的cpu.share除以當(dāng)前正在執(zhí)行CPU活動(dòng)的所有cgroup的cpu.share之和來計(jì)算:
process_cpu_share_percent=cpu.shares/sum_cpu_shares*100
在PaaS云平臺(tái)中,cgroup共享介于10~1 024之間,而1 024是默認(rèn)的。cgroup獲取的實(shí)際共享量可以從cgroup配置的cpu.share文件中讀取,在/sys/fs/cgroup/cpu的容器中可用。
分配給應(yīng)用程序cgroup的共享量取決于應(yīng)用程序聲明在清單中需要的內(nèi)存量。PaaS云平臺(tái)將分配的共享數(shù)量與內(nèi)存量成線性關(guān)系,一個(gè)應(yīng)用實(shí)例請(qǐng)求8G內(nèi)存獲得1 024個(gè)共享的上限。
process_cpu.shares=max((application_memory/8),1024)
考慮3個(gè)進(jìn)程P1、P2、P3,cpu.shares值分別為5、20及30。
P1是活動(dòng)的,而P2和P3不需要CPU。因此,P1可以使用整個(gè)CPU。當(dāng)P2加入并正在執(zhí)行一些實(shí)際工作(例如請(qǐng)求傳入)時(shí),將按以下方式計(jì)算P1和P2之間的CPU份額:
1)P1->5/(5+20)=0.2=20%
2)P2->20/(5+20)=0.8=80%
3)P3(idle)
在某個(gè)時(shí)候,進(jìn)程P3也加入進(jìn)來。然后再重新計(jì)算CPU份額:
1)P1->5/(5+20+30)=0.090 9≈~9%
2)P2->20/(5+20+30)=0.363≈~36%
3)P3->30/(5+20+30)=0.545≈~55%
如果P1變?yōu)榭臻e,則P2和P3之間重新計(jì)算CPU份額:
1)P1(idle)
2)P2->20/(20+30)=0.4=40%
3)P3->30/(20+30)=0.6=60%
如果P3完成或變?yōu)榭臻e,則P2可以消耗所有CPU時(shí)鐘周期,因?yàn)閷?zhí)行另一次重新計(jì)算。
cgroup共享份額是進(jìn)程可以獲得的最小保證CPU共享份額。只有當(dāng)同一主機(jī)上的進(jìn)程競爭資源時(shí),此限制才會(huì)生效。
主機(jī)VM只有一個(gè)IP地址。如果按照建議使用VLAN上的集群配置部署,那么所有通信量都會(huì)通過以下級(jí)別的網(wǎng)絡(luò)地址轉(zhuǎn)換,如圖1所示。
圖1 PaaS云平臺(tái)的入站和出站流量
1)入站請(qǐng)求從負(fù)載均衡器通過路由器流向主機(jī)單元,然后流入應(yīng)用程序容器。路由器確定哪個(gè)應(yīng)用程序?qū)嵗邮彰總€(gè)請(qǐng)求。
2)出站流量從應(yīng)用程序容器流到單元格,然后流到單元格虛擬網(wǎng)絡(luò)接口上的網(wǎng)關(guān)。此網(wǎng)關(guān)可能是對(duì)外部網(wǎng)絡(luò)的NAT,取決于IaaS平臺(tái)。
管理員配置規(guī)則以控制容器網(wǎng)絡(luò)通信量。這就是容器如何在PaaS云平臺(tái)之外發(fā)送流量,并從外部(Internet)接收流量。這些規(guī)則可以阻止外部網(wǎng)絡(luò)和內(nèi)部組件之間的系統(tǒng)訪問,并確定應(yīng)用程序是否可以通過虛擬網(wǎng)絡(luò)接口建立連接。
管理員在兩個(gè)級(jí)別配置這些規(guī)則:
1)應(yīng)用程序安全組(ASGs)在容器級(jí)別應(yīng)用網(wǎng)絡(luò)流量規(guī)則。
2)容器到容器的網(wǎng)絡(luò)策略決定了應(yīng)用程序到應(yīng)用程序的通信。在PaaS云平臺(tái)內(nèi)部,應(yīng)用程序可以直接相互通信,但是容器與外部PaaS云平臺(tái)是隔離的。
PaaS云平臺(tái)通過以下措施確保容器的安全:
1)默認(rèn)情況下在非特權(quán)容器中運(yùn)行應(yīng)用程序?qū)嵗?/p>
2)通過限制功能和訪問權(quán)限來加固容器;
3)只允許從應(yīng)用程序容器到公共地址的出站連接,這是默認(rèn)設(shè)置,管理員可以通過配置ASGs來更改此行為。
容器類型有兩種:非特權(quán)容器類型和特權(quán)容器類型。通常,PaaS云平臺(tái)默認(rèn)在非特權(quán)容器中運(yùn)行所有應(yīng)用程序?qū)嵗腿蝿?wù)。此措施通過消除容器內(nèi)root權(quán)限的威脅來提高安全性[3]。
盡管現(xiàn)在默認(rèn)情況下所有應(yīng)用程序?qū)嵗腿蝿?wù)都在非特權(quán)容器中運(yùn)行,但管理員可以通過自定義其部署清單和重新部署來覆蓋這些默認(rèn)值。
PaaS云平臺(tái)以下列方式減輕了容器突破和拒絕服務(wù)攻擊。
a)使用完整的Linux名稱空間(IPC、Network、Mount、PID、User和UTS)來提供在同一主機(jī)上運(yùn)行的容器之間的隔離。
b)在非特權(quán)容器中,PaaS云平臺(tái)將容器用戶名稱空間中的UID/GID 0(Root)映射到主機(jī)上的另一個(gè)UID/GID,以防止應(yīng)用程序突破容器的情況在主機(jī)上繼承UID/GID 0。
1)對(duì)所有容器使用相同的UID/GID。
2)將除UID 0以外的所有UID映射到自己,將容器命名空間中的UID 0映射到容器名稱空間之外的MAX_UID-1。
3)容器root用戶不授予主機(jī)root權(quán)限。
c)將/proc和/sys以只讀權(quán)限掛載到容器內(nèi)。
d)不允許非特權(quán)用戶和非特權(quán)容器中的所有用戶訪問dmesg。
e)建立一個(gè)特定于容器的OverlayFS掛載。將根文件系統(tǒng)移動(dòng)到此OverlayFS中,以便將容器與主機(jī)系統(tǒng)的文件系統(tǒng)隔離開來。
f)不調(diào)用容器文件系統(tǒng)中的任何二進(jìn)制或腳本,以消除根文件系統(tǒng)中對(duì)腳本和二進(jìn)制文件的依賴。
g)通過綁定掛載或其他方法避免容器中的二進(jìn)制文件加載另外的二進(jìn)制文件,而是當(dāng)它需要在容器中運(yùn)行二進(jìn)制時(shí),通過從/proc/self/exe讀取它來重新執(zhí)行相同的二進(jìn)制。
h)為網(wǎng)絡(luò)通信的每個(gè)容器建立虛擬以太網(wǎng)對(duì)。
1)該對(duì)中的一個(gè)接口位于容器的網(wǎng)絡(luò)命名空間內(nèi),是容器內(nèi)唯一可訪問的非環(huán)回接口。
2)另一個(gè)接口保留在主機(jī)網(wǎng)絡(luò)命名空間中,并橋接到容器端接口。
3)出口白名單規(guī)則根據(jù)管理員配置的應(yīng)用程序安全組(ASGs)應(yīng)用于這些接口。
4)首包日志功能也可以應(yīng)用于TCP白名單規(guī)則上。
5)在主機(jī)上建立DNAT規(guī)則,使流量從主機(jī)接口進(jìn)入容器端接口上的白名單端口。
i)使用特定于容器的具有指定磁盤配額容量的XFS配額以應(yīng)用磁盤配額。
j)通過內(nèi)存cgroup限制總內(nèi)存使用配額,如果某個(gè)容器的內(nèi)存使用量超過配額則銷毀該容器。
k)通過cpu.share控件組對(duì)容器中的進(jìn)程的CPU使用量施加合理使用限制。
l)使用cgroup限制對(duì)設(shè)備的訪問,但將下列安全設(shè)備節(jié)點(diǎn)加入白名單[4]:
1)/dev/full
2)/dev/fuse
3)/dev/null
4)/dev/ptmx
5)/dev/pts/*
6)/dev/random
7)/dev/tty
8)/dev/tty0
9)/dev/tty1
10)/dev/urandom
11)/dev/zero
12)/dev/tap
13)/dev/tun
m)刪除所有容器進(jìn)程的下列Linux功能。每次丟棄的功能都限制root用戶可以執(zhí)行的操作[5]。
1)CAP_DAC_READ_SEARCH
2)CAP_LINUX_IMMUTABLE
3)CAP_NET_BROADCAST
4)CAP_NET_ADMIN
5)CAP_IPC_LOCK
6)CAP_IPC_OWNER
7)CAP_SYS_MODULE
8)CAP_SYS_RAWIO
9)CAP_SYS_PTRACE
10)CAP_SYS_PACCT
11)CAP_SYS_BOOT
12)CAP_SYS_NICE
13)CAP_SYS_RESOURCE
14)CAP_SYS_TIME
15)CAP_SYS_TTY_CONFIG
16)CAP_LEASE
17)CAP_AUDIT_CONTROL
18)CAP_MAC_OVERRIDE
19)CAP_MAC_ADMIN
20)CAP_SYSLOG
21)CAP_WAKE_ALARM
22)CAP_BLOCK_SUSPEND
23)CAP_SYS_ADMIN(針對(duì)非特權(quán)容器)
在使用基于容器的PaaS云平臺(tái)時(shí),安全性問題尤為重要。因此,本文介紹了PaaS云平臺(tái)的容器機(jī)制,描述了PaaS云平臺(tái)保護(hù)Linux上承載應(yīng)用實(shí)例的容器的方法,概述了容器隔離和容器網(wǎng)絡(luò),并描述了PaaS云平臺(tái)管理員為其部署自定義容器網(wǎng)絡(luò)流量規(guī)則和PaaS云平臺(tái)通過在非特權(quán)容器中運(yùn)行應(yīng)用程序?qū)嵗⒓訌?qiáng)它們來保護(hù)容器的方法。