十大 Docker 優(yōu)秀實踐,望君遵守!!
本文是關(guān)于容器安全的文章,展示了 10 種強化 Docker 基礎(chǔ)架構(gòu)并保護容器和數(shù)據(jù)免受惡意攻擊的方法。
介紹
隨著許多公司在其基礎(chǔ)設(shè)施中采用 Docker,威脅參與者的攻擊面也增加了。這就需要保護 Docker 基礎(chǔ)設(shè)施。在本文中,提到了一些可以加強 Docker 容器安全性的要點。
要充分利用本文,必須具備以下條件:
- 熟悉 Linux 命令行
- 關(guān)于容器化和 Docker 的基本概念
什么是 Docker?
Docker 是一個開源容器化平臺。它允許開發(fā)人員將應(yīng)用程序打包到容器中:標(biāo)準(zhǔn)化的可執(zhí)行組件將應(yīng)用程序源代碼與在運行該代碼所需的操作系統(tǒng) (OS) 庫和依賴項相結(jié)合。
十大優(yōu)秀實踐
Docker 文檔概述了在保護 Docker 容器時要考慮的四個主要方面:
- 內(nèi)核對命名空間和 cgroup 的支持
- Docker 守護進程的攻擊面
- 容器配置錯誤
- 使用 AppArmor、SELinux 等 Linux 內(nèi)核安全模塊等
我們將這些分解為可以遵循的 10 大實踐來強化 Docker 環(huán)境。
1. 經(jīng)常更新主機和 Docker 守護進程
容器與主機系統(tǒng)共享內(nèi)核。在容器上下文中執(zhí)行的任何內(nèi)核漏洞都會直接影響主機內(nèi)核。內(nèi)核提權(quán)漏洞 Dirty Cow 在容器中執(zhí)行時會導(dǎo)致對主機的 root 訪問。因此,保持主機和 Docker 引擎最新很重要。
2. 不要暴露 Docker daemon socket
Docker 客戶端和 Docker 守護程序之間發(fā)生的所有通信都通過 Docker 守護程序套接字進行,這是一個 UNIX 套接字,通常位于/var/run/docker.sock,這允許訪問 Docker API。傳統(tǒng)的 UNIX 文件權(quán)限用于限制對該套接字的訪問。在默認配置中,該套接字由 root 用戶擁有。如果其他人獲得了對套接字的訪問權(quán),將擁有對主機的 root 訪問權(quán)。
- 設(shè)置權(quán)限,以便只有 root 用戶和 docker 組可以訪問 Docker 守護進程套接字
- 使用 SSH 保護 Docker 守護進程套接字
- 使用 TLS (HTTPS) 保護 Docker 守護程序套接字。這允許通過 HTTP 以安全的方式訪問 Docker
- 不要讓守護程序套接字可用于遠程連接,除非您使用 Docker 的加密 HTTPS 套接字,它支持身份驗證
- 不要使用類似的選項運行 Docker 鏡像-v /var/run/docker.sock:/var/run/docker.sock,這會在生成的容器中公開套接字。請記住,以只讀方式安裝套接字不是解決方案,只會使其更難被破壞。docker compose 文件中的一個例子是:
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
要檢查您是否已經(jīng)有一個在這種配置中運行的容器:
docker inspect --format='{{.HostConfig.Binds}}' [container id]
3. 以無 root 模式運行 Docker
可以以非 root 用戶身份運行 Docker 守護程序,以防止 Docker 中的潛在漏洞。這稱為“無 root 模式”。無 root 模式不需要 root 權(quán)限安裝 Docker 與 Docker API 通信。
在無 root 模式下,Docker 守護進程和容器在用戶命名空間中運行,默認情況下沒有 root 權(quán)限。
(1) 在無 root 模式下運行 Docker
使用 sudo 權(quán)限安裝uidmap?軟件包:
apt-get install -y uidmap
從 Docker 的網(wǎng)站獲取安裝腳本并運行:
curl -fSsL https://get.docker.com/rootless | sh
獲取無 root 安裝腳本:
復(fù)制以開頭的最后兩行export?并將它們粘貼到~/.bashrc?文件的末尾。這樣可以確保每次打開 Bash shell 時,都會設(shè)置這兩個變量:PATH? 和DOCKER_HOST。
.bashrc
運行source ~/.bashrc以在您當(dāng)前的 shell 會話中設(shè)置這些變量。
運行systemctl --user start docker以啟動 Docker 引擎。
我們可以通過運行來檢查 docker 是否正在運行docker version:
4. 容器資源配置
控制組或 cgroups 是 Linux 內(nèi)核功能,在實現(xiàn)容器的資源分配和限制方面起著關(guān)鍵作用。他們的工作不僅是確保每個容器獲得其公平份額的資源,如內(nèi)存和 CPU,而且還要確保單個容器不會因耗盡其中一個資源而導(dǎo)致系統(tǒng)崩潰。
限制資源可防止拒絕服務(wù)攻擊。以下是一些可用于限制容器資源的 CLI 標(biāo)志:
- --memory=<memory size>— 最大內(nèi)存量
- --restart=on-failure:<number_of_restarts> — 重啟次數(shù)
- --memory-swap <value>— 交換內(nèi)存量
- --cpus=<number>— 容器可用的最大 CPU 資源
- --ulimit nofile=<number>— 文件描述符的最大數(shù)量
- --ulimit nproc=<number>— 最大進程數(shù)
默認情況下,Docker 允許容器使用主機內(nèi)核允許的盡可能多的 RAM 和 CPU 資源。因此有必要設(shè)置資源約束以防止容器和主機中的安全問題。
5. 避免使用特權(quán)容器
(1) 避免使用 --privileged 標(biāo)志
Docker 具有允許容器在主機上以 root 權(quán)限運行的功能。這是通過—-privileged標(biāo)志完成的。以特權(quán)模式運行的容器對主機上的所有設(shè)備都具有 root 權(quán)限。
如果攻擊者要破壞特權(quán)容器,他們就有可能輕松訪問主機上的資源。篡改系統(tǒng)中的安全模塊(如 SELinux)也很容易。因此,不建議在開發(fā)生命周期的任何階段以特權(quán)模式運行容器。
特權(quán)容器是主要的安全風(fēng)險。濫用的可能性是無窮無盡的。攻擊者可以識別主機上運行的服務(wù)來發(fā)現(xiàn)和利用漏洞。他們還可以利用容器錯誤配置,例如具有弱憑據(jù)或沒有身份驗證的容器。特權(quán)容器為攻擊者提供 root 訪問權(quán)限,從而導(dǎo)致執(zhí)行惡意代碼。避免在任何環(huán)境中使用它們。
要檢查容器是否在特權(quán)模式下運行,請使用以下命令:
docker inspect --format='{{.HostConfig.Privileged}}' [container_id]
- true意味著容器是特權(quán)的
- false表示容器沒有特權(quán)
(2) 使用 no-new-privileges 選項
在創(chuàng)建容器時添加??no-new-privileges?
??安全選項,以禁止容器進程使用??setuid?
??或??setgid?
?二進制文件提升其權(quán)限。這可以防止容器內(nèi)的進程在執(zhí)行期間獲得新的權(quán)限。因此,如果有一個設(shè)置了 setuid 或 setgid 位的程序,任何試圖通過該程序獲得特權(quán)的操作都將被拒絕。
6. 將文件系統(tǒng)和卷設(shè)置為只讀
Docker 中一個具有安全意識的有用功能是使用只讀文件系統(tǒng)運行容器。這減少了攻擊向量,因為容器的文件系統(tǒng)不能被篡改或?qū)懭耄撬鼘ζ湮募到y(tǒng)文件和目錄具有明確的讀寫權(quán)限。
以下代碼將 Docker 容器設(shè)置為只讀:
docker run --read-only alpine sh -c 'echo "read only" > /tmp'
7. Drop capabilities
Linux 內(nèi)核能夠?qū)?root 用戶的權(quán)限分解為不同的單元,稱為 capabilities。幾乎所有與 Linux root 用戶相關(guān)的特殊權(quán)限都分解為單獨的 capabilities。
capsh 顯示的特權(quán)容器的capabilities
Docker 施加了某些限制,使得使用功能變得更加簡單。文件功能存儲在文件的擴展屬性中,并且在構(gòu)建 Docker 鏡像時會去除擴展屬性。這意味著您通常不必過多關(guān)注容器中的文件功能。
正如我們之前提到的,記住不要運行帶有--privileged標(biāo)志的容器,因為這會將所有 Linux 內(nèi)核功能添加到容器中。
最安全的設(shè)置是使用--cap-drop all 刪除所有功能,然后僅添加所需的功能。例如:
docker run --cap-drop all --cap-add CHOWN alpine
8. 使用 Linux 安全模塊
考慮使用像 seccomp 或 AppArmor 這樣的安全模塊。以下是一些眾所周知的模塊:
- Seccomp:用于允許/禁止在容器中運行的系統(tǒng)調(diào)用
- AppArmor:使用程序配置文件來限制單個程序的功能
- SELinux:使用安全策略,這是一組規(guī)則,告訴 SELinux 什么可以訪問或不能訪問,以強制執(zhí)行策略允許的訪問。
這些安全模塊可用于為進程和用戶的訪問權(quán)限提供另一個級別的安全檢查,超出標(biāo)準(zhǔn)文件級訪問控制所提供的安全檢查。
(1) seccomp
默認情況下,容器獲取默認的 seccomp 配置文件。
https://github.com/moby/moby/blob/master/profiles/seccomp/default.json
這可以用以下命令覆蓋:
docker run --rm -it --security-opt seccomp=./seccomp/profile.json hello-world
使用 Seccomp 配置文件運行容器
使用 Seccomp 配置文件,您可以選擇容器中允許哪些系統(tǒng)調(diào)用以及拒絕哪些系統(tǒng)調(diào)用,因為在生產(chǎn)環(huán)境中并非全部都需要。您可以從 Docker 文檔中了解有關(guān)編寫 seccomp 配置文件的更多信息。
(2) AppArmor
默認情況下,容器使用docker-default? AppArmor 模板。可以使用--security-opt自定義配置文件覆蓋默認設(shè)置。
為此,您必須首先將新配置文件加載到 AppArmor 中以與容器一起使用:
apparmor_parser -r -W /path/to/custom_profile
現(xiàn)在使用自定義配置文件運行容器
docker run --rm -it --security-opt apparmor=custom_profile hello-world
請參閱此 wiki 以了解如何創(chuàng)建 AppArmor 配置文件。
https://gitlab.com/apparmor/apparmor/-/wikis/QuickProfileLanguage