亚洲全黄无码一级在线看_国产剧情久久久性色_无码av一区二区三区无码_亚洲成a×人片在线观看

當(dāng)前位置: 首頁 > 科技新聞 >

Podman和用戶名字空間:天作之合

時間:2019-11-13 04:55來源:網(wǎng)絡(luò)整理 瀏覽:
了解如何使用 Podman 在單獨的用戶空間運行容器。 Podman 是 libpod 庫的一部分,使用戶能夠管理 pod、容器和容器鏡像

Podman和用戶名字空間:天作之合

了解如何使用 Podman 在單獨的用戶空間運行容器。

Podman 是 libpod 庫的一部分,使用戶能夠管理 pod、容器和容器鏡像。在我的上一篇文章中,我寫過將 Podman 作為一種更安全的運行容器的方式。在這里,我將解釋如何使用 Podman 在單獨的用戶命名空間中運行容器。

作為分離容器的一個很棒的功能,我一直在思考用戶命名空間user namespace,它主要是由 Red Hat 的 Eric Biederman 開發(fā)的。用戶命名空間允許你指定用于運行容器的用戶標(biāo)識符(UID)和組標(biāo)識符(GID)映射。這意味著你可以在容器內(nèi)以 UID 0 運行,在容器外以 UID 100000 運行。如果容器進程逃逸出了容器,內(nèi)核會將它們視為以 UID 100000 運行。不僅如此,任何未映射到用戶命名空間的 UID 所擁有的文件對象都將被視為 nobody 所擁有(UID 是 65534, 由 kernel.overflowuid 指定),并且不允許容器進程訪問,除非該對象可由“其他人”訪問(即世界可讀/可寫)。

如果你擁有一個權(quán)限為 660 的屬主為“真實” root 的文件,而當(dāng)用戶命名空間中的容器進程嘗試讀取它時,會阻止它們訪問它,并且會將該文件視為 nobody 所擁有。

示例

以下是它是如何工作的。首先,我在 root 擁有的系統(tǒng)中創(chuàng)建一個文件。

 

接下來,我將該文件卷掛載到一個使用用戶命名空間映射 0:100000:5000 運行的容器中。

 

上面的 --uidmap 設(shè)置告訴 Podman 在容器內(nèi)映射一系列的 5000 個 UID,從容器外的 UID 100000 開始的范圍(100000-104999)映射到容器內(nèi) UID 0 開始的范圍(0-4999)。在容器內(nèi)部,如果我的進程以 UID 1 運行,則它在主機上為 100001。

由于實際的 UID=0 未映射到容器中,因此 root 擁有的任何文件都將被視為 nobody 所擁有。即使容器內(nèi)的進程具有 CAP_DAC_OVERRIDE 能力,也無法覆蓋此種保護。DAC_OVERRIDE 能力使得 root 的進程能夠讀/寫系統(tǒng)上的任何文件,即使進程不是 root 用戶擁有的,也不是全局可讀或可寫的。

用戶命名空間的功能與宿主機上的功能不同。它們是命名空間的功能。這意味著我的容器的 root 只在容器內(nèi)具有功能 —— 實際上只有該范圍內(nèi)的 UID 映射到內(nèi)用戶命名空間。如果容器進程逃逸出了容器,則它將沒有任何非映射到用戶命名空間的 UID 之外的功能,這包括 UID=0。即使進程可能以某種方式進入另一個容器,如果容器使用不同范圍的 UID,它們也不具備這些功能。

請注意,SELinux 和其他技術(shù)還限制了容器進程破開容器時會發(fā)生的情況。

使用 podman top 來顯示用戶名字空間

我們在 podman top 中添加了一些功能,允許你檢查容器內(nèi)運行的進程的用戶名,并標(biāo)識它們在宿主機上的真實 UID。

讓我們首先使用我們的 UID 映射運行一個 sleep 容器。

 

現(xiàn)在運行 podman top

 

注意 podman top 報告用戶進程在容器內(nèi)以 root 身份運行,但在宿主機(HUSER)上以 UID 100000 運行。此外,ps 命令確認(rèn) sleep 過程以 UID 100000 運行。

現(xiàn)在讓我們運行第二個容器,但這次我們將選擇一個單獨的 UID 映射,從 200000 開始。

 

請注意,podman top 報告第二個容器在容器內(nèi)以 root 身份運行,但在宿主機上是 UID=200000。

另請參閱 ps 命令,它顯示兩個 sleep 進程都在運行:一個為 100000,另一個為 200000。

這意味著在單獨的用戶命名空間內(nèi)運行容器可以在進程之間進行傳統(tǒng)的 UID 分離,而這從一開始就是 Linux/Unix 的標(biāo)準(zhǔn)安全工具。

用戶名字空間的問題

幾年來,我一直主張用戶命名空間應(yīng)該作為每個人應(yīng)該有的安全工具,但幾乎沒有人使用過。原因是沒有任何文件系統(tǒng)支持,也沒有一個移動文件系統(tǒng)shifting file system。

在容器中,你希望在許多容器之間共享基本鏡像。上面的每個示例中使用了 Fedora 基本鏡像。Fedora 鏡像中的大多數(shù)文件都由真實的 UID=0 擁有。如果我在此鏡像上使用用戶名稱空間 0:100000:5000 運行容器,默認(rèn)情況下它會將所有這些文件視為 nobody 所擁有,因此我們需要移動所有這些 UID 以匹配用戶名稱空間。多年來,我想要一個掛載選項來告訴內(nèi)核重新映射這些文件 UID 以匹配用戶命名空間。上游內(nèi)核存儲開發(fā)人員還在繼續(xù)研究,在此功能上已經(jīng)取得一些進展,但這是一個難題。

由于由 Nalin Dahyabhai 領(lǐng)導(dǎo)的團隊開發(fā)的自動 chown 內(nèi)置于容器/存儲中,Podman 可以在同一鏡像上使用不同的用戶名稱空間。當(dāng) Podman 使用容器/存儲,并且 Podman 在新的用戶命名空間中首次使用一個容器鏡像時,容器/存儲會 “chown”(如,更改所有權(quán))鏡像中的所有文件到用戶命名空間中映射的 UID 并創(chuàng)建一個新鏡像??梢园阉胂蟪梢粋€ fedora:0:100000:5000 鏡像。

當(dāng) Podman 在具有相同 UID 映射的鏡像上運行另一個容器時,它使用“預(yù)先 chown”的鏡像。當(dāng)我在0:200000:5000 上運行第二個容器時,容器/存儲會創(chuàng)建第二個鏡像,我們稱之為 fedora:0:200000:5000。

請注意,如果你正在執(zhí)行 podman buildpodman commit 并將新創(chuàng)建的鏡像推送到容器注冊庫,Podman 將使用容器/存儲來反轉(zhuǎn)該移動,并將推送所有文件屬主變回真實 UID=0 的鏡像。

這可能會導(dǎo)致在新的 UID 映射中創(chuàng)建容器時出現(xiàn)真正的減速,因為 chown 可能會很慢,具體取決于鏡像中的文件數(shù)。此外,在普通的 OverlayFS 上,鏡像中的每個文件都會被復(fù)制。普通的 Fedora 鏡像最多可能需要 30 秒才能完成 chown 并啟動容器。

幸運的是,Red Hat 內(nèi)核存儲團隊(主要是 Vivek Goyal 和 Miklos Szeredi)在內(nèi)核 4.19 中為 OverlayFS 添加了一項新功能。該功能稱為“僅復(fù)制元數(shù)據(jù)”。如果使用 metacopy=on 選項來掛載層疊文件系統(tǒng),則在更改文件屬性時,它不會復(fù)制較低層的內(nèi)容;內(nèi)核會創(chuàng)建新的 inode,其中包含引用指向較低級別數(shù)據(jù)的屬性。如果內(nèi)容發(fā)生變化,它仍會復(fù)制內(nèi)容。如果你想試用它,可以在 Red Hat Enterprise Linux 8 Beta 中使用此功能。

這意味著容器 chown 可能在兩秒鐘內(nèi)發(fā)生,并且你不會倍增每個容器的存儲空間。

這使得像 Podman 這樣的工具在不同的用戶命名空間中運行容器是可行的,大大提高了系統(tǒng)的安全性。

前瞻

我想向 Podman 添加一個新選項,比如 --userns=auto,它會為你運行的每個容器自動選擇一個唯一的用戶命名空間。這類似于 SELinux 與單獨的多類別安全(MCS)標(biāo)簽一起使用的方式。如果設(shè)置環(huán)境變量 PODMAN_USERNS=auto,則甚至不需要設(shè)置該選項。

Podman 最終允許用戶在不同的用戶名稱空間中運行容器。像 Buildah 和 CRI-O 這樣的工具也可以利用用戶命名空間。但是,對于 CRI-O,Kubernetes 需要了解哪個用戶命名空間將運行容器引擎,上游正在開發(fā)這個功能。

在我的下一篇文章中,我將解釋如何在用戶命名空間中將 Podman 作為非 root 用戶運行。

【責(zé)任編輯:龐桂玉 TEL:(010)68476606】
推薦內(nèi)容