容器安全之 Dockerfile 安全掃描

一、Dockerfile 掃描工具

  • checkov
  • hadolint(構建最佳實踐Docker 鏡像。)
  • 也可以考慮 docker scan

二、checkov

Dockerfile Configuration Scaning-checkov

checkov 不僅可以掃描dockfile, 也可以掃描 CloudformationAWS SAMKubernetesHelm chartsKustomize 、鏡像等。

Checkov 支持對 Dockerfile 文件的策略進行評估。 使用 checkov 掃描包含 Dockerfile 的目錄時,它將驗證該文件是否符合 Docker 最佳實踐,例如不使用 root 用戶、確保運行狀況檢查存在以及不公開 SSH 端口。

可以在此處找到 Dockerfile 策略檢查的完整列表。

2.1、示例配置錯誤的 Dockerfile

FROM node:alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000 22
HEALTHCHECK CMD curl --fail http://localhost:3000 || exit 1
USER root
CMD ["node","app.js"]

2.2、安裝

Requirements

  • Python >= 3.7 (Data classes are available for Python 3.7+)
  • Terraform >= 0.12
pip3 install checkov   -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

2.3、在 CLI 中運行

checkov -d . --framework dockerfile

2.4、示例輸出

# checkov -d . --framework dockerfile
[ dockerfile framework ]: 100%|████████████████████|[1/1], Current File Scanned=..\..\..\..\Dockerfile


       _               _
   ___| |__   ___  ___| | _______   __
  / __| '_ \ / _ \/ __| |/ / _ \ \ / /
 | (__| | | |  __/ (__|   < (_) \ V /
  \___|_| |_|\___|\___|_|\_\___/ \_/

By bridgecrew.io | version: 2.3.102
Update available 2.3.102 -> 2.3.121
Run pip3 install -U checkov to update


dockerfile scan results:

Passed checks: 21, Failed checks: 2, Skipped checks: 0

Check: CKV_DOCKER_11: "Ensure From Alias are unique for multistage builds."
        PASSED for resource: /Dockerfile.
        File: /Dockerfile:1-9
        Guide: https://docs.bridgecrew.io/docs/ensure-docker-from-alias-is-unique-for-multistage-builds
Check: CKV_DOCKER_7: "Ensure the base image uses a non latest version tag"
        PASSED for resource: /Dockerfile.
        File: /Dockerfile:1-9
        Guide: https://docs.bridgecrew.io/docs/ensure-the-base-image-uses-a-non-latest-version-tag
Check: CKV_DOCKER_9: "Ensure that APT isn't used"
        PASSED for resource: /Dockerfile.
        File: /Dockerfile:1-9
        Guide: https://docs.bridgecrew.io/docs/ensure-docker-apt-is-not-used
Check: CKV_DOCKER_5: "Ensure update instructions are not use alone in the Dockerfile"
        PASSED for resource: /Dockerfile.
        File: /Dockerfile:1-9
        Guide: https://docs.bridgecrew.io/docs/ensure-update-instructions-are-not-used-alone-in-the-dockerfile
Check: CKV_DOCKER_10: "Ensure that WORKDIR values are absolute paths"
        PASSED for resource: /Dockerfile.
        File: /Dockerfile:1-9
        Guide: https://docs.bridgecrew.io/docs/ensure-docker-workdir-values-are-absolute-paths
Check: CKV_DOCKER_2: "Ensure that HEALTHCHECK instructions have been added to container images"
        PASSED for resource: /Dockerfile.HEALTHCHECK
        File: /Dockerfile:7-7
        Guide: https://docs.bridgecrew.io/docs/ensure-that-healthcheck-instructions-have-been-added-to-container-images
Check: CKV_DOCKER_3: "Ensure that a user for the container has been created"
        PASSED for resource: /Dockerfile.USER
        File: /Dockerfile:8-8
        Guide: https://docs.bridgecrew.io/docs/ensure-that-a-user-for-the-container-has-been-created
Check: CKV2_DOCKER_14: "Ensure that certificate validation isn't disabled for git by setting the environment variable 'GIT_SSL_NO_VERIFY' to any value"
        PASSED for resource: /Dockerfile.RUN
        File: /Dockerfile:4-4
Check: CKV2_DOCKER_6: "Ensure that certificate validation isn't disabled with the NODE_TLS_REJECT_UNAUTHORIZED environmnet variable"
        PASSED for resource: /Dockerfile.RUN
        File: /Dockerfile:4-4
Check: CKV2_DOCKER_12: "Ensure that certificate validation isn't disabled for npm via the 'NPM_CONFIG_STRICT_SSL' environmnet variable"
        PASSED for resource: /Dockerfile.RUN
        File: /Dockerfile:4-4
Check: CKV2_DOCKER_5: "Ensure that certificate validation isn't disabled with the PYTHONHTTPSVERIFY environmnet variable"
        PASSED for resource: /Dockerfile.RUN
        File: /Dockerfile:4-4
Check: CKV2_DOCKER_7: "Ensure that packages with untrusted or missing signatures are not used by apk via the '--allow-untrusted' option"
        PASSED for resource: /Dockerfile.RUN
        File: /Dockerfile:4-4
Check: CKV2_DOCKER_11: "Ensure that the '--force-yes' option is not used, as it disables signature validation and allows packages to be downgraded which can leave the system in a broken or inconsistent state"
        PASSED for resource: /Dockerfile.RUN
        File: /Dockerfile:4-4
Check: CKV2_DOCKER_8: "Ensure that packages with untrusted or missing signatures are not used by apt-get via the '--allow-unauthenticated' option"
        PASSED for resource: /Dockerfile.RUN
        File: /Dockerfile:4-4
Check: CKV2_DOCKER_13: "Ensure that certificate validation isn't disabled for npm or yarn by setting the option strict-ssl to false"
        PASSED for resource: /Dockerfile.RUN
        File: /Dockerfile:4-4
Check: CKV2_DOCKER_4: "Ensure that certificate validation isn't disabled with the pip '--trusted-host' option"
        PASSED for resource: /Dockerfile.RUN
        File: /Dockerfile:4-4
Check: CKV2_DOCKER_10: "Ensure that packages with untrusted or missing signatures are not used by rpm via the '--nodigest', '--nosignature', '--noverify', or '--nofiledigest' options"
        PASSED for resource: /Dockerfile.RUN
        File: /Dockerfile:4-4
Check: CKV2_DOCKER_2: "Ensure that certificate validation isn't disabled with curl"
        PASSED for resource: /Dockerfile.RUN
        File: /Dockerfile:4-4
Check: CKV2_DOCKER_3: "Ensure that certificate validation isn't disabled with wget"
        PASSED for resource: /Dockerfile.RUN
        File: /Dockerfile:4-4
Check: CKV2_DOCKER_1: "Ensure that sudo isn't used"
        PASSED for resource: /Dockerfile.RUN
        File: /Dockerfile:4-4
Check: CKV2_DOCKER_9: "Ensure that packages with untrusted or missing GPG signatures are not used by dnf, tdnf, or yum via the '--nogpgcheck' option"
        PASSED for resource: /Dockerfile.RUN
        File: /Dockerfile:4-4
Check: CKV_DOCKER_1: "Ensure port 22 is not exposed"
        FAILED for resource: /Dockerfile.EXPOSE
        File: /Dockerfile:6-6
        Guide: https://docs.bridgecrew.io/docs/ensure-port-22-is-not-exposed

                6 | EXPOSE 3000 22

Check: CKV_DOCKER_8: "Ensure the last USER is not root"
        FAILED for resource: /Dockerfile.USER
        File: /Dockerfile:8-8
        Guide: https://docs.bridgecrew.io/docs/ensure-the-last-user-is-not-root

                8 | USER root

三、hadolint

GitHub - hadolint/hadolint: Dockerfile linter, validate inline bash, 用 Haskell 編寫

3.1、在線網站

Dockerfile Linter (hadolint.github.io)

3.2、DockerFile

FROM node:alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000 22
HEALTHCHECK CMD curl --fail http://localhost:3000 || exit 1
USER root
CMD ["node","app.js"]

3.3、基於容器運行

docker run --rm -i hadolint/hadolint < Dockerfile
# OR
docker run --rm -i ghcr.io/hadolint/hadolint < Dockerfile

3.4、Centos 安裝運行

[root@ops-pinpoint-123 tmp]# wget https://github.com/hadolint/hadolint/releases/download/v2.12.0/hadolint-Linux-x86_64
[root@ops-pinpoint-123 tmp]# chmod +x hadolint-Linux-x86_64
[root@ops-pinpoint-123 tmp]# hadolint-Linux-x86_64 ./Dockerfile
[root@ops-pinpoint-123 tmp]# ./hadolint-Linux-x86_64  /root/Dockerfile  
/root/Dockerfile:8 DL3002 warning: Last USER should not be root

我們可以發現 hadolint 掃描出來的是基於他特定的規則和最佳實踐。

四、兩者對比

我們前面進行檢查的 Dockerfile 是一樣的,我們發現兩者給出來的信息還是有些差異的。

hadolint 檢測出來的 USERROOT 的問題。 checkov 不僅檢測出了 USERROOT 的問題, 還有一個 22 端口的問題。因爲 22 端口一般都是我們 ssh 使用的端口,我們也不應該暴露出來。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章