Docker 和 Kubernetes 中的 root 與 privileged
我們大多數(shù)熟悉 Unix 類系統(tǒng)的人,都習(xí)慣于通過使用 sudo 來隨意提升自己的權(quán)限,成為 root 用戶。我們在使用 Docker 容器的過程中知道,他提供了一個 --privileged 的參數(shù),其實(shí)它與隨意使用 sudo 有很大的不同,它可能會讓你的應(yīng)用程序面臨不必要的風(fēng)險(xiǎn),下面我們將向你展示這與以 root 身份運(yùn)行的區(qū)別,以及特權(quán)的實(shí)際含義。
作為 Root 運(yùn)行
Docker 允許在其宿主機(jī)上隔離一個進(jìn)程、capabilities 和文件系統(tǒng),但是大多數(shù)容器實(shí)際上都是默認(rèn)以 root 身份運(yùn)行。這里我們拿 DockerHub 上幾個比較流行的鏡像來進(jìn)行說明。
Postgres:
$?docker?run?-it?postgres
#?whoami
root
#?id?-u
0
Couchbase:
$?docker?run?-it?couchbase?sh
#?whoami
root
#?id?-u
0
Alpine:
$?docker?run?-it?alpine?sh
#?whoami
root
#?id?-u
0
我們可以看到這幾個鏡像默認(rèn)都是以 root 身份運(yùn)行,這樣當(dāng)然更容易調(diào)試,特別是當(dāng)你要 exec 到容器中時,但最好的情況還是應(yīng)該避免以 root 身份運(yùn)行。
避免以 root 運(yùn)行
雖然在容器內(nèi)以 root 身份運(yùn)行是很正常的,但如果你想加固你的容器,還是應(yīng)該避免這樣做。首先,,其次,容器將成為運(yùn)行 Docker 命令的同一用戶命名空間的一部分,如果容器能夠逃逸,它將可以訪問相同的資源,比如 volumes 和 sockets。
這里我們有兩種方法可以避免以 root 身份運(yùn)行。
通過在 Dockerfile 文件中指定 user 用戶:
//?DockerfileFROM?microsoft/windowsservercore
#?Create?Windows?user?in?the?container
RUN?net?user?/add?patrick
#?Set?it?for?subsequent?commands
USER?patrick
運(yùn)行容器的時候覆蓋用戶 ID:
$?docker?run?-it?--user?4000?postgres?sh
#?whoami
whoami:?cannot?find?name?for?user?ID?4000
#?id?-u
4000
特權(quán)模式
--privileged 標(biāo)志可以將我們前面看到的0的用戶 ID 直接映射到主機(jī)的用戶 ID 0上,使其可以不受限制地訪問任何自己的系統(tǒng)調(diào)用。在正常的操作中,即使容器內(nèi)有 root,Docker 也會限制容器的 Linux Capabilities 的,這種限制包括像 CAP_AUDIT_WRITE 這樣的東西,它允許覆蓋內(nèi)核的審計(jì)日志--你的容器化工作負(fù)載很可能不需要這個 Capabilities。所以特權(quán)只應(yīng)該在你真正需要它的特定設(shè)置中使用,簡而言之,它給容器提供了幾乎所有主機(jī)(作為root)可以做的事情的權(quán)限。
本質(zhì)上,它就是一個免費(fèi)的通行證,可以逃避容器所包含的文件系統(tǒng)、進(jìn)程、sockets ?套接字等,當(dāng)然它有特定的使用場景,比如在很多 CI/CD 系統(tǒng)中需要的 Docker IN Docker 模式(在 Docker 容器內(nèi)部需要 Docker 守護(hù)進(jìn)程),以及需要極端網(wǎng)絡(luò)的地方。即便如此,也有一些方法可以避免使用特權(quán)模式,例如,我們可以使用谷歌創(chuàng)建的名為 Kaniko 的工具來替代特權(quán)模式的容器。
下面讓我們看一個使用 Ubuntu 鏡像的例子。
在沒有特權(quán)的情況下:
$?docker?run?-it?ubuntu?sh
#?whoami
root?#?注意這里,仍然是?root?用戶
#?id?-u
0
#?hostname
382f1c400bd
#?sysctl?kernel.hostname=Attacker
sysctl:?setting?key?"kernel.hostname":?Read-only?file?system??#?Yet?we?can't?do?this
特權(quán)模式:
$?docker?run?-it?--privileged?ubuntu?sh
#?whoami
root.?#?Root?again
#?id?-u
0
#?hostname
86c62e9bba5e
#?sysctl?kernel.hostname=Attacker
kernel.hostname?=?Attacker?#?Except?now?we?are?privileged
#?hostname
Attacker
如果我們在 Kubernetes 中要使用的話可以使用 SecurityContext 來進(jìn)行配置:
apiVersion:?v1
kind:?Pod
metadata:
??name:?nginx
spec:
??containers:
??-?name:?nginx
????image:?nginx
????securityContext:
??????privileged:?true
此外 Kubernetes 還包含一個名為 PodSecurityPolicy 的資源對象,它是一個準(zhǔn)入控制器(Kubernetes 在允許容器進(jìn)入集群之前會它進(jìn)行檢查),強(qiáng)烈建議的一項(xiàng)策略就是配置不允許特權(quán)模式的 Pod。
apiVersion:?policy/v1beta1
kind:?PodSecurityPolicy
metadata:
??name:?example
spec:
??privileged:?false??#?禁止特權(quán)模式
總結(jié)
最后希望你對 root 用戶和 --privileged 標(biāo)志以及它們與宿主機(jī)的關(guān)系有了更多的認(rèn)識。我們可以通過不以 root 用戶運(yùn)行、不以特權(quán)模式運(yùn)行以及添加 SecurityContext 和 PodSecurityPolicy 來實(shí)現(xiàn)更高的容器安全。
“原文鏈接:https://itnext.io/docker-and-kubernetes-root-vs-privileged-9d2a37453dec
”
?點(diǎn)擊屏末?|?閱讀原文?|?即刻學(xué)習(xí)