goodwithtech/dockle

GitHub: goodwithtech/dockle

Dockle 是一款容器镜像安全审计与最佳实践检查工具,帮助用户在 CI/CD 流程中自动检测 Docker 镜像的安全合规问题。

Stars: 3273 | Forks: 163

`Dockle` 可以帮助你: 1. 构建 [最佳实践](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) 的 Docker 镜像 2. 构建安全的 Docker 镜像 - 检查项包含 [CIS Benchmarks](https://www.cisecurity.org/cis-benchmarks/) ``` $ brew untap goodwithtech/dockle # who use 0.1.16 or older version $ brew install goodwithtech/r/dockle $ dockle [YOUR_IMAGE_NAME] ``` 请参阅 [安装](#installation) 和 [常见示例](#common-examples) # 检查项对比 # 目录 - [功能特性](#features) - [对比](#comparison) - [安装](#installation) - [Homebrew (Mac OS X / Linux 和 WSL)](#homebrew-mac-os-x--linux-and-wsl) - [RHEL/CentOS](#rhelcentos) - [Debian/Ubuntu](#debianubuntu) - [Arch Linux](#arch-linux) - [Windows](#windows) - [Microsoft PowerShell 7](#microsoft-powershell-7) - [二进制文件](#binary) - [asdf](#asdf) - [mise](#mise) - [从源码安装](#from-source) - [使用 Docker](#use-docker) - [快速开始](#quick-start) - [基础用法](#basic) - [Docker](#docker) - [检查项汇总](#checkpoint-summary) - [常见示例](#common-examples) - [扫描镜像](#scan-an-image) - [扫描镜像文件](#scan-an-image-file) - [以 JSON 格式获取或保存结果](#get-or-save-the-results-as-json) - [以 SARIF 格式获取或保存结果](#get-or-save-the-results-as-sarif) - [指定退出代码](#specify-exit-code) - [指定退出级别](#specify-exit-level) - [忽略指定的检查项](#ignore-the-specified-checkpoints) - [接受可疑的 `environment variables` / `files` / `file extensions`](#accept-suspicious-environment-variables--files--file-extensions) - [拒绝可疑的 `environment variables` / `files` / `file extensions`](#reject-suspicious-environment-variables--files--file-extensions) - [持续集成](#continuous-integration-ci) - [GitHub Action](#github-action) - [Travis CI](#travis-ci) - [CircleCI](#circleci) - [GitLab CI](#gitlab-ci) - [私有 Docker Registry 授权](#authorization-for-private-docker-registry) - [Docker Hub](#docker-hub) - [Amazon ECR (Elastic Container Registry)](#amazon-ecr-elastic-container-registry) - [GCR (Google Container Registry)](#gcr-google-container-registry) - [自托管 Registry (BasicAuth)](#self-hosted-registry-basicauth) - [贡献者](#contributors) - [代码贡献者](#code-contributors) - [资金贡献者](#financial-contributors) - [个人](#individuals) - [组织](#organizations) - [许可证](#license) - [作者](#author) # 功能特性 - 检测容器漏洞 - 帮助构建最佳实践的 Dockerfile - 简单易用 - 仅需指定镜像名称 - 请参阅 [快速开始](#quick-start) 和 [常见示例](#common-examples) - 支持 CIS Benchmarks - 高准确度 - DevSecOps - 适用于 Travis CI、CircleCI、Jenkins 等 CI 流程 - 请参阅 [CI 示例](#continuous-integration-ci) # 对比 |  | [Dockle](https://github.com/goodwithtech/dockle) | [Hadolint](https://github.com/hadolint/hadolint) | [Docker Bench for Security](https://github.com/docker/docker-bench-security) | [Clair](https://github.com/coreos/clair) | |--- |---:|---:|---:|---:| | 目标 | 镜像 | Dockerfile | 主机
Docker Daemon
镜像
容器运行时 | 镜像 | | 运行方式 | 二进制文件 | 二进制文件 | Shell 脚本 | 二进制文件 | | 依赖 | 无 | 无 | 部分依赖 | 无 | | 适用 CI | ✓ | ✓ | x | x | | 目的 |安全审计
Dockerfile Lint| Dockerfile Lint | 安全审计
Dockerfile Lint | 漏洞扫描 | # 安装 ## Homebrew (Mac OS X / Linux 和 WSL) 你可以在 [Mac OS X](https://brew.sh/) 或 [Linux 和 WSL (Windows Subsystem for Linux)](https://docs.brew.sh/Homebrew-on-Linux) 上使用 Homebrew。 ``` $ brew install goodwithtech/r/dockle ``` ## RHEL/CentOS ``` VERSION=$( curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \ grep '"tag_name":' | \ sed -E 's/.*"v([^"]+)".*/\1/' \ ) && rpm -ivh https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Linux-64bit.rpm ``` ## Debian/Ubuntu ``` VERSION=$( curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \ grep '"tag_name":' | \ sed -E 's/.*"v([^"]+)".*/\1/' \ ) && curl -L -o dockle.deb https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Linux-64bit.deb $ sudo dpkg -i dockle.deb && rm dockle.deb ``` ## Arch Linux 可以使用 `dockle` 或 `dockle-bin` 包从 Arch User Repository 安装 dockle。 ``` git clone https://aur.archlinux.org/dockle-bin.git cd dockle-bin makepkg -sri ``` ## Windows ``` VERSION=$( curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \ grep '"tag_name":' | \ sed -E 's/.*"v([^"]+)".*/\1/' \ ) && curl -L -o dockle.zip https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Windows-64bit.zip $ unzip dockle.zip && rm dockle.zip $ ./dockle.exe [IMAGE_NAME] ``` ## Microsoft PowerShell 7 ``` if (((Invoke-WebRequest "https://api.github.com/repos/goodwithtech/dockle/releases/latest").Content) -match '"tag_name":"v(?[^"]+)"') { $VERSION=$Matches.ver && Invoke-WebRequest "https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Windows-64bit.zip" -OutFile dockle.zip && Expand-Archive dockle.zip && Remove-Item dockle.zip } ``` ## 二进制文件 你可以从 [发布页面](https://github.com/goodwithtech/dockle/releases/latest) 获取最新版本的二进制文件。 下载适用于你的操作系统/架构的压缩文件。解压该压缩文件,并将二进制文件放在你的 `$PATH` 中的某个位置(在 UNIX 系统上,通常是 `/usr/local/bin` 或类似目录)。 - 注意:确保已开启其执行权限位。(`chmod +x dockle`) ## asdf 你可以使用 [asdf 版本管理器](https://asdf-vm.com/) 和这个[插件](https://github.com/mathew-fleisch/asdf-dockle)来安装 dockle,该插件可以自动化安装(并在不同版本间切换)各种 github 发布的二进制文件的过程。在已安装 asdf 的情况下,运行以下命令来安装 dockle: ``` # 添加 dockle plugin asdf plugin add dockle # 显示所有可安装的版本 asdf list-all dockle # 安装特定版本 asdf install dockle latest # 全局设置版本(在你的 ~/.tool-versions 文件中) asdf global dockle latest # 现在 dockle 命令已可用 dockle --version ``` ## mise 你可以使用多语言工具版本管理器 [mise](https://github.com/jdx/mise) 来安装 dockle。在已安装 mise 的情况下,运行以下命令来安装 dockle: ``` # 显示所有可安装的版本 mise ls-remote dockle # 安装特定版本 mise install dockle@latest # 全局设置版本 mise use -g dockle@latest # 现在 dockle 命令已可用 dockle --version ``` ## 从源码安装 ``` $ GO111MODULE=off go get github.com/goodwithtech/dockle/cmd/dockle $ cd $GOPATH/src/github.com/goodwithtech/dockle && GO111MODULE=on go build -o $GOPATH/bin/dockle cmd/dockle/main.go ``` ## 使用 Docker [Docker Hub](https://hub.docker.com/r/goodwithtech/dockle) 上也有 [`Dockle` 镜像](https://hub.docker.com/r/goodwithtech/dockle)。你可以在安装命令行工具之前先试用 `dockle`。 ``` $ VERSION=$( curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \ grep '"tag_name":' | \ sed -E 's/.*"v([^"]+)".*/\1/' \ ) && docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ goodwithtech/dockle:v${VERSION} [YOUR_IMAGE_NAME] ``` 当你想扫描主机上的镜像时,你只需要挂载 `-v /var/run/docker.sock:/var/run/docker.sock`。 # 快速开始 ## 基础用法 只需指定镜像名称(和标签)即可。 ``` $ dockle [YOUR_IMAGE_NAME] ```
结果 ``` FATAL - CIS-DI-0009: Use COPY instead of ADD in Dockerfile * Use COPY : /bin/sh -c #(nop) ADD file:81c0a803075715d1a6b4f75a29f8a01b21cc170cfc1bff6702317d1be2fe71a3 in /app/credentials.json FATAL - CIS-DI-0010: Do not store credential in ENVIRONMENT vars/files * Suspicious filename found : app/credentials.json FATAL - DKL-DI-0005: Clear apt-get caches * Use 'rm -rf /var/lib/apt/lists' after 'apt-get install' : /bin/sh -c apt-get update && apt-get install -y git FATAL - DKL-LI-0001: Avoid empty password * No password user found! username : nopasswd WARN - CIS-DI-0001: Create a user for the container * Last user should not be root INFO - CIS-DI-0005: Enable Content trust for Docker * export DOCKER_CONTENT_TRUST=1 before docker pull/build INFO - CIS-DI-0008: Confirm safety of setuid/setgid files * setuid file: app/suid.txt urw-r--r-- * setgid file: app/gid.txt grw-r--r-- * setuid file: usr/bin/gpasswd urwxr-xr-x * setgid file: usr/bin/wall grwxr-xr-x * setuid file: bin/su urwxr-xr-x * setuid file: bin/umount urwxr-xr-x * setuid file: bin/mount urwxr-xr-x * setgid file: usr/bin/ssh-agent grwxr-xr-x * setuid file: etc/shadow urw-r----- * setuid file: usr/bin/chsh urwxr-xr-x * setuid file: usr/bin/chfn urwxr-xr-x * setuid file: usr/lib/openssh/ssh-keysign urwxr-xr-x * setgid file: etc/passwd grw-r--r-- * setgid file: sbin/unix_chkpwd grwxr-xr-x * setgid file: usr/bin/chage grwxr-xr-x * setuid file: usr/bin/passwd urwxr-xr-x * setgid file: usr/bin/expiry grwxr-xr-x * setuid file: usr/bin/newgrp urwxr-xr-x IGNORE - CIS-DI-0006: Add HEALTHCHECK instruction to the container image ```
## Docker 此外,你也可以按如下方式使用 Docker 来运行 `dockle` 命令。 ``` $ export DOCKLE_LATEST=$( curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \ grep '"tag_name":' | \ sed -E 's/.*"v([^"]+)".*/\1/' \ ) $ docker run --rm goodwithtech/dockle:v${DOCKLE_LATEST} [YOUR_IMAGE_NAME] ``` - 如果你想扫描主机上的镜像,你需要挂载 `docker.sock`。 $ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock ... # 检查项汇总 - 各检查项的详细信息请参阅 [CHECKPOINT.md](CHECKPOINT.md) | 代码 | 描述 | 级别[※](#level) | |---|---|:---:| | | [CIS 的 Docker 镜像检查项](CHECKPOINT.md#docker-image-checkpoints) | | | [CIS-DI-0001](CHECKPOINT.md#cis-di-0001) | 为容器创建一个用户 | WARN | | [CIS-DI-0002](CHECKPOINT.md#cis-di-0002) | 为容器使用受信任的基础镜像 | FATAL | [CIS-DI-0003](CHECKPOINT.md#cis-di-0003) | 不要在容器中安装不必要的包 | FATAL | [CIS-DI-0004](CHECKPOINT.md#cis-di-0004) | 扫描并重建镜像以包含安全补丁 | FATAL | [CIS-DI-0005](CHECKPOINT.md#cis-di-0005) | 为 Docker 启用 Content trust | INFO | [CIS-DI-0006](CHECKPOINT.md#cis-di-0006) | 在容器镜像中添加 `HEALTHCHECK` 指令 | INFO | [CIS-DI-0007](CHECKPOINT.md#cis-di-0007) | 不要在 Dockerfile 中单独使用 `update` 指令 | FATAL | [CIS-DI-0008](CHECKPOINT.md#cis-di-0008) | 确认 `setuid` 和 `setgid` 文件的安全性 | INFO | [CIS-DI-0009](CHECKPOINT.md#cis-di-0009) | 在 Dockerfile 中使用 `COPY` 而不是 `ADD` | FATAL | [CIS-DI-0010](CHECKPOINT.md#cis-di-0010) | 不要在 Dockerfiles 中存储机密信息 | FATAL | [CIS-DI-0011](CHECKPOINT.md#cis-di-0011) | 仅安装已验证的包 | INFO || [Dockle 针对 Docker 的检查项](CHECKPOINT.md#dockle-checkpoints-for-docker) | | [DKL-DI-0001](CHECKPOINT.md#dkl-di-0001) | 避免使用 `sudo` 命令 | FATAL | [DKL-DI-0002](CHECKPOINT.md#dkl-di-0002) | 避免挂载敏感目录 | FATAL | [DKL-DI-0003](CHECKPOINT.md#dkl-di-0003) | 避免 `apt-get dist-upgrade` | WARN | [DKL-DI-0004](CHECKPOINT.md#dkl-di-0004) | 使用带有 `--no-cache` 的 `apk add` | FATAL | [DKL-DI-0005](CHECKPOINT.md#dkl-di-0005) | 清除 `apt-get` 缓存 | FATAL | [DKL-DI-0006](CHECKPOINT.md#dkl-di-0006) | 避免 `latest` 标签 | WARN || [Dockle 针对 Linux 的检查项](CHECKPOINT.md#dockerdockle-checkpoints-for-linux) | | [DKL-LI-0001](CHECKPOINT.md#dkl-li-0001) | 避免空密码 | FATAL | [DKL-LI-0002](CHECKPOINT.md#dkl-li-0002) | 保持 UID/GROUPs 唯一 | FATAL | [DKL-LI-0003](CHECKPOINT.md#dkl-li-0003) | 仅放置必要的文件 | INFO ## 级别 `Dockle` 有 5 个检查级别。 | 级别 | 描述 | |:---:|---| | FATAL | 实用且谨慎 | | WARN | 实用且谨慎,但限制使用(即使是官方镜像) | | INFO | 可能会对实用性或性能产生负面影响 | | SKIP | 未找到目标文件 | | PASS | 未发现任何问题 | ## 常见示例 ### 扫描镜像 只需指定镜像名称(和标签)即可。 ``` $ dockle goodwithtech/test-image:v1 ```
结果 ``` FATAL - CIS-DI-0001: Create a user for the container * Last user should not be root WARN - CIS-DI-0005: Enable Content trust for Docker * export DOCKER_CONTENT_TRUST=1 before docker pull/build FATAL - CIS-DI-0006: Add HEALTHCHECK instruction to the container image * not found HEALTHCHECK statement FATAL - CIS-DI-0007: Do not use update instructions alone in the Dockerfile * Use 'Always combine RUN 'apt-get update' with 'apt-get install' : /bin/sh -c apt-get update && apt-get install -y git FATAL - CIS-DI-0008: Remove setuid and setgid permissions in the images * Found setuid file: etc/passwd grw-r--r-- * Found setuid file: usr/lib/openssh/ssh-keysign urwxr-xr-x * Found setuid file: app/hoge.txt ugrw-r--r-- * Found setuid file: app/hoge.txt ugrw-r--r-- * Found setuid file: etc/shadow urw-r----- FATAL - CIS-DI-0009: Use COPY instead of ADD in Dockerfile * Use COPY : /bin/sh -c #(nop) ADD file:81c0a803075715d1a6b4f75a29f8a01b21cc170cfc1bff6702317d1be2fe71a3 in /app/credentials.json FATAL - CIS-DI-0010: Do not store secrets in ENVIRONMENT variables * Suspicious ENV key found : MYSQL_PASSWD FATAL - CIS-DI-0010: Do not store secret files * Suspicious filename found : app/credentials.json PASS - DKL-DI-0001: Avoid sudo command FATAL - DKL-DI-0002: Avoid sensitive directory mounting * Avoid mounting sensitive dirs : /usr PASS - DKL-DI-0003: Avoid apt-get/apk/dist-upgrade PASS - DKL-DI-0004: Use apk add with --no-cache FATAL - DKL-DI-0005: Clear apt-get caches * Use 'apt-get clean && rm -rf /var/lib/apt/lists/*' : /bin/sh -c apt-get update && apt-get install -y git PASS - DKL-DI-0006: Avoid latest tag FATAL - DKL-LI-0001: Avoid empty password * No password user found! username : nopasswd PASS - DKL-LI-0002: Be unique UID PASS - DKL-LI-0002: Be unique GROUP ```
### 扫描镜像文件 ``` $ docker save alpine:latest -o alpine.tar $ dockle --input alpine.tar ``` ### 以 JSON 格式获取或保存结果 ``` $ dockle -f json goodwithtech/test-image:v1 $ dockle -f json -o results.json goodwithtech/test-image:v1 ```
结果 ``` { "summary": { "fatal": 6, "warn": 2, "info": 2, "pass": 7 }, "details": [ { "code": "CIS-DI-0001", "title": "Create a user for the container", "level": "WARN", "alerts": [ "Last user should not be root" ] }, { "code": "CIS-DI-0005", "title": "Enable Content trust for Docker", "level": "INFO", "alerts": [ "export DOCKER_CONTENT_TRUST=1 before docker pull/build" ] }, { "code": "CIS-DI-0006", "title": "Add HEALTHCHECK instruction to the container image", "level": "WARN", "alerts": [ "not found HEALTHCHECK statement" ] }, { "code": "CIS-DI-0008", "title": "Remove setuid and setgid permissions in the images", "level": "INFO", "alerts": [ "Found setuid file: usr/lib/openssh/ssh-keysign urwxr-xr-x" ] }, { "code": "CIS-DI-0009", "title": "Use COPY instead of ADD in Dockerfile", "level": "FATAL", "alerts": [ "Use COPY : /bin/sh -c #(nop) ADD file:81c0a803075715d1a6b4f75a29f8a01b21cc170cfc1bff6702317d1be2fe71a3 in /app/credentials.json " ] }, { "code": "CIS-DI-0010", "title": "Do not store secrets in ENVIRONMENT variables", "level": "FATAL", "alerts": [ "Suspicious ENV key found : MYSQL_PASSWD" ] }, { "code": "CIS-DI-0010", "title": "Do not store secret files", "level": "FATAL", "alerts": [ "Suspicious filename found : app/credentials.json " ] }, { "code": "DKL-DI-0002", "title": "Avoid sensitive directory mounting", "level": "FATAL", "alerts": [ "Avoid mounting sensitive dirs : /usr" ] }, { "code": "DKL-DI-0005", "title": "Clear apt-get caches", "level": "FATAL", "alerts": [ "Use 'rm -rf /var/lib/apt/lists' after 'apt-get install' : /bin/sh -c apt-get update \u0026\u0026 apt-get install -y git" ] }, { "code": "DKL-LI-0001", "title": "Avoid empty password", "level": "FATAL", "alerts": [ "No password user found! username : nopasswd" ] } ] } ```
### 以 SARIF 格式获取或保存结果 ``` $ dockle -f sarif goodwithtech/test-image:v1 $ dockle -f sarif -o results.json goodwithtech/test-image:v1 ```
结果 ``` { "version": "2.1.0", "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json", "runs": [ { "tool": { "driver": { "name": "Dockle", "informationUri": "https://github.com/goodwithtech/dockle", "rules": [ { "id": "CIS-DI-0009", "shortDescription": { "text": "Use COPY instead of ADD in Dockerfile" }, "help": { "text": "https://github.com/goodwithtech/dockle/blob/master/CHECKPOINT.md#CIS-DI-0009" } }, { "id": "CIS-DI-0010", "shortDescription": { "text": "Do not store credential in ENVIRONMENT vars/files" }, "help": { "text": "https://github.com/goodwithtech/dockle/blob/master/CHECKPOINT.md#CIS-DI-0010" } }, { "id": "DKL-DI-0005", "shortDescription": { "text": "Clear apt-get caches" }, "help": { "text": "https://github.com/goodwithtech/dockle/blob/master/CHECKPOINT.md#DKL-DI-0005" } }, { "id": "DKL-LI-0001", "shortDescription": { "text": "Avoid empty password" }, "help": { "text": "https://github.com/goodwithtech/dockle/blob/master/CHECKPOINT.md#DKL-LI-0001" } }, { "id": "CIS-DI-0005", "shortDescription": { "text": "Enable Content trust for Docker" }, "help": { "text": "https://github.com/goodwithtech/dockle/blob/master/CHECKPOINT.md#CIS-DI-0005" } }, { "id": "CIS-DI-0008", "shortDescription": { "text": "Confirm safety of setuid/setgid files" }, "help": { "text": "https://github.com/goodwithtech/dockle/blob/master/CHECKPOINT.md#CIS-DI-0008" } }, { "id": "CIS-DI-0001", "shortDescription": { "text": "Create a user for the container" }, "help": { "text": "https://github.com/goodwithtech/dockle/blob/master/CHECKPOINT.md#CIS-DI-0001" } }, { "id": "CIS-DI-0006", "shortDescription": { "text": "Add HEALTHCHECK instruction to the container image" }, "help": { "text": "https://github.com/goodwithtech/dockle/blob/master/CHECKPOINT.md#CIS-DI-0006" } } ] } }, "results": [ { "ruleId": "CIS-DI-0009", "level": "error", "message": { "text": "Use COPY : /bin/sh -c #(nop) ADD file:81c0a803075715d1a6b4f75a29f8a01b21cc170cfc1bff6702317d1be2fe71a3 in /app/credentials.json " } }, { "ruleId": "CIS-DI-0010", "level": "error", "message": { "text": "Suspicious filename found : app/credentials.json , Suspicious ENV key found : MYSQL_PASSWD" } }, { "ruleId": "DKL-DI-0005", "level": "error", "message": { "text": "Use 'rm -rf /var/lib/apt/lists' after 'apt-get install' : /bin/sh -c apt-get update \u0026\u0026 apt-get install -y git" } }, { "ruleId": "DKL-LI-0001", "level": "error", "message": { "text": "No password user found! username : nopasswd" } }, { "ruleId": "CIS-DI-0005", "level": "note", "message": { "text": "export DOCKER_CONTENT_TRUST=1 before docker pull/build" } }, { "ruleId": "CIS-DI-0008", "level": "note", "message": { "text": "setuid file: urwxr-xr-x usr/bin/newgrp, setgid file: grwxr-xr-x usr/bin/ssh-agent, setgid file: grwxr-xr-x usr/bin/expiry, setuid file: urwxr-xr-x usr/lib/openssh/ssh-keysign, setuid file: urwxr-xr-x bin/umount, setgid file: grwxr-xr-x usr/bin/chage, setuid file: urwxr-xr-x usr/bin/passwd, setgid file: grwxr-xr-x sbin/unix_chkpwd, setuid file: urwxr-xr-x usr/bin/chsh, setgid file: grwxr-xr-x usr/bin/wall, setuid file: urwxr-xr-x bin/ping, setuid file: urwxr-xr-x bin/su, setuid file: urwxr-xr-x usr/bin/chfn, setuid file: urwxr-xr-x usr/bin/gpasswd, setuid file: urwxr-xr-x bin/mount" } }, { "ruleId": "CIS-DI-0001", "level": "none", "message": { "text": "Last user should not be root" } }, { "ruleId": "CIS-DI-0006", "level": "none", "message": { "text": "not found HEALTHCHECK statement" } } ] } ] } ```
### 指定退出代码 默认情况下,即使存在一些问题,`Dockle` 也会以代码 `0` 退出。 如果发现 `WARN` 或 `FATAL` 警报,请使用 `--exit-code, -c` 选项以非零退出代码退出。 ``` $ dockle --exit-code 1 [IMAGE_NAME] ``` ### 指定退出级别 默认情况下,当存在 `WARN` 或 `FATAL` 级别的警报时,会触发 `--exit-code`。 使用 `--exit-level, -l` 选项可以更改警报级别。你可以设置为 `info`、`warn` 或 `fatal`。 ``` $ dockle --exit-code 1 --exit-level info [IMAGE_NAME] $ dockle --exit-code 1 --exit-level fatal [IMAGE_NAME] ``` ### 忽略指定的检查项 `--ignore, -i` 选项可以忽略指定的检查项。 ``` $ dockle -i CIS-DI-0001 -i DKL-DI-0006 [IMAGE_NAME] ``` 或者,使用 `DOCKLE_IGNORES`: ``` export DOCKLE_IGNORES=CIS-DI-0001,DKL-DI-0006 dockle [IMAGE_NAME] ``` 或者,使用 `.dockleignore` 文件: ``` $ cat .dockleignore # 将 root 设置为默认用户,因为我们想要运行 nginx CIS-DI-0001 # 使用 latest tag,因为仅用于检查内部镜像 DKL-DI-0006 ``` ### 接受可疑的 `environment variables` / `files` / `file extensions` ``` # --accept-key value, --ak value 你可以添加可接受的关键词。 dockle -ak GPG_KEY -ak KEYCLOAK_VERSION [IMAGE_NAME] or DOCKLE_ACCEPT_KEYS=GPG_KEY,KEYCLOAK_VERSION dockle [IMAGE_NAME] # --accept-file value, --af value 你可以添加可接受的文件名。 dockle -af id_rsa -af id_dsa [IMAGE_NAME] or DOCKLE_ACCEPT_FILES=id_rsa,id_dsa dockle [IMAGE_NAME] # --accept-file-extension value, --ae value 你可以添加可接受的文件扩展名。 dockle -ae pem -ae log [IMAGE_NAME] or DOCKLE_ACCEPT_FILE_EXTENSIONS=pem,log dockle [IMAGE_NAME] ``` ### 拒绝可疑的 `environment variables` / `files` / `file extensions` ``` # --sensitive-word value, --sw value 你可以添加可接受的关键词。 dockle -sw PRIVATE [IMAGE_NAME] or DOCKLE_ACCEPT_KEYS=GPG_KEY,KEYCLOAK_VERSION dockle [IMAGE_NAME] # --sensitive-file value, --sf value 你可以添加可接受的文件名。 dockle -sf .env [IMAGE_NAME] or DOCKLE_REJECT_FILES=.env dockle [IMAGE_NAME] # --sensitive-file-extension value, --se value 你可以添加可接受的文件扩展名。 dockle -se pfx [IMAGE_NAME] or DOCKLE_REJECT_FILE_EXTENSIONS=pfx dockle [IMAGE_NAME] ``` ## 持续集成 (CI) 你可以在 Travis CI/CircleCI 中使用 `Dockle` 扫描构建好的镜像。 在这些示例中,如果发现任何警告,测试将会失败。 不过,你可以通过使用 `.dockleignore` 文件来忽略指定的目标检查项。 或者,如果你只想显示结果而不想让测试因此失败,请在 `dockle` 命令中将 `--exit-code` 指定为 `0`。 ### GitHub Action 我们提供了 [goodwithtech/dockle-action](https://github.com/goodwithtech/dockle-action)。 ``` - uses: goodwithtech/dockle-action@main with: image: 'target' format: 'list' exit-code: '1' exit-level: 'warn' ignore: 'CIS-DI-0001,DKL-DI-0006' ``` ### Travis CI
.travis.yml ``` services: - docker env: global: - COMMIT=${TRAVIS_COMMIT::8} before_install: - docker build -t dockle-ci-test:${COMMIT} . - export VERSION=$(curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/') - wget https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Linux-64bit.tar.gz - tar zxvf dockle_${VERSION}_Linux-64bit.tar.gz script: - ./dockle dockle-ci-test:${COMMIT} - ./dockle --exit-code 1 dockle-ci-test:${COMMIT} ```
- 示例: https://travis-ci.org/goodwithtech/dockle-ci-test - 仓库: https://github.com/goodwithtech/dockle-ci-test ### CircleCI
.circleci/config.yml ``` jobs: build: docker: - image: docker:18.09-git steps: - checkout - setup_remote_docker - run: name: Build image command: docker build -t dockle-ci-test:${CIRCLE_SHA1} . - run: name: Install dockle command: | apk add --update curl VERSION=$( curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \ grep '"tag_name":' | \ sed -E 's/.*"v([^"]+)".*/\1/' ) wget https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Linux-64bit.tar.gz tar zxvf dockle_${VERSION}_Linux-64bit.tar.gz mv dockle /usr/local/bin - run: name: Scan the local image with dockle command: dockle --exit-code 1 dockle-ci-test:${CIRCLE_SHA1} workflows: version: 2 release: jobs: - build ```
- 示例: https://circleci.com/gh/goodwithtech/dockle-ci-test - 仓库: https://github.com/goodwithtech/dockle-ci ## GitLab CI
.gitlab-ci.yml ``` image: docker:stable stages: - test variables: DOCKER_HOST: tcp://docker:2375/ DOCKER_DRIVER: overlay2 services: - docker:dind unit_test: stage: test before_script: - apk -Uuv add bash git curl tar sed grep script: - docker build -t dockle-ci-test:${CI_COMMIT_SHORT_SHA} . - | VERSION=$( curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \ grep '"tag_name":' | \ sed -E 's/.*"v([^"]+)".*/\1/' \ ) && curl -L -o dockle.tar.gz https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Linux-64bit.tar.gz && \ tar zxvf dockle.tar.gz - ./dockle --exit-code 1 dockle-ci-test:${CI_COMMIT_SHORT_SHA} ```
- 示例: https://gitlab.com/tomoyamachi/dockle-ci-test/-/jobs/238215077 - 仓库: https://github.com/goodwithtech/dockle-ci-test ## 私有 Docker Registry 授权 `Dockle` 可以从私有 registry 下载镜像,而无需安装 `Docker` 或任何其他第三方工具。这样设计是为了方便在 CI 流程中使用。 你需要做的就是:安装 `Dockle` 并设置环境变量。 - 注意:我不建议在本地机器上使用环境变量。 ### Docker Hub 要从 Docker Hub 下载私有仓库,你需要设置 `DOCKLE_AUTH_URL`、`DOCKLE_USERNAME` 和 `DOCKLE_PASSWORD` 环境变量。 ``` export DOCKLE_AUTH_URL=https://registry.hub.docker.com export DOCKLE_USERNAME={DOCKERHUB_USERNAME} export DOCKLE_PASSWORD={DOCKERHUB_PASSWORD} ``` - 注意:从公共仓库下载时不需要设置环境变量。 ### Amazon ECR (Elastic Container Registry) `Dockle` 使用 AWS SDK。你不需要安装 `aws` CLI 工具。 使用 [AWS CLI 的环境变量](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html)。 ``` export AWS_ACCESS_KEY_ID={AWS ACCESS KEY} export AWS_SECRET_ACCESS_KEY={SECRET KEY} export AWS_DEFAULT_REGION={AWS REGION} ``` ### GCR (Google Container Registry) `Dockle` 使用 Google Cloud SDK。因此,你不需要安装 `gcloud` 命令。 如果你想使用目标项目的仓库,可以通过 `GOOGLE_APPLICATION_CREDENTIAL` 进行设置。 ``` # 必须将 DOCKLE_USERNAME 设置为空字符 export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credential.json ``` ### 自托管 Registry (BasicAuth) BasicAuth 服务器需要 `DOCKLE_USERNAME` 和 `DOCKLE_PASSWORD`。 ``` export DOCKLE_USERNAME={USERNAME} export DOCKLE_PASSWORD={PASSWORD} # 如果你想使用 80 port,请使用 NonSSL export DOCKLE_NON_SSL=true ``` ## 贡献者 ### 代码贡献者 这个项目的存在要感谢所有做出贡献的人。[[参与贡献](CONTRIBUTING.md)]。 ### 资金贡献者 成为一名资金贡献者并帮助我们维持社区运转。[[参与贡献](https://opencollective.com/dockle/contribute)] #### 个人 #### 组织 用你的组织支持这个项目。你的 logo 将会显示在这里,并附带指向你网站的链接。[[参与贡献](https://opencollective.com/dockle/contribute)] ### OSS 项目支持者 本项目使用了以下 OSS 计划提供的服务。 # 许可证 - Apache License 2.0 # 作者 [@tomoyamachi](https://github.com/tomoyamachi) (Tomoya Amachi) 特别感谢 [@knqyf263](https://github.com/knqyf263) (Teppei Fukuda) 和 [Trivy](https://github.com/knqyf263/trivy)
标签:ATTACK-Python-Client, CIS Benchmark, DevSecOps, Docker, EVTX分析, LNA, 上游代理, 代码检查工具, 安全基线检查, 安全防御评估, 日志审计, 活动识别, 请求拦截, 镜像扫描