docker 根据标签删除镜像_10 个 Docker 镜像安全最佳实践
FROM ubuntu
RUN mkdir /app
RUN groupadd -r lirantal && useradd -r -s /bin/false -g lirantal lirantal
WORKDIR /app
COPY . /app
RUN chown -R lirantal:lirantal /app
USER lirantal
CMD node index.js
在上例中:創建一個系統用戶( -r 選項),沒有密碼、沒有主目錄且沒有 shell;
將該用戶添加到前面(使用?groupadd?)創建的用戶組;
最后一段參數設定了用戶名以及所屬的用戶組。
FROM node:10-alpine
RUN mkdir /app
COPY . /app
RUN chown -R node:node /app
USER node
CMD [“node”, “index.js”]
Node.js 應用開發者請參閱官方的Docker 和 Node.js 最佳實踐[5]。3. 簽名和校驗鏡像,防范中間人攻擊Docker 鏡像的認證頗具挑戰性。在生產環境使用這些鏡像運行我們的代碼,意味著我們對這些鏡像的極大信任。因此,必須保證我們拉取的容器鏡像確實是發布者發布的鏡像,沒有被任何人篡改。發生鏡像篡改,有可能是因為 Docker 客戶端和鏡像中心之間的中間人攻擊,或者是發布者的身份被人盜用并在鏡像中心發布了惡意鏡像。校驗 Docker 鏡像Docker 默認直接拉取容器鏡像,不會校驗鏡像的來源和發布者。這意味著你有可能使用來源和發布者不明的任何鏡像。無論采用何種策略,最佳實踐都是先校驗容器鏡像,通過驗證后再拉取鏡像。為了體驗鏡像校驗功能,執行下列暫時開啟 Docker Content Trust 的命令:export DOCKER_CONTENT_TRUST=1
現在,嘗試拉取一個沒有簽名的容器鏡像——請求會被拒絕,不會拉取鏡像。簽名 Docker 鏡像優先使用?Docker 認證的鏡像,即這些鏡像來自經過 Docker Hub 檢查和選擇的可信提供者。不要使用無法檢驗來源和發布者的容器鏡像。Docker 支持鏡像簽名,提供了額外一層的保護。使用?Docker Notary?簽名鏡像。Notary 會檢驗鏡像的簽名,如果簽名不合法,它會阻止運行該鏡像。如果開啟了 Docker Content Trust ,構建 Docker 鏡像的同時也會對鏡像簽名。如果是第一次簽名,Docker 會為當前用戶生成一個私鑰,保存在?~/docker/trust?。后續所有的鏡像都會使用這個私鑰簽名。請參考Docker 官方文檔[6],了解簽名鏡像的詳細指令。4. 找出、修正和監控開源漏洞指定容器的基礎鏡像,同時也引入了該鏡像包含的操作系統及系統庫有可能存在的所有安全風險。最好選用能夠正常運行應用代碼的最小化鏡像,這有助于減少攻擊面,因為限制了可能的安全漏洞數量。不過,這么做并沒有對鏡像進行安全審計,也不能防范將來發現的新漏洞。因此,防范安全軟件漏洞的一種方法是使用像?Snyk?這樣的工具,持續掃描和監控 Docker 鏡像各層可能存在的漏洞。使用下列命令掃描容器鏡像,檢查是否存在已知漏洞:# fetch the image to be tested so it exists locally
$ docker pull node:10
# scan the image with snyk
$ snyk test --docker node:10 --file=path/to/Dockerfile
Snyk 能夠監控指定的容器鏡像,一旦有新發現的安全漏洞,通知用戶并給出修補建議:$ snyk monitor --docker node:10
根據 Snyk 用戶執行的鏡像掃描,我們發現大約 40% 的 Docker 鏡像包含已知漏洞,實際上彌補這些漏洞的新版本基礎鏡像已經有了。 Synx 提供了絕無僅有的修正建議功能,用戶可以根據建議采取行動,升級 Docker 鏡像。Snyk 還發現在掃描的所有鏡像中,為了減少漏洞的數量,大約 20% 的鏡像需要重新構建。更多信息請參閱《開源安全報告-2019[3]》。5. 不要在容器鏡像中包含機密信息有時候,構建包含應用的容器鏡像時,需要用到一些機密信息,例如從私有倉庫拉取代碼所需的 SSH 私鑰,或者安全私有軟件包所需的令牌。如果?Dockerfile?中包含復制機密信息的命令,構建鏡像時,這行命令對應的中間容器會被緩存,導致機密數據也被緩存,有可能造成機密信息泄漏。因此,像令牌和密鑰這樣的機密信息必須保存在?Dockerfile?之外。使用多階段構建利用 Docker 的多階段構建功能,用一個中間鏡像層獲取和管理機密信息,然后清除中間鏡像,這樣在應用鏡像構建階段不涉及敏感數據。如下面例子所示,使用代碼將機密信息添加到中間層:FROM: ubuntu as intermediate
WORKDIR /app
COPY secret/key /tmp/
RUN scp -i /tmp/key build@acme/files .
FROM ubuntu
WORKDIR /app
COPY --from intermediate /app .
使用 Docker 的 secret 管理功能使用 Docker 的 secret 管理功能(alpha 階段),加載敏感信息文件且不會緩存這些信息:# syntax = docker/dockerfile:1.0-experimental
FROM alpine
# shows secret from default secret location
RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecre
# shows secret from custom secret location
RUN --mount=type=secret,id=mysecret,dst=/foobar cat /foobar
想了解有關 Docker secret 的更多信息,請訪問 Docker 官方站點[6]。避免無意中復制機密信息往鏡像中復制文件時,也要當心,避免無意中添加了機密信息。例如,下面的命令將整個構建上下文文件夾復制到 Docker 鏡像,有可能把敏感文件也復制進去了:COPY . .
如果文件夾中有敏感文件,要么先移除這些文件,要么將這些文件包含在 .dockerignore 中,復制時會忽略這些文件:private.key
appsettings.json
6. 設定鏡像的標簽,保證鏡像的不可更改性每個 Docker 鏡像可以有多個標簽(tag),代表該鏡像的不同變體。最常見的標簽是?latest?,表示這是該鏡像的最新版本。鏡像標簽是可更改的,也就是說鏡像的作者可以多次發布相同標簽的鏡像。因此,即使你的?Dockerfile?明確指定了使用的基礎鏡像及其標簽,這次鏡像構建和下次鏡像構建仍然可能用到了不同的基礎鏡像。解決這個問題,有多種辦法:優先選用最詳細的鏡像標簽。例如,鏡像有?:8、:8.0.1?和?:8.0.1-alpine?等標簽,選擇最后這個,因為它提供了最詳細的信息。不要使用像?latest?這樣過于泛泛的標簽。
記住,鏡像的發布者有可能刪除鏡像的某個標簽。如果設定了所用鏡像的標簽,一旦這個標簽被刪除,鏡像構建會因為找不到基礎鏡像而失敗。為了避免這個問題,可以提前把該鏡像復制到私有鏡像中心或者公有鏡像中心的私人賬戶下面。這么做,保證了鏡像的不可更改性,同時也帶來了維護私有鏡像中心的負擔。
使用比簽名更具體的 SHA256 引用指明要使用的鏡像,這能保證每次拉取都是相同內容的鏡像。這么做也有風險,如果鏡像改變了,以前的 SHA256 引用(散列值)也不存在了。
COPY - 將本地文件或者目錄(遞歸)復制到容器鏡像中的目標目錄,復制來源和目標都必須明確指定。
ADD - 與 COPY 類似的功能,有兩個不同:(1)如果復制來源是本地壓縮文件,ADD 將把該文件解壓縮到目標目錄;(2)ADD 也可以將遠程 URL 指定的文件下載到目標目錄。
使用 ADD 從遠程 URL 下載文件,存在中間人攻擊的風險,文件內容有可能因此被篡改。必須確保遠程 URL 必須是安全的 TLS 鏈接,校驗遠程 URL 的來源和身份。譯者注:實際上,官方文檔并不鼓勵使用 ADD 添加遠程文件。
如果復制的是本地壓縮文件, ADD 自動將它解壓縮到目標目錄,這有可能觸發 zip 炸彈或者?zip 任意文件覆蓋漏洞。
相比較而言,使用 COPY 復制文件或目錄,會創建一個緩存的中間鏡像層,優化鏡像構建的速度。
LABEL maintainer="me@acme.com"
除了鏡像的維護者信息,添加其他你認為重要的元數據,包括提交對象的散列值、相關構建的鏈接、質量狀態(通過所有測試了嗎?)、源代碼鏈接、SECURITY.TXT 文件的位置等。SECURITY.TXT?(RFC5785)[8] 文件說明了鏡像維護者的安全披露政策。最好在鏡像元數據中加上 SECURITY.TXT 的鏈接,例如:LABEL securitytxt="https://www.example.com/.well-known/security.txt"
想了解鏡像元數據的更多信息,請訪問?https://label-schema.org/rc1/?。譯者注:這個規范好像已經廢止了,請直接訪問?OCI 鏡像規范[9]。9. 使用多階段構建小而安全的鏡像使用?Dockerfile?構建應用容器鏡像時,會生成很多只是構建時需要的鏡像層,包括編譯時所需的開發工具和庫,運行單元測試所需的依賴、臨時文件、機密信息等等。如果保留這些鏡像層,不僅會增加鏡像的大小,影響鏡像下載速度,而且會因為安裝更多軟件包而面臨更大的攻擊危險。這對用到的鏡像也是成立的——需要使用一個專門構建應用的鏡像,但不會用它來運行應用代碼。Go 語言就是一個很好的例子。構建一個 Go 應用需要用到 Go 編譯器。編譯得到的 Go 應用能夠在任何操作系統上直接運行,沒有任何依賴,包括 scratch 鏡像。Docker 因此提供了多階段構建的功能,允許在構建過程中使用多個臨時鏡像,只保留最后一個鏡像。這樣,用戶得到兩個鏡像:第一個鏡像——非常大的鏡像,包含了構建應用和運行測試所需的所有依賴;
第二個鏡像——非常小的鏡像,只包含運行應用所需的極少數依賴。
https://res.cloudinary.com/snyk/image/upload/v1551798390/Docker_Image_Security_Best_Practices_.pdf
https://snyk.io/blog/shifting-docker-security-left/
https://snyk.io/blog/top-ten-most-popular-docker-images-each-contain-at-least-30-vulnerabilities/
https://snyk.io/container-vulnerability-management/
https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md
https://docs.docker.com/engine/security/trust/content_trust/
https://snyk.io/blog/10-docker-image-security-best-practices/
https://securitytxt.org/
https://github.com/opencontainers/image-spec
https://snyk.io/container-vulnerability-management/
總結
以上是生活随笔為你收集整理的docker 根据标签删除镜像_10 个 Docker 镜像安全最佳实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 760k能吃鸡吗
- 下一篇: fps测试网页_对话斗鱼云游戏负责人:做