Dockerfile 安全最佳實踐

Xpitz發表於2020-10-26

文章首發於個人公眾號:「阿拉平平」

這篇文章 [1] 來自於 Cloudberry Engineering,作者總結了在編寫 Dockerfile 時有哪些安全的注意點,並開源了一個清單 [2] 用來檢測 Dockerfile 是否符合規則。我整理了原文,並對部分內容做了精簡。由於自己水平有限,文中難免有疏漏錯誤之處,歡迎大家在留言區指正,以下是正文。

※※※

容器安全雖然是一個很寬泛的問題,但其實有很多小技巧可以幫助我們降低使用的風險。編寫 Dockerfile 時遵循一些規則就是一個很好的出發點。

不要在環境變數中儲存保密字典

保密字典(secrets)的釋出是一個棘手的問題,很容易出錯。對於容器化的應用,可以通過掛載卷或者環境變數的方式顯示它們。

使用 ENV 儲存 secrets 則是一種糟糕的做法,因為 Dockerfile 通常會和應用一起釋出,所以這樣就和把 secrets 硬編碼到程式碼裡沒區別了。

僅使用受信任的基礎映象

容器化應用的供應鏈攻擊來自於構建容器本身的分層結構。

很明顯,罪魁禍首就是所用的基礎映象。使用不可信的基礎映象會帶來很高的風險,應儘量避免。

Docker 為大多數作業系統和應用提供了官方的基礎映象。使用它們,可以最大程度地降低被破壞的風險。

不要使用 latest 作為基礎映象的標籤

使用固定的版本作為基礎映象的標籤,可以保證正在構建的容器的預期性。

使用 latest 作為標籤會隱性地繼承升級包,這種情況輕則可能會影響應用的可靠性,重則可能引入漏洞。

避免執行 curl

從網上拉取東西再在 shell 中執行是一種很糟糕的做法。不幸的是,它是一個簡化軟體安裝的普遍解決方案。

wget https://cloudberry.engineering/absolutely-trustworthy.sh | sh

供應鏈攻擊的風險與此相同,歸根結底是信任問題。如果你真的需要在 bash 中執行 curl,請正確執行以下操作:

  • 使用受信任的源
  • 使用一個安全連結
  • 驗證下載內容的真實性和完整性

不要升級你的系統

這點可能有些誇張,但原因如下:你想固定軟體依賴包的版本,但在執行 apt-get upgrade 後,這些依賴包會升級到最新版本。

進行升級並使用 latest 作為基礎映象的標籤,會增加依賴樹的不可預測性。

你要做的就是固定基礎映象的版本,僅執行 apt/apk update

儘量不要使用 ADD 指令

ADD 指令的一個功能是構建時獲取遠端 URL 的內容。

ADD https://cloudberry.engineering/absolutely-trust-me.tar.gz

諷刺的是,官方文件建議使用 curl 作為替代方案。

從安全的角度來看,我給出同樣的建議:不要用 ADD。先獲取所需的內容,驗證好再使用 COPY 指令。如果非用不可,請使用安全連結訪問受信任的源。

不要使用 root 使用者執行

容器裡的 root 使用者與宿主機相同,但受 Docker 守護程式配置的限制。無論有什麼限制,如果使用者突破了容器, 他就有辦法獲取到對宿主機的完全控制權。

所以不要忽略以 root 使用者身份執行所帶來的風險。

因此,最好始終指定一個普通使用者:

USER hopefullynotroot

請注意,在 Dockerfile 顯示設定使用者只是一層防護,並不能解決整個執行問題。

相反,我們可以也應該採用深度防禦的方案,並在整個堆疊中進一步降低風險:嚴格配置 Docker 的守護程式或者使用無 root 使用者的容器,限制執行時的配置(可以的話,設定 --privileged 引數)等。

不要使用 sudo 命令

既然不使用 root 使用者,那麼也不應該使用 sudo 命令。

即使你使用的是普通使用者,也請檢查下 sudoers 檔案,確保該使用者沒有特權。

References

[1] 文章: https://cloudberry.engineering/article/dockerfile-security-best-practices/
[2] 清單:https://github.com/gbrindisi/dockerfile-security

相關文章