您好,登錄后才能下訂單哦!
這篇文章主要講解了“Docker的安全性支持舉例分析”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Docker的安全性支持舉例分析”吧!
Docker作為最重視安全的容器技術(shù)之一,在很多方面都提供了強(qiáng)安全性的默認(rèn)配置,其中包括:容器root用戶的 Capability 能力限制、Seccomp系統(tǒng)調(diào)用過濾、Apparmor的 MAC 訪問控制、ulimit限制、pid-limits的支持,鏡像簽名機(jī)制等。
Docker利用Namespace實(shí)現(xiàn)了6項(xiàng)隔離,看似完整,實(shí)際上依舊沒有完全隔離Linux資源,比如/proc 、/sys 、/dev/sd*等目錄未完全隔離,SELinux、time、syslog等所有現(xiàn)有Namespace之外的信息都未隔離。 其實(shí)Docker在安全性上也做了很多工作,大致包括下面幾個(gè)方面:
1、Linux內(nèi)核 Capability 能力限制
Docker支持為容器設(shè)置Capabilities,指定開放給容器的權(quán)限。這樣在容器中的root用戶比實(shí)際的root少很多權(quán)限。Docker 在0.6版本以后支持將容器開啟超級(jí)權(quán)限,使容器具有宿主機(jī)的root權(quán)限。
2、鏡像簽名機(jī)制
Docker 1.8版本以后提供了鏡像簽名機(jī)制來驗(yàn)證鏡像的來源和完整性,這個(gè)功能需要手動(dòng)開啟,這樣鏡像制作者可以在push鏡像前對(duì)鏡像進(jìn)行簽名,在鏡像pull的時(shí)候,Docker不會(huì)pull驗(yàn)證失敗或者沒有簽名的鏡像標(biāo)簽。
3、Apparmor的MAC訪問控制
Apparmor可以將進(jìn)程的權(quán)限與進(jìn)程capabilities能力聯(lián)系在一起,實(shí)現(xiàn)對(duì)進(jìn)程的強(qiáng)制性訪問控制(MAC)。在Docker中,我們可以使用Apparmor來限制用戶只能執(zhí)行某些特定命令、限制容器網(wǎng)絡(luò)、文件讀寫權(quán)限等功能。
4、Seccomp系統(tǒng)調(diào)用過濾
使用Seccomp可以限制進(jìn)程能夠調(diào)用的系統(tǒng)調(diào)用(system call)的范圍,Docker提供的默認(rèn) Seccomp 配置文件已經(jīng)禁用了大約 44 個(gè)超過 300+ 的系統(tǒng)調(diào)用,滿足大多數(shù)容器的系統(tǒng)調(diào)用訴求。
5、User Namespace隔離
Namespace為運(yùn)行中進(jìn)程提供了隔離,限制他們對(duì)系統(tǒng)資源的訪問,而進(jìn)程沒有意識(shí)到這些限制,為防止容器內(nèi)的特權(quán)升級(jí)攻擊的最佳方法是將容器的應(yīng)用程序配置為作為非特權(quán)用戶運(yùn)行,對(duì)于其進(jìn)程必須作為容器中的 root 用戶運(yùn)行的容器,可以將此用戶重新映射到 Docker 主機(jī)上權(quán)限較低的用戶。映射的用戶被分配了一系列 UID,這些 UID 在命名空間內(nèi)作為從 0 到 65536 的普通 UID 運(yùn)行,但在主機(jī)上沒有特權(quán)。
6、SELinux
SELinux主要提供了強(qiáng)制訪問控制(MAC),即不再是僅依據(jù)進(jìn)程的所有者與文件資源的rwx權(quán)限來決定有無訪問能力。能在攻擊者實(shí)施了容器突破攻擊后增加一層壁壘。Docker提供了對(duì)SELinux的支持。
7、pid-limits的支持
在說pid-limits前,需要說一下什么是fork炸彈(fork bomb),fork炸彈就是以極快的速度創(chuàng)建大量進(jìn)程,并以此消耗系統(tǒng)分配予進(jìn)程的可用空間使進(jìn)程表飽和,從而使系統(tǒng)無法運(yùn)行新程序。說起進(jìn)程數(shù)限制,大家可能都知道ulimit的nproc這個(gè)配置,nproc是存在坑的,與其他ulimit選項(xiàng)不同的是,nproc是一個(gè)以用戶為管理單位的設(shè)置選項(xiàng),即他調(diào)節(jié)的是屬于一個(gè)用戶UID的最大進(jìn)程數(shù)之和。這部分內(nèi)容下一篇會(huì)介紹。Docker從1.10以后,支持為容器指定--pids-limit 限制容器內(nèi)進(jìn)程數(shù),使用其可以限制容器內(nèi)進(jìn)程數(shù)。
8、其他內(nèi)核安全特性工具支持
在容器生態(tài)的周圍,還有很多工具可以為容器安全性提供支持,比如可以使用 Docker bench audit tool(工具地址:https://github.com/docker/docker-bench-security)檢查你的Docker運(yùn)行環(huán)境,使用Sysdig Falco(工具地址:https://sysdig.com/opensource/falco/)來檢測(cè)容器內(nèi)是否有異?;顒?dòng),可以使用GRSEC 和 PAX來加固系統(tǒng)內(nèi)核等等。
這次分享我們帶大家了解一下Docker對(duì)前四項(xiàng)是如何安全支持的,下一篇文章會(huì)帶大家了解剩余內(nèi)容。
1Linux內(nèi)核Capability能力限制
Capabilities簡(jiǎn)單來說,就是指開放給進(jìn)程的權(quán)限,比如允許進(jìn)程可以訪問網(wǎng)絡(luò)、讀取文件等。Docker容器本質(zhì)上就是一個(gè)進(jìn)程,默認(rèn)情況下,Docker 會(huì)刪除 必須的 capabilities 外的所有 capabilities,可以在 Linux 手冊(cè)頁 中看到完整的可用 capabilities 列表。Docker 0.6版本以后支持在啟動(dòng)參數(shù)中增加 --privileged 選項(xiàng)為容器開啟超級(jí)權(quán)限。
Docker支持Capabilities對(duì)于容器安全意義重大,因?yàn)樵谌萜髦形覀兘?jīng)常會(huì)以root用戶來運(yùn)行,使用Capability限制后,容器中的 root 比真正的 root用戶權(quán)限少得多。這就意味著,即使入侵者設(shè)法在容器內(nèi)獲取了 root 權(quán)限,也難以做到嚴(yán)重破壞或獲得主機(jī) root 權(quán)限。
當(dāng)我們?cè)赿ocker run時(shí)指定了--privileded 選項(xiàng),docker其實(shí)會(huì)完成兩件事情:
獲取系統(tǒng)root用戶所有能力賦值給容器;
掃描宿主機(jī)所有設(shè)備文件掛載到容器內(nèi)。
下面我們給大家實(shí)際演示一下:
當(dāng)執(zhí)行docker run 時(shí)未指定--privileded 選項(xiàng)
lynzabo@ubuntu:~$ docker run --rm --name def-cap-con1 -d alpine /bin/sh -c "while true;do echo hello; sleep 1;done"
f216f9261bb9c3c1f226c341788b97c786fa26657e18d7e52bee3c7f2eef755c
lynzabo@ubuntu:~$ docker inspect def-cap-con1 -f '{{.State.Pid}}'
43482
lynzabo@ubuntu:~$ cat /proc/43482/status | grep Cap
CapInh: 00000000a80425fb
CapPrm: 00000000a80425fb
CapEff: 00000000a80425fb
CapBnd: 00000000a80425fb
CapAmb: 0000000000000000
lynzabo@ubuntu:~$
lynzabo@ubuntu:~$ docker exec def-cap-con1 ls /dev
core fd full mqueue null ptmx pts random shm stderr stdin stdout tty urandom zero ...總共15條
lynzabo@ubuntu:~$
△左右滑動(dòng)看全部△
如果指定了--privileded 選項(xiàng)
lynzabo@ubuntu:~$ docker run --privileged --rm --name pri-cap-con1 -d alpine /bin/sh -c "while true;do echo hello; sleep 1;done"
ad6bcff477fd455e73b725afe914b82c8aa6040f36326106a9a3539ad0be03d2
lynzabo@ubuntu:~$ docker inspect pri-cap-con1 -f '{{.State.Pid}}'
44312
lynzabo@ubuntu:~$ cat /proc/44312/status | grep Cap
CapInh: 0000003fffffffff
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
lynzabo@ubuntu:~$ docker exec pri-cap-con1 ls /dev
agpgart autofs bsg btrfs-control bus core cpu_dma_latency cuse dmmidi dri ecryptfs
...總共186條
lynzabo@ubuntu:~$
△左右滑動(dòng)看全部△
對(duì)比/proc/$pid/status ,可以看到兩個(gè)容器進(jìn)程之間能力位圖的差別,加上--privileged 的能力位圖與超級(jí)用戶的能力位圖一樣。再對(duì)比增加--privileged后目錄/dev 下文件變化,可以看到,加了特權(quán)后,宿主機(jī)所有設(shè)備文件都掛載在容器內(nèi)。
我們可以看到,使用--privileged 參數(shù)授權(quán)給容器的權(quán)限太多,所以需要謹(jǐn)慎使用。如果需要掛載某個(gè)特定的設(shè)備,可以通過--device方式,只掛載需要使用的設(shè)備到容器中,而不是把宿主機(jī)的全部設(shè)備掛載到容器上。例如,為容器內(nèi)掛載宿主機(jī)聲卡:
$ docker run --device=/dev/snd:/dev/snd …
此外,可以通過--add-cap 和 --drop-cap 這兩個(gè)參數(shù)來對(duì)容器的能力進(jìn)行調(diào)整,以最大限度地保證容器使用的安全。
例如,給容器增加一個(gè)修改系統(tǒng)時(shí)間的命令:
$ docker run --cap-drop ALL --cap-add SYS_TIME ntpd /bin/sh
查看容器PID,執(zhí)行g(shù)etpcaps PID查看進(jìn)程的能力,執(zhí)行結(jié)果如下:
[root@VM_0_6_centos ~]# getpcaps 652
Capabilities for `652': = cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_sys_time,...
[root@VM_0_6_centos ~]#
△左右滑動(dòng)看全部△
可以看到容器中已經(jīng)增加了sys_time 能力,可以修改系統(tǒng)時(shí)間了。
2Docker鏡像簽名機(jī)制
當(dāng)我們執(zhí)行docker pull 鏡像的時(shí)候,鏡像倉庫再驗(yàn)證完用戶身份后,會(huì)先返回一個(gè)manifest.json文件,其中包含了鏡像名稱、tag、所有l(wèi)ayer層SHA256值,還有鏡像的簽名信息,然后docker daemon會(huì)并行的下載這些layer層文件。Docker 1.8以后,提供了一個(gè)數(shù)字簽名機(jī)制——content trust來驗(yàn)證官方倉庫鏡像的來源和完整性,簡(jiǎn)單來說就是鏡像制作者制作鏡像時(shí)可以選擇對(duì)鏡像標(biāo)簽(tag)進(jìn)行簽名或者不簽名,當(dāng)pull鏡像時(shí),就可以通過這個(gè)簽名進(jìn)行校驗(yàn),如果一致則認(rèn)為數(shù)據(jù)源可靠,并下載鏡像。
默認(rèn)情況下,這個(gè)content trust是被關(guān)閉了的,你需要設(shè)置一個(gè)環(huán)境變量來開啟這個(gè)機(jī)制,即:
$ export DOCKER_CONTENT_TRUST=11
當(dāng)content trust機(jī)制被開啟后,docker不會(huì)pull驗(yàn)證失敗或者沒有簽名的鏡像標(biāo)簽。當(dāng)然也可以通過在pull時(shí)加上--disable-content-trust來暫時(shí)取消這個(gè)限制。
3Apparmor的MAC訪問控制
AppArmor和SELinux都是Linux安全模塊,可以將進(jìn)程的權(quán)限與進(jìn)程capabilities能力聯(lián)系在了一起,實(shí)現(xiàn)對(duì)進(jìn)程的強(qiáng)制性訪問控制(MAC)。由于SELinux有點(diǎn)復(fù)雜,經(jīng)常都被人直接關(guān)閉,而AppArmor就相對(duì)要簡(jiǎn)單點(diǎn)。Docker官方也推薦這種方式。
Docker 自動(dòng)為容器生成并加載名為 docker-default 的默認(rèn)配置文件。在 Docker 1.13.0和更高版本中,Docker 二進(jìn)制文件在 tmpfs 中生成該配置文件,然后將其加載到內(nèi)核中。在早于 1.13.0 的 Docker 版本上,此配置文件將在 /etc/apparmor.d/docker 中生成。docker-default 配置文件是運(yùn)行容器的默認(rèn)配置文件。它具有適度的保護(hù)性,同時(shí)提供廣泛的應(yīng)用兼容性。
注意:這個(gè)配置文件用于容器而不是 Docker 守護(hù)進(jìn)程。運(yùn)行容器時(shí)會(huì)使用 docker-default 策略,除非通過 security-opt 選項(xiàng)覆蓋。
下面我們使用Nginx做演示,提供一個(gè)自定義AppArmor 配置文件:
1、創(chuàng)建自定義配置文件,假設(shè)文件路徑為 /etc/apparmor.d/containers/docker-nginx 。
#include <tunables/global>
profile docker-nginx flags=(attach_disconnected,mediate_deleted) {
#include <abstractions/base>
...
deny network raw,
...
deny /bin/** wl,
deny /root/** wl,
deny /bin/sh mrwklx,
deny /bin/dash mrwklx,
deny /usr/bin/top mrwklx,
...
}
△左右滑動(dòng)看全部△
2、加載配置文件
$ sudo apparmor_parser -r -W /etc/apparmor.d/containers/docker-nginx
3、使用這個(gè)配置文件運(yùn)行容器
$ docker run --security-opt "apparmor=docker-nginx" -p 80:80 -d --name apparmor-nginx nginx12
4、進(jìn)入運(yùn)行中的容器中,嘗試一些操作來測(cè)試配置是否生效:
$ docker container exec -it apparmor-nginx bash2
root@6da5a2a930b9:~# ping 8.8.8.8
ping: Lacking privilege for raw socket.
root@6da5a2a930b9:/# top
bash: /usr/bin/top: Permission denied
root@6da5a2a930b9:~# touch ~/thing
touch: cannot touch 'thing': Permission denied
root@6da5a2a930b9:/# sh
bash: /bin/sh: Permission denied
可以看到,我們通過 apparmor 配置文件可以對(duì)容器進(jìn)行保護(hù)。
4Seccomp系統(tǒng)調(diào)用過濾
Seccomp是Linux kernel 從2.6.23版本開始所支持的一種安全機(jī)制,可用于限制進(jìn)程能夠調(diào)用的系統(tǒng)調(diào)用(system call)的范圍。在Linux系統(tǒng)里,大量的系統(tǒng)調(diào)用(systemcall)直接暴露給用戶態(tài)程序,但是,并不是所有的系統(tǒng)調(diào)用都被需要,而且不安全的代碼濫用系統(tǒng)調(diào)用會(huì)對(duì)系統(tǒng)造成安全威脅。通過Seccomp,我們限制程序使用某些系統(tǒng)調(diào)用,這樣可以減少系統(tǒng)的暴露面,同時(shí)使程序進(jìn)入一種“安全”的狀態(tài)。每個(gè)進(jìn)程進(jìn)行系統(tǒng)調(diào)用(system call)時(shí),kernel 都會(huì)檢查對(duì)應(yīng)的白名單以確認(rèn)該進(jìn)程是否有權(quán)限使用這個(gè)系統(tǒng)調(diào)用。從Docker1.10版本開始,Docker安全特性中增加了對(duì)Seccomp的支持。
使用Seccomp的前提是Docker構(gòu)建時(shí)已包含了Seccomp,并且內(nèi)核中的CONFIG_SECCOMP已開啟。可使用如下方法檢查內(nèi)核是否支持Seccomp:
$ cat /boot/config-`uname -r` | grep CONFIG_SECCOMP=
CONFIG_SECCOMP=y
默認(rèn)的 seccomp 配置文件為使用 seccomp 運(yùn)行容器提供了一個(gè)合理的設(shè)置,并禁用了大約 44 個(gè)超過 300+ 的系統(tǒng)調(diào)用。它具有適度的保護(hù)性,同時(shí)提供廣泛的應(yīng)用兼容性。默認(rèn)的 Docker 配置文件可以在moby源碼profiles/seccomp/下找到。
默認(rèn)seccomp profile片段如下:
{
"defaultAction": "SCMP_ACT_ERRNO",
"archMap": [
{
"architecture": "SCMP_ARCH_X86_64",
"subArchitectures": [
"SCMP_ARCH_X86",
"SCMP_ARCH_X32"
]
},=
...
],
"syscalls": [
{
"names": [
"reboot"
],
"action": "SCMP_ACT_ALLOW",
"args": [],
"comment": "",
"includes": {
"caps": [
"CAP_SYS_BOOT"
]
},
"excludes": {}
},
...
]
}
seccomp profile包含3個(gè)部分:默認(rèn)操作,系統(tǒng)調(diào)用所支持的Linux架構(gòu)和系統(tǒng)調(diào)用具體規(guī)則(syscalls)。對(duì)于每個(gè)調(diào)用規(guī)則,其中name是系統(tǒng)調(diào)用的名稱,action是發(fā)生系統(tǒng)調(diào)用時(shí)seccomp的操作,args是系統(tǒng)調(diào)用的參數(shù)限制條件。比如上面的“SCMP_ACT_ALLOW”action代表這個(gè)進(jìn)程這個(gè)系統(tǒng)調(diào)用被允許,這個(gè)call,允許進(jìn)程可以重啟系統(tǒng)。
實(shí)際上,該配置文件是白名單,默認(rèn)情況下阻止訪問所有的系統(tǒng)調(diào)用,然后將特定的系統(tǒng)調(diào)用列入白名單。
seccomp 有助于以最小權(quán)限運(yùn)行 Docker 容器。不建議更改默認(rèn)的 seccomp 配置文件。
運(yùn)行容器時(shí),如果沒有通過 --security-opt 選項(xiàng)覆蓋容器,則會(huì)使用默認(rèn)配置。例如,以下顯式指定了一個(gè)策略:
$ docker run --rm \
-it \
--security-opt seccomp=/path/to/seccomp/profile.json \
hello-seccomp
感謝各位的閱讀,以上就是“Docker的安全性支持舉例分析”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)Docker的安全性支持舉例分析這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。