container-hadolintSkill container-hadolint

Dockerfile 安全检查工具,用于验证 Docker 构建文件是否符合安全最佳实践和 CIS Docker 基准,集成 ShellCheck 验证 RUN 指令安全性,提供多阶段构建验证和 CI/CD 集成支持。

CI/CD 0 次安装 0 次浏览 更新于 3/1/2026

container-hadolint 安全检查

概述

Hadolint 是一个 Dockerfile 检查工具,它根据安全最佳实践和 CIS Docker 基准验证容器构建文件。它在构建和部署镜像之前分析 Dockerfile 指令,识别配置错误、反模式和安全漏洞。

Hadolint 集成了 ShellCheck 来验证 RUN 指令,确保遵循安全最佳实践的 shell 命令。拥有 100 多个内置规则,与 CIS Docker 基准控制相映射,Hadolint 为容器镜像提供了全面的安全验证。

快速开始

安装 Hadolint

# macOS 通过 Homebrew 安装
brew install hadolint

# Linux 通过二进制文件安装
wget -O /usr/local/bin/hadolint https://github.com/hadolint/hadolint/releases/latest/download/hadolint-Linux-x86_64
chmod +x /usr/local/bin/hadolint

# 通过 Docker 安装
docker pull hadolint/hadolint

扫描 Dockerfile

# 扫描当前目录下的 Dockerfile
hadolint Dockerfile

# 扫描特定路径下的 Dockerfile
hadolint path/to/Dockerfile

# 使用 Docker 扫描
docker run --rm -i hadolint/hadolint < Dockerfile

生成报告

# JSON 输出,用于自动化
hadolint -f json Dockerfile > hadolint-report.json

# GitLab Code Quality 格式
hadolint -f gitlab_codeclimate Dockerfile > hadolint-codeclimate.json

# Checkstyle 格式,用于 CI 集成
hadolint -f checkstyle Dockerfile > hadolint-checkstyle.xml

核心工作流

1. 本地开发扫描

在开发过程中验证 Dockerfiles:

# 基本扫描,带彩色输出
hadolint Dockerfile

# 特定严重性阈值扫描
hadolint --failure-threshold error Dockerfile

# 只显示警告和错误
hadolint --no-color --format tty Dockerfile | grep -E "^(warning|error)"

# 详细输出,带规则 ID
hadolint -t style -t warning -t error Dockerfile

输出格式:

Dockerfile:3 DL3008 警告:在 apt-get install 中固定版本
Dockerfile:7 DL3025 错误:使用 JSON 表示法 CMD 和 ENTRYPOINT
Dockerfile:12 DL3059 信息:检测到多个 RUN 指令

何时使用: 开发者工作站,预提交验证,迭代 Dockerfile 开发。

2. CI/CD 流水线集成

在构建流水线中自动化 Dockerfile 验证:

GitHub Actions

name: Hadolint
on: [push, pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Hadolint Dockerfile
        uses: hadolint/hadolint-action@v3.1.0
        with:
          dockerfile: Dockerfile
          failure-threshold: warning
          format: sarif
          output-file: hadolint.sarif

      - name: 上传 SARIF 到 GitHub 安全
        if: always()
        uses: github/codeql-action/upload-sarif@v2
        with:
          sarif_file: hadolint.sarif

GitLab CI

hadolint:
  image: hadolint/hadolint:latest-debian
  stage: lint
  script:
    - hadolint -f gitlab_codeclimate Dockerfile > hadolint-report.json
  artifacts:
    reports:
      codequality: hadolint-report.json
    when: always

何时使用: 自动化安全门,拉取请求检查,部署验证。

3. 配置自定义

创建 .hadolint.yaml 自定义规则:

# .hadolint.yaml
failure-threshold: warning
ignored:
  - DL3008  # 允许未固定的 apt-get 包(先评估风险)
  - DL3059  # 允许多个 RUN 指令

trustedRegistries:
  - docker.io/library  # 官方 Docker Hub 镜像
  - gcr.io/distroless  # Google distroless 镜像
  - registry.access.redhat.com  # Red Hat 注册表

override:
  error:
    - DL3001  # 强制执行:永远不要在没有版本固定的情况下使用 yum/dnf/zypper
  warning:
    - DL3015  # 警告:使用 apt-get 时使用 --no-install-recommends
  info:
    - DL3059  # 信息:多个 RUN 指令减少层缓存

label-schema:
  maintainer: text
  org.opencontainers.image.vendor: text
  org.opencontainers.image.version: semver

使用 assets/ 中的捆绑模板:

  • assets/hadolint-strict.yaml - 严格的安全执行(仅 CRITICAL/HIGH)
  • assets/hadolint-balanced.yaml - 平衡验证(推荐)
  • assets/hadolint-permissive.yaml - 宽容的旧 Dockerfile 迁移

何时使用: 减少误报,组织标准,旧 Dockerfile 迁移。

4. 安全重点验证

强制执行关键安全规则:

# 只在安全问题上失败(错误严重性)
hadolint --failure-threshold error Dockerfile

# 检查特定安全规则
hadolint --trusted-registry docker.io/library Dockerfile

# 扫描项目中的所有 Dockerfiles
find . -name "Dockerfile*" -exec hadolint {} \;

# 生成仅包含错误的安全报告
hadolint -f json Dockerfile | jq '.[] | select(.level == "error")'

关键安全规则:

  • DL3000: 使用绝对 WORKDIR(防止目录遍历)
  • DL3001: 总是使用版本固定
  • DL3002: 永远不要在 Dockerfile 中切换到 root USER
  • DL3020: 使用 COPY 而不是 ADD(防止任意 URL 获取)
  • DL3025: 使用 JSON 表示法 CMD/ENTRYPOINT(防止 shell 注入)

查看 references/security_rules.md 获取完整的安全规则目录和 CIS 映射。

5. 多阶段构建验证

扫描复杂的多阶段 Dockerfiles:

# 验证所有阶段
hadolint Dockerfile

# 特定阶段验证(使用自定义脚本)
./scripts/hadolint_multistage.py Dockerfile

常见多阶段问题:

  • 在构建和运行时阶段使用相同的用户
  • 将不必要的构建工具复制到生产镜像
  • 最后阶段缺少安全硬化
  • 构建阶段中的秘密传播到运行时

何时使用: 复杂构建,安全硬化镜像,生产容器化。

6. 预提交钩子集成

防止不安全的 Dockerfiles 提交:

# 使用捆绑脚本安装预提交钩子
./scripts/install_precommit.sh

# 或手动创建钩子
cat << 'EOF' > .git/hooks/pre-commit
#!/bin/bash
for dockerfile in $(git diff --cached --name-only | grep -E 'Dockerfile'); do
  hadolint --failure-threshold warning "$dockerfile" || exit 1
done
EOF

chmod +x .git/hooks/pre-commit

何时使用: 开发者工作站,团队入职,强制安全控制。

安全考虑

敏感数据处理

  • 秘密检测:Hadolint 标记 ENV、ARG、LABEL 指令中硬编码的秘密
  • 构建秘密:使用 Docker BuildKit 秘密(RUN --mount=type=secret)而不是 ARG 用于凭证
  • 多阶段安全:确保构建阶段的秘密不会泄露到最终镜像
  • 镜像扫描:Hadolint 验证 Dockerfile - 结合镜像扫描(Trivy, Grype)进行运行时安全

访问控制

  • CI/CD 权限:Hadolint 扫描需要读取 Dockerfile 和构建上下文的权限
  • 报告存储:将扫描报告视为内部文档 - 可能揭示安全实践
  • 受信任的注册表:配置 trustedRegistries 以强制批准的基础镜像源

审计日志

记录以下内容以符合合规性和安全审计:

  • 扫描执行的时间戳和 Dockerfile 路径
  • 按严重性(错误、警告、信息)的规则违规
  • 被压制的规则和理由
  • 基础镜像注册表验证结果
  • 补救行动和时间表

合规性要求

  • CIS Docker 基准 1.6:Hadolint 规则映射到 CIS 控制(见 references/cis_mapping.md
    • 4.1: 为容器创建用户(DL3002)
    • 4.6: 添加 HEALTHCHECK 指令(DL3025)
    • 4.7: 不要在 Dockerfile 中单独使用更新(DL3009)
    • 4.9: 使用 COPY 而不是 ADD(DL3020)
  • OWASP Docker 安全:验证 OWASP 容器安全最佳实践
  • NIST SP 800-190:应用容器安全指南

捆绑资源

脚本(scripts/

  • hadolint_scan.py - 综合扫描多个 Dockerfiles 和输出格式
  • hadolint_multistage.py - 多阶段 Dockerfile 分析,特定阶段验证
  • install_precommit.sh - 自动化预提交钩子安装
  • ci_integration.sh - 多个平台的 CI/CD 集成示例

参考资料(references/

  • security_rules.md - 完整的 Hadolint 安全规则与 CIS 基准映射
  • cis_mapping.md - 详细的 CIS Docker 基准控制映射
  • remediation_guide.md - 逐条规则的补救指导,带有安全示例
  • shellcheck_integration.md - RUN 指令验证的 ShellCheck 规则

资产(assets/

  • hadolint-strict.yaml - 严格的安全配置
  • hadolint-balanced.yaml - 生产就绪配置(推荐)
  • hadolint-permissive.yaml - 旧 Dockerfile 迁移配置
  • github-actions.yml - 完整的 GitHub Actions 工作流
  • gitlab-ci.yml - 完整的 GitLab CI 流水线
  • precommit-config.yaml - 预提交框架配置

常见模式

模式 1: 初始 Dockerfile 安全审计

首次安全评估:

# 1. 查找所有 Dockerfiles
find . -type f -name "Dockerfile*" > dockerfile-list.txt

# 2. 用 JSON 输出扫描所有 Dockerfiles
mkdir -p security-reports
while read dockerfile; do
  output_file="security-reports/$(echo $dockerfile | tr '/' '_').json"
  hadolint -f json "$dockerfile" > "$output_file" 2>&1
done < dockerfile-list.txt

# 3. 生成摘要报告
./scripts/hadolint_scan.py --input-dir . --output summary-report.html

# 4. 审查关键/高发现
cat security-reports/*.json | jq '.[] | select(.level == "error")' > critical-findings.json

模式 2: 渐进式补救

逐步安全硬化:

# 第一阶段:基线(不要失败构建)
hadolint --failure-threshold none -f json Dockerfile > baseline.json

# 第二阶段:修复关键问题(仅错误失败)
hadolint --failure-threshold error Dockerfile

# 第三阶段:处理警告
hadolint --failure-threshold warning Dockerfile

# 第四阶段:完全合规(包括样式/信息)
hadolint Dockerfile

模式 3: 安全硬化的生产镜像

构建以安全为先的容器镜像:

# 遵循 Hadolint 最佳实践的示例安全 Dockerfile

# 使用受信任注册表中的特定基础镜像版本
FROM docker.io/library/node:18.19.0-alpine3.19

# 安装软件包,带版本固定和清理
RUN apk add --no-cache \
    dumb-init=1.2.5-r2 \
    && rm -rf /var/cache/apk/*

# 创建非根用户
RUN addgroup -g 1001 -S appuser && \
    adduser -S -u 1001 -G appuser appuser

# 设置工作目录
WORKDIR /app

# 复制应用程序文件(使用 COPY 而不是 ADD)
COPY --chown=appuser:appuser package*.json ./
COPY --chown=appuser:appuser . .

# 安装依赖项
RUN npm ci --only=production && \
    npm cache clean --force

# 切换到非根用户
USER appuser

# 暴露端口(仅文档,不是安全控制)
EXPOSE 3000

# 添加健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD node healthcheck.js || exit 1

# 使用 JSON 表示法进行入口/命令
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
CMD ["node", "server.js"]

用 Hadolint 验证:

hadolint Dockerfile  # 应该没有错误通过

模式 4: CI/CD 与自动补救建议

在拉取请求中提供可操作的反馈:

# 在 CI 流水线中
hadolint -f json Dockerfile > hadolint.json

# 生成补救建议
./scripts/hadolint_scan.py \
  --input hadolint.json \
  --format markdown \
  --output pr-comment.md

# 发布到 PR 评论(使用 gh CLI)
gh pr comment --body-file pr-comment.md

集成点

CI/CD 集成

  • GitHub Actions: 原生 hadolint-action 支持 SARIF 格式,用于安全标签
  • GitLab CI: GitLab Code Quality 格式集成
  • Jenkins: Checkstyle 格式用于 Jenkins Warnings 插件
  • CircleCI: 基于 Docker 的执行器与工件保留
  • Azure Pipelines: 任务集成与结果发布

安全工具生态系统

  • 镜像扫描: 结合 Trivy, Grype, Clair 进行运行时漏洞扫描
  • 秘密扫描: 集成 Gitleaks, TruffleHog 进行综合秘密检测
  • IaC 安全: 链式 Checkov 进行 Kubernetes/Terraform 验证
  • SBOM 生成: 与 Syft/Trivy SBOM 报告一起导出发现
  • 安全仪表板: 导出 JSON 到 Grafana, Kibana, Datadog 进行集中监控

SDLC 集成

  • 开发: 预提交钩子提供即时反馈
  • 代码审查: PR 检查防止不安全的 Dockerfiles 合并
  • 测试: 扫描测试环境 Dockerfiles
  • 暂存: 在生产推广前验证门
  • 生产: 定期审计部署的容器配置

故障排除

问题:太多误报

症状: 合法模式被标记(旧 Dockerfiles,特定用例)

解决方案:

# 创建 .hadolint.yaml
ignored:
  - DL3059  # 多个 RUN 指令(对于复杂构建有效)

# 或使用内联忽略
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y curl

参考 references/remediation_guide.md 获取特定规则的指导。

问题:基础镜像注册表不受信任

症状: 即使对于合法镜像,也会出现关于不受信任注册表的错误

解决方案:

# 添加到 .hadolint.yaml
trustedRegistries:
  - mycompany.azurecr.io
  - gcr.io/my-project
  - docker.io/library

问题:RUN 指令中的 ShellCheck 警告

症状: 来自 ShellCheck 集成的 SC2086, SC2046 警告

解决方案:

# 坏的:未引用变量
RUN echo $MY_VAR > file.txt

# 好的:引用变量
RUN echo "$MY_VAR" > file.txt

# 或禁用特定的 ShellCheck 规则
# hadolint ignore=DL4006
RUN echo $MY_VAR > file.txt

查看 references/shellcheck_integration.md 获取完整的 ShellCheck 指导。

问题:多阶段构建未被识别

症状: 尽管正确设置多阶段,但缺少 USER 指令的错误

解决方案:

# 确保每个阶段都有适当的 USER
FROM node:18 AS builder
# 构建操作...

FROM node:18-alpine AS runtime
USER node  # 在最后阶段添加 USER
CMD ["node", "app.js"]

问题:CI 流水线因警告而失败

症状: 构建因低严重性问题而失败

解决方案:

# 在 CI 中调整失败阈值
hadolint --failure-threshold error Dockerfile

# 或按环境配置
if [ "$CI_ENVIRONMENT" == "production" ]; then
  hadolint --failure-threshold warning Dockerfile
else
  hadolint --failure-threshold error Dockerfile
fi

高级配置

自定义规则严重性覆盖

# .hadolint.yaml
override:
  error:
    - DL3001  # 软件包版本控制至关重要
    - DL3020  # COPY 与 ADD 是安全关键
  warning:
    - DL3059  # 多个 RUN 是警告,不是信息
  info:
    - DL3008  # 将 apt-get 固定降级为开发镜像的信息

内联抑制

# 抑制单个指令的单个规则
# hadolint ignore=DL3018
RUN apk add --no-cache curl

# 抑制多个规则
# hadolint ignore=DL3003,DL3009
WORKDIR /tmp
RUN apt-get update && apt-get install -y wget

# 全局抑制(谨慎使用)
# hadolint global ignore=DL3059

受信任的注册表执行

# .hadolint.yaml
trustedRegistries:
  - docker.io/library      # 仅官方镜像
  - gcr.io/distroless      # Google distroless
  - cgr.dev/chainguard     # Chainguard 镜像

# 这将错误于:
# FROM nginx:latest                    ❌ (docker.io/nginx)
# FROM docker.io/library/nginx:latest  ✅ (受信任)

标签模式验证

# .hadolint.yaml
label-schema:
  maintainer: text
  org.opencontainers.image.created: rfc3339
  org.opencontainers.image.version: semver
  org.opencontainers.image.vendor: text

确保 Dockerfile LABELs 符合 OCI 镜像规范。

参考资料