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(?
结果
``` 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 ```结果
``` 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 ```结果
``` { "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" ] } ] } ```结果
``` { "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" } } ] } ] } ```.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} ```.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 ```.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} ```
标签:ATTACK-Python-Client, CIS Benchmark, DevSecOps, Docker, EVTX分析, LNA, 上游代理, 代码检查工具, 安全基线检查, 安全防御评估, 日志审计, 活动识别, 请求拦截, 镜像扫描