Docker容器的root用户
Docker 是 Linux 平臺上容器的管理引擎,其提供的容器服務(wù)一方面可以很好地分配物理資源,不論是資源還是權(quán)限都能夠達(dá)到隔離的效果;另一方面,Docker 的設(shè)計(jì)把更多的目光投向了「應(yīng)用」本身,簡化了應(yīng)用從開發(fā)、測試、發(fā)布等迭代發(fā)展的生命周期。
Docker 帶著「重新定義應(yīng)用」的豪言,沖擊著大家對軟件的理解,在云計(jì)算領(lǐng)域更是如此。然而,新技術(shù)的誕生往往需要接受行業(yè)千錘百煉似的考驗(yàn),安全無疑是業(yè)界最關(guān)心的因素之一。傳統(tǒng)的硬件虛擬化等技術(shù)發(fā)展了數(shù)十年,逐漸步入成熟期,成為如今云計(jì)算技術(shù)的中堅(jiān)技術(shù),其高隔離性自然是保障安全的首要功臣;對于應(yīng)用而言,安全問題尤為嚴(yán)峻,系統(tǒng)業(yè)務(wù)核心幾乎全部通過應(yīng)用來實(shí)現(xiàn),應(yīng)用的安全一旦失守,后果不堪設(shè)想。
正視安全,Docker 無法回避。在眾多安全性考量中,有一點(diǎn)經(jīng)常被 Docker 實(shí)踐者提起,那就是 Docker 容器的 root 安全性。由于截止到目前的 docker 1.8.3 版本,Docker 依然沒有完成對 Linux User Namespace 的支持,因此對于 Docker 容器而言,容器內(nèi)部的 root 和宿主機(jī)上的 root 屬于同一個用戶,兩者的 UID 均為 0。容器中的超級用戶,是否會影響其他容器,乃至宿主機(jī),自然成了大家最關(guān)心的安全問題。
Docker 容器 root 和宿主機(jī) root
意識到 Docker 容器內(nèi)的 root 用戶屬于超級用戶之外,更多的憂慮逐漸表露,比如「使用 root 用戶運(yùn)行 Docker 容器內(nèi)部的應(yīng)用,是否安全?」,比如「容器內(nèi)的 root 是否可以操縱宿主機(jī)資源?」……
如果 Docker 容器內(nèi)的 root 用戶和宿主機(jī)的 root 用戶完全一致,那么 Docker 容器可以認(rèn)為在權(quán)限方面擁有宿主機(jī)上 root 相應(yīng)的權(quán)限,此時的 Docker 容器擁有超級管理員權(quán)限,原則上 Docker 容器本身完全有能力操縱宿主機(jī)的一切。然而,結(jié)果真是如此嗎?
答案自然是否定的,否則的話,Docker 的安全簡直不堪一擊。雖然 Docker 容器內(nèi)的 root 用戶直接是宿主機(jī)的 root 用戶,但是 Docker 可以保證兩者在權(quán)限方面,擁有巨大的差異。此時,這種差異的存在完全是借助于Linux 內(nèi)核的 Capabilities 機(jī)制。換言之,正是 Capabilities 在保障 Docker 容器的安全性。
Capabilities 在 Docker 容器的管理過程中使用非常方便。如果不需要授予 Docker 容器足夠的系統(tǒng)權(quán)限,也就是足夠的 Capabilities,只需在運(yùn)行 Docker 容器時不使用 --privileged 參數(shù),如:
docker run -it --priviledged=false ubuntu:14.04 /bin/bash或者
docker run -it ubuntu:14.04 /bin/bash如果需要授予 Docker 容器足夠的管理權(quán)限,則直接將 --privileged 參數(shù)設(shè)為 true,如:
docker run -it --privileged=true ubuntu:14.04 /bin/bash另外,在 docker run 命令中,添加 --cap-add 以及 --cap-drop 參數(shù)也完全可以更靈活的添加以及移除 Linux Capabilities。
Linux Capabilities
既然 Docker 采用了 Linux Capabilities 機(jī)制,那么何為 Linux Capabilities,我們來一探究竟。
大家一定知道,在傳統(tǒng)的 Unix 系統(tǒng)中,為了實(shí)現(xiàn)權(quán)限的檢查,操作系統(tǒng)上運(yùn)行的進(jìn)程可以分為兩種:特權(quán)進(jìn)程(priviledged processes) 和非特權(quán)進(jìn)程(unpriviledged processes) 。其中,前者的有效用戶 ID 為 0,也就是大家常說的超級用戶或者 root 用戶,而后者的有效用戶 ID 為非 0,也常被稱為普通用戶。特權(quán)進(jìn)程在運(yùn)行時可以繞過所有的內(nèi)核權(quán)限檢查,而非特權(quán)進(jìn)程則必須完全接受這些檢查。
雖然如此,然而實(shí)際情況要比以上的描述復(fù)雜一些。實(shí)際情況下,Linux 會將傳統(tǒng)超級用戶的特權(quán)劃分為多個單位,也就是我們關(guān)心的 Capabilties。Capabilities 會有很多種,而且對于 root 用戶而言,完全可以單獨(dú)啟用或者關(guān)閉,因此同為 root 用戶,權(quán)限卻因 Capabilities 的不同而存在差異。
Linux Capabilities 機(jī)制將超級用戶的權(quán)限劃分非常之細(xì),所有的 Capabilities 列表有接近 40 項(xiàng)之多。我們可以通過幾個具體的 Capability 來看看他們各自管理的權(quán)限范圍。
- CAP_SYS_ADMIN:CAP_SYS_ADMIN 實(shí)現(xiàn)一系列的系統(tǒng)管理權(quán)限,比如實(shí)現(xiàn)磁盤配額的 quotactl,實(shí)現(xiàn)文件系統(tǒng)掛載的 mount 權(quán)限;比如在 fork 子進(jìn)程時,通過 clone 和 unshare 系統(tǒng)調(diào)用,使用 CLONE_* 的 flag 參數(shù)來為子進(jìn)程創(chuàng)建新的 namespaces;比如實(shí)現(xiàn)各種特權(quán)塊設(shè)備以及文件系統(tǒng)的 ioctl 操作等。
- CAP_NET_ADMIN:CAP_NET_ADMIN 實(shí)現(xiàn)一系列的網(wǎng)絡(luò)管理權(quán)限,比如網(wǎng)絡(luò)設(shè)備的配置,IP 防火墻,IP 偽裝以及統(tǒng)計(jì)等功能;比如路由表的修改,TOS 的配置,混雜模式的配置等。
- CAP_SETUID:CAP_SETUID 有能力對進(jìn)程 UID 做出任何管控。
- CAP_SYS_MODULE:CAP_SYS_MODULE 幫助 root 用戶加載或者卸載相應(yīng)的 Linux 內(nèi)核模塊。
- CAP_SYS_NICE:CAP_SYS_NICE 有能力對任意進(jìn)程修改其 NICE 值,同時支持對任何進(jìn)程設(shè)置調(diào)度策略與優(yōu)先級,還有在進(jìn)程的 CPU 親和性以及 I/O 調(diào)度方面有相應(yīng)的配置權(quán)限。
……
Linux 總共有接近 40 項(xiàng)的 Capabilities,然而初步接觸以上 5 項(xiàng) Capabilties,我們可以發(fā)現(xiàn):Linux 對于超級用戶的特權(quán)也進(jìn)行了種類繁多的劃分,有劃分就意味著有區(qū)別,有區(qū)別就意味著并不是所有的 root 用戶都擁有相同的權(quán)限.
那么 Linux Capabilties 與 Docker 容器的關(guān)系究竟如何?
Docker 容器與 Linux Capabilities
大家已經(jīng)清楚 Docker 容器中的 root 用戶與宿主機(jī)的 root 用戶同屬一個 uid,均為 0;并且大家也可以發(fā)現(xiàn)不同的 Capabilities 可以區(qū)分 root 用戶的權(quán)限,那么 Docker 容器中的 root 用戶的 Capabilities 情況到底是什么樣,這種現(xiàn)狀會存在安全隱患嗎?
上文已經(jīng)涉及了 docker run 命令創(chuàng)建容器時 privileged 參數(shù)的用法,實(shí)際上 Docker 容器的Capabilties 情況也會因用戶設(shè)置而異。
Docker 容器的非特權(quán)模式
默認(rèn)情況下,docker run 命令的 privileged 參數(shù)值為 false。因此,毫無疑問,Docker 容器內(nèi)部的 root 用戶將受到嚴(yán)格的權(quán)限限制,很多有系統(tǒng)相關(guān)的操作權(quán)限都將被剝奪,只具備超級用戶的一些基本權(quán)限。
研究 Docker 的源碼,我們可以發(fā)現(xiàn):在 Linux 接近40項(xiàng)的 Capabilities 中,Docker為了確保容器的安全,僅僅支持了其中的14項(xiàng)基本的 Capabilities ,現(xiàn)在,我們不妨來看看這些 Capabilities 到底有哪些,它們分別是: CAP_CHOWN 、 CAP_DAC_OVERRIDE 、 CAP_FSETID 、 CAP_MKNOD 、 FOWNER 、 NET_RAW 、 SETGID 、 SETUID 、 SETFCAP 、 SETPCAP 、 NET_BIND_SERVICE 、 SYS_CHROOT 、 KILL 和 AUDIT_WRITE 。
我們可以發(fā)現(xiàn):在這 14 項(xiàng)中幾乎沒有一項(xiàng)涉及到系統(tǒng)管理權(quán)限,比如 Docker 容器的 root 用戶不具備 CAP_SYS_ADMIN,磁盤限額操作、mount 操作、創(chuàng)建進(jìn)程新命名空間等均無法實(shí)現(xiàn);比如由于沒有 CAP_NET_ADMIN,網(wǎng)絡(luò)方面的配置管理也將受到管制。因此,默認(rèn)情況下,Docker 容器中的 root 用戶并沒有以往我們想象得那么能力超群,Docker 依然對其存在限制,這樣設(shè)計(jì)的出發(fā)點(diǎn)之一自然是安全。
Docker 容器的特權(quán)模式
了解完 Docker 容器的非特權(quán)模式,大家也許會覺得 Docker 容器的 root 權(quán)限被削減得有點(diǎn)難以置信,確保安全,卻剝奪了過多系統(tǒng)權(quán)限 。其實(shí),Docker 作為一個管理容器的工具,并未在容器 root 方面「一刀切」,Docker 容器的非特權(quán)模式就可以滿足 root 用戶的權(quán)限最大化。
一旦將 docker run 命令的 privileged 參數(shù)設(shè)為 true,那么 Docker 容器的 root 權(quán)限將得到大幅度的提升。此時,Docker容器的 root 用戶將獲得 37 項(xiàng) Capabilities 能力。由于 Docker 容器與宿主機(jī)處于共享同一個內(nèi)核操作系統(tǒng)的狀態(tài),因此,Docker 容器將完全擁有內(nèi)核的管理權(quán)限 。安全隱患,瞬間浮出水面。
兩種模式的比較
Docker 容器的實(shí)踐,不能缺少場景。談到以上兩種模式的比較,場景更是如此。安全與權(quán)限,孰輕孰重,魚與熊掌,是否可以兼得?
云計(jì)算領(lǐng)域,公有云一向被認(rèn)為是一項(xiàng)技術(shù)甚至一種產(chǎn)品的試金石。Docker 這項(xiàng)技術(shù)更是需要在公有云領(lǐng)域展現(xiàn)自己的價值。安全這個話題,在公有云中尤為敏感,這一點(diǎn)相信已經(jīng)毋庸贅言。那么,在安全至上的情況下,開啟 Docker 容器的特權(quán)模式將完全不現(xiàn)實(shí),如此一來,Docker 容器的權(quán)限將不得不做出妥協(xié)。Docker 技術(shù)在公有云領(lǐng)域,不論服務(wù)于 PaaS,還是目前興起的 CaaS,權(quán)限的削減是否會影響這兩種云計(jì)算模式?
Docker 容器 root 用戶權(quán)限的缺失,主要還是集中于系統(tǒng)管理方面。那我們就從系統(tǒng)管理權(quán)限 ,來分析 PaaS 和 CaaS 對 Docker 需求的區(qū)別。
PaaS:Docker 作為 PaaS 技術(shù)的底層技術(shù),完全有能力支撐起用戶應(yīng)用的運(yùn)行。對于提供運(yùn)行時環(huán)境而言,應(yīng)用將無需過多的與系統(tǒng)管理相關(guān)聯(lián);同時,從應(yīng)用本身出發(fā),高移植性應(yīng)該是重要的設(shè)計(jì)目標(biāo)之一,過多的與系統(tǒng)耦合同樣將會帶來運(yùn)維成本。
CaaS:CaaS 與 PaaS 最大的區(qū)別,在于 CaaS 帶來的服務(wù)模式要更廣。CaaS 中容器的范疇很廣,完全可以不限于用戶應(yīng)用的運(yùn)行。CaaS 中 Docker 的自足點(diǎn)將不再是專注于應(yīng)用本身,而是將計(jì)算資源的管理也圈入其內(nèi),比如提供類似于傳統(tǒng)虛擬機(jī)的計(jì)算單元。由于為了安全,無法提供與虛擬機(jī) root 用戶相同的權(quán)限,因此 Docker 容器的權(quán)限問題將無情暴露,CaaS 的服務(wù)質(zhì)量必將受到影響。
Docker與Linux User Namespace
Docker 容器的 root 安全嗎?相信大家已經(jīng)有了一定的認(rèn)識。這個問題,其實(shí)并不是僅僅涉及安全這一個話題,而是一種安全與權(quán)限的博弈 。既然如此,難道就只能取舍,魚和熊掌,不可兼得嗎?
答案是否定的。Linux User Namespace 的支持將大大緩解這種情況。(目前,docker 1.8.3 仍未支持 User Namespace。)一旦完成對 Linux User Namespace 的支持,Docker 容器內(nèi)部的 root 用戶在宿主機(jī)看來 UID 將不再是 0,換言之,在宿主機(jī)上僅僅是一個普通用戶,而在 Docker 容器內(nèi)部,原則上可以應(yīng)用更多的 Capabilities,實(shí)現(xiàn)權(quán)限的提升。Docker 與 Linux User Namespace 的淵源,后續(xù)我們再深入。
總結(jié)
Docker 容器中 root 用戶的安全性一直備受關(guān)注。安全性問題,并未想象中的那么壞,當(dāng)然也絕對不是無懈可擊,更多的是一種安全與權(quán)限的博弈 。
Docker 大潮一波高過一波,我們沒有理由懷疑 Docker 的未來。Docker 對 Linux User Namespace 的支持也是萬眾矚目。User Namespace 不僅能夠從 Capabilities 的角度提升 Docker 容器 root 的容器內(nèi)系統(tǒng)權(quán)限,而且也有能力對 ulimit 的支持更加完善。理論上,User Namespace 對于安全與隔離是存在巨大的共享,但是這也僅僅是一種極大的緩解。緣何如此,根在共享內(nèi)核。
轉(zhuǎn)載自:https://www.cnblogs.com/shoufu/p/14454793.html
超強(qiáng)干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生總結(jié)
以上是生活随笔為你收集整理的Docker容器的root用户的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux Capabilities 入
- 下一篇: RAP2工具的应用