Docker Scout 容器漏洞掃描

Docker Scout Container Vulnerability Scanning

前言

在現代雲原生應用程式開發中,容器安全已成為不可忽視的重要議題。隨著容器化技術的普及,攻擊者也開始針對容器映像檔中的漏洞進行攻擊。Docker Scout 是 Docker 官方推出的容器安全掃描工具,能夠幫助開發者在軟體開發生命週期的各個階段識別和修復安全漏洞。

本文將深入介紹 Docker Scout 的功能特性、安裝設定、使用方法,以及如何將其整合到 CI/CD 流程中。


Docker Scout 功能介紹

什麼是 Docker Scout?

Docker Scout 是一個容器映像檔分析工具,主要提供以下功能:

  • 漏洞掃描:分析容器映像檔中的已知安全漏洞(CVE)
  • SBOM 生成:自動產生軟體物料清單(Software Bill of Materials)
  • 政策評估:根據預定義或自訂政策評估映像檔的合規性
  • 修復建議:提供具體的漏洞修復方案和升級路徑
  • 持續監控:追蹤已部署映像檔的新發現漏洞

核心特色

功能說明
即時分析在本地或 Docker Hub 上即時掃描映像檔
深度解析分析所有層級的套件依賴關係
多來源比對整合多個漏洞資料庫進行交叉比對
原生整合與 Docker Desktop 和 Docker Hub 無縫整合
API 支援提供 REST API 供程式化存取

安裝與設定

前置需求

  • Docker Desktop 4.17.0 或更新版本(已內建 Docker Scout)
  • 或 Docker Engine 搭配 Docker Scout CLI 外掛

安裝 Docker Scout CLI

如果您使用的是 Docker Engine 而非 Docker Desktop,可以手動安裝 Docker Scout CLI 外掛:

1
2
3
4
5
6
7
8
# 建立 CLI 外掛目錄
mkdir -p ~/.docker/cli-plugins

# 下載最新版本的 Docker Scout CLI
curl -sSfL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh | sh -s --

# 驗證安裝
docker scout version

透過套件管理器安裝

1
2
3
4
5
6
# macOS 使用 Homebrew
brew install docker/tap/docker-scout

# 或直接下載二進位檔
curl -fsSL https://github.com/docker/scout-cli/releases/latest/download/docker-scout_linux_amd64.tar.gz | tar -xz
sudo mv docker-scout /usr/local/bin/

登入 Docker Hub

使用 Docker Scout 前需要先登入 Docker Hub:

1
2
3
4
5
# 登入 Docker Hub
docker login

# 確認登入狀態
docker info | grep Username

啟用 Docker Scout

1
2
3
4
5
# 為特定 Repository 啟用 Docker Scout
docker scout repo enable <organization>/<repository>

# 查看已啟用的 Repository
docker scout repo list

映像檔掃描基礎

快速掃描

最基本的掃描方式是使用 docker scout quickview 命令:

1
2
3
4
5
6
7
8
# 掃描本地映像檔
docker scout quickview nginx:latest

# 掃描特定映像檔
docker scout quickview myapp:v1.0.0

# 掃描 Docker Hub 上的映像檔
docker scout quickview docker/scout-cli:latest

輸出範例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
    ✓ Image stored for indexing
    ✓ Indexed 187 packages

  Target     │  nginx:latest       │    0C     2H    12M    25L
    digest   │  a8758716bb6a       │
  Base image │  debian:bookworm-slim

  What's Next?
    View vulnerabilities → docker scout cves nginx:latest
    View base image update recommendations → docker scout recommendations nginx:latest

詳細漏洞掃描

使用 docker scout cves 命令進行詳細的漏洞分析:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 完整 CVE 掃描
docker scout cves nginx:latest

# 僅顯示高危及嚴重漏洞
docker scout cves --only-severity critical,high nginx:latest

# 輸出為 JSON 格式
docker scout cves --format json nginx:latest > vulnerabilities.json

# 輸出為 SARIF 格式(適用於 GitHub Security)
docker scout cves --format sarif nginx:latest > scout-results.sarif

# 只掃描特定類型的套件
docker scout cves --only-package-type npm nginx:latest

掃描結果過濾

1
2
3
4
5
6
7
8
# 過濾特定 CVE
docker scout cves --only-cve CVE-2024-1234 nginx:latest

# 排除特定套件
docker scout cves --ignore-package openssl nginx:latest

# 僅顯示可修復的漏洞
docker scout cves --only-fixed nginx:latest

比較兩個映像檔

1
2
3
4
5
# 比較兩個版本的漏洞差異
docker scout compare nginx:1.24 --to nginx:1.25

# 比較本地與遠端映像檔
docker scout compare myapp:local --to myapp:production

輸出範例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
    ✓ Analyzed image nginx:1.24
    ✓ Analyzed image nginx:1.25

                           │ nginx:1.24 │ nginx:1.25 │
  ─────────────────────────┼────────────┼────────────┤
    Packages               │    187     │    185     │
    Critical vulnerabilities│     0      │     0      │
    High vulnerabilities   │     2      │     0      │
    Medium vulnerabilities │    12      │     8      │
    Low vulnerabilities    │    25      │    20      │

SBOM 軟體物料清單

什麼是 SBOM?

軟體物料清單(Software Bill of Materials, SBOM)是一份詳細列出軟體組成元件的清單,包含:

  • 套件名稱與版本
  • 授權資訊
  • 依賴關係
  • 來源資訊

生成 SBOM

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 生成 SPDX 格式的 SBOM
docker scout sbom nginx:latest --format spdx > sbom-spdx.json

# 生成 CycloneDX 格式的 SBOM
docker scout sbom nginx:latest --format cyclonedx > sbom-cyclonedx.json

# 生成簡易格式的 SBOM
docker scout sbom nginx:latest --format list

# 僅列出特定類型的套件
docker scout sbom --only-package-type apk,deb nginx:latest

SBOM 輸出範例

1
docker scout sbom --format list nginx:latest | head -20

輸出:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
  Name                    Version              Type
  ─────────────────────────────────────────────────
  adduser                 3.134                deb
  apt                     2.6.1                deb
  base-files              12.4+deb12u5         deb
  base-passwd             3.6.1                deb
  bash                    5.2.15-2+b2          deb
  bsdutils                1:2.38.1-5+b1        deb
  coreutils               9.1-1                deb
  curl                    7.88.1-10+deb12u5    deb
  ...

分析 SBOM 內容

1
2
3
4
5
# 查看套件授權資訊
docker scout sbom nginx:latest --format spdx | jq '.packages[] | {name: .name, license: .licenseConcluded}'

# 統計套件類型
docker scout sbom nginx:latest --format list | awk '{print $3}' | sort | uniq -c

CVE 漏洞分析與修復建議

漏洞嚴重程度分類

Docker Scout 使用 CVSS(Common Vulnerability Scoring System)評分系統:

等級CVSS 分數說明
Critical9.0 - 10.0嚴重漏洞,需立即修復
High7.0 - 8.9高危漏洞,應優先處理
Medium4.0 - 6.9中等風險,計劃性修復
Low0.1 - 3.9低風險,可視情況處理

詳細漏洞資訊

1
2
3
4
5
# 查看完整漏洞詳情
docker scout cves --format markdown nginx:latest

# 查看特定 CVE 的詳細資訊
docker scout cves nginx:latest 2>&1 | grep -A 10 "CVE-2024"

獲取修復建議

1
2
3
4
5
# 查看基礎映像檔升級建議
docker scout recommendations nginx:latest

# 查看詳細的修復建議
docker scout recommendations --format json nginx:latest

輸出範例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
  Current base image: debian:bookworm-slim
    - Vulnerabilities: 2C 5H 15M 30L

  Recommended updates:

  1. Update to debian:bookworm-slim (newer version)
     - Vulnerabilities: 0C 2H 10M 25L
     - Reduces: 2C 3H 5M 5L

  2. Switch to alpine:3.19
     - Vulnerabilities: 0C 0H 2M 5L
     - Reduces: 2C 5H 13M 25L

建立 VEX 聲明

VEX(Vulnerability Exploitability eXchange)允許您聲明某些漏洞在您的環境中不受影響:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 建立 VEX 聲明檔案
cat > vex.json << 'EOF'
{
  "@context": "https://openvex.dev/ns/v0.2.0",
  "@id": "https://example.com/vex/myapp",
  "author": "security@example.com",
  "timestamp": "2025-05-19T00:00:00Z",
  "statements": [
    {
      "vulnerability": {
        "@id": "CVE-2024-1234"
      },
      "products": [
        {
          "@id": "pkg:docker/myapp@1.0.0"
        }
      ],
      "status": "not_affected",
      "justification": "vulnerable_code_not_present"
    }
  ]
}
EOF

# 使用 VEX 聲明進行掃描
docker scout cves --vex-location ./vex.json myapp:1.0.0

政策與合規性檢查

內建政策

Docker Scout 提供多種內建安全政策:

1
2
3
4
5
# 列出所有可用政策
docker scout policy list

# 查看政策詳情
docker scout policy inspect <policy-name>

常見的內建政策:

政策名稱說明
no-critical-vulnerabilities不允許存在嚴重漏洞
no-high-vulnerabilities不允許存在高危漏洞
no-fixable-vulnerabilities不允許存在可修復的漏洞
approved-base-images僅允許使用核准的基礎映像檔
no-unapproved-licenses不允許使用未核准的授權

評估映像檔政策

1
2
3
4
5
6
7
8
# 評估單一映像檔
docker scout policy evaluate nginx:latest

# 評估特定政策
docker scout policy evaluate --policy no-critical-vulnerabilities nginx:latest

# 輸出 JSON 格式的評估結果
docker scout policy evaluate --format json nginx:latest

自訂政策

建立自訂政策檔案 custom-policy.yaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# custom-policy.yaml
version: "1.0"
policies:
  - name: production-ready
    description: "生產環境映像檔安全標準"
    rules:
      - type: vulnerability
        severity:
          - critical
        action: deny
        message: "不允許存在嚴重漏洞"

      - type: vulnerability
        severity:
          - high
        max_count: 5
        action: warn
        message: "高危漏洞數量超過閾值"

      - type: base-image
        allowed:
          - "alpine:3.*"
          - "debian:bookworm-slim"
          - "ubuntu:22.04"
        action: deny
        message: "必須使用核准的基礎映像檔"

      - type: license
        denied:
          - "GPL-3.0"
          - "AGPL-3.0"
        action: warn
        message: "包含受限授權的套件"
1
2
# 使用自訂政策評估
docker scout policy evaluate --policy-file custom-policy.yaml myapp:latest

組織級政策管理

1
2
3
4
5
# 為組織設定預設政策
docker scout config organization <org-name> --policy no-critical-vulnerabilities

# 查看組織政策狀態
docker scout policy status --org <org-name>

CI/CD 整合

GitHub Actions 整合

建立 .github/workflows/docker-scout.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
name: Docker Scout Security Scan

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build image
        uses: docker/build-push-action@v5
        with:
          context: .
          push: false
          load: true
          tags: ${{ github.repository }}:${{ github.sha }}

      - name: Docker Scout Quickview
        uses: docker/scout-action@v1
        with:
          command: quickview
          image: ${{ github.repository }}:${{ github.sha }}

      - name: Docker Scout CVE Scan
        uses: docker/scout-action@v1
        with:
          command: cves
          image: ${{ github.repository }}:${{ github.sha }}
          only-severities: critical,high
          exit-code: true

      - name: Docker Scout SBOM
        uses: docker/scout-action@v1
        with:
          command: sbom
          image: ${{ github.repository }}:${{ github.sha }}
          output: sbom.spdx.json

      - name: Upload SBOM
        uses: actions/upload-artifact@v4
        with:
          name: sbom
          path: sbom.spdx.json

      - name: Compare with previous version
        uses: docker/scout-action@v1
        if: github.event_name == 'pull_request'
        with:
          command: compare
          image: ${{ github.repository }}:${{ github.sha }}
          to: ${{ github.repository }}:latest
          exit-code: true
          only-severities: critical,high

GitLab CI 整合

建立 .gitlab-ci.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
stages:
  - build
  - scan
  - deploy

variables:
  DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

build:
  stage: build
  image: docker:24
  services:
    - docker:24-dind
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build -t $DOCKER_IMAGE .
    - docker push $DOCKER_IMAGE

scout-scan:
  stage: scan
  image: docker:24
  services:
    - docker:24-dind
  before_script:
    - apk add --no-cache curl
    - curl -sSfL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh | sh -s --
    - docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_TOKEN
  script:
    - docker pull $DOCKER_IMAGE
    - docker scout cves $DOCKER_IMAGE --exit-code --only-severity critical,high
    - docker scout sbom $DOCKER_IMAGE --format spdx > sbom.json
  artifacts:
    paths:
      - sbom.json
    expire_in: 1 week
  allow_failure: false

scout-policy:
  stage: scan
  image: docker:24
  services:
    - docker:24-dind
  before_script:
    - apk add --no-cache curl
    - curl -sSfL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh | sh -s --
    - docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_TOKEN
  script:
    - docker pull $DOCKER_IMAGE
    - docker scout policy evaluate $DOCKER_IMAGE
  allow_failure: true

Jenkins Pipeline 整合

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Jenkinsfile
pipeline {
    agent any

    environment {
        DOCKER_IMAGE = "${env.DOCKER_REGISTRY}/${env.JOB_NAME}:${env.BUILD_NUMBER}"
        DOCKERHUB_CREDENTIALS = credentials('dockerhub-credentials')
    }

    stages {
        stage('Build') {
            steps {
                script {
                    docker.build(DOCKER_IMAGE)
                }
            }
        }

        stage('Security Scan') {
            steps {
                script {
                    // 登入 Docker Hub
                    sh '''
                        echo $DOCKERHUB_CREDENTIALS_PSW | docker login -u $DOCKERHUB_CREDENTIALS_USR --password-stdin
                    '''

                    // 執行 Docker Scout 掃描
                    sh '''
                        docker scout cves ${DOCKER_IMAGE} --format sarif --output scout-results.sarif
                        docker scout cves ${DOCKER_IMAGE} --only-severity critical,high --exit-code
                    '''
                }
            }
            post {
                always {
                    // 上傳 SARIF 結果
                    archiveArtifacts artifacts: 'scout-results.sarif', fingerprint: true
                }
            }
        }

        stage('SBOM Generation') {
            steps {
                sh '''
                    docker scout sbom ${DOCKER_IMAGE} --format spdx --output sbom.spdx.json
                '''
            }
            post {
                always {
                    archiveArtifacts artifacts: 'sbom.spdx.json', fingerprint: true
                }
            }
        }

        stage('Policy Check') {
            steps {
                sh '''
                    docker scout policy evaluate ${DOCKER_IMAGE} || true
                '''
            }
        }

        stage('Push') {
            when {
                branch 'main'
            }
            steps {
                script {
                    docker.withRegistry("https://${env.DOCKER_REGISTRY}", 'docker-registry-credentials') {
                        docker.image(DOCKER_IMAGE).push()
                        docker.image(DOCKER_IMAGE).push('latest')
                    }
                }
            }
        }
    }

    post {
        always {
            sh 'docker logout'
        }
    }
}

使用 Pre-commit Hook

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash
# .git/hooks/pre-push

echo "Running Docker Scout security scan..."

# 取得要推送的映像檔標籤
IMAGE_TAG=$(docker images --format "{{.Repository}}:{{.Tag}}" | head -1)

if [ -z "$IMAGE_TAG" ]; then
    echo "No Docker image found. Skipping scan."
    exit 0
fi

# 執行掃描
docker scout cves "$IMAGE_TAG" --only-severity critical,high --exit-code

if [ $? -ne 0 ]; then
    echo "❌ Security scan failed! Critical or high vulnerabilities detected."
    echo "Please fix the vulnerabilities before pushing."
    exit 1
fi

echo "✅ Security scan passed."
exit 0

與其他工具比較

Docker Scout vs Trivy vs Snyk

功能特性Docker ScoutTrivySnyk
授權模式免費 + 付費方案開源免費免費 + 付費方案
掃描速度快速非常快速中等
漏洞資料庫多來源整合多來源整合Snyk 專屬資料庫
SBOM 支援SPDX, CycloneDXSPDX, CycloneDXSPDX
政策引擎內建需搭配 OPA內建
IDE 整合Docker DesktopVS Code 外掛多種 IDE
CI/CD 整合原生支援原生支援原生支援
修復建議詳細基本詳細
容器 Runtime 掃描有限支援支援
IaC 掃描不支援支援支援

Trivy 使用範例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 安裝 Trivy
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin

# 掃描映像檔
trivy image nginx:latest

# 僅顯示嚴重漏洞
trivy image --severity CRITICAL,HIGH nginx:latest

# 生成 SBOM
trivy image --format spdx-json -o sbom.json nginx:latest

Snyk 使用範例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 安裝 Snyk CLI
npm install -g snyk

# 登入
snyk auth

# 掃描容器映像檔
snyk container test nginx:latest

# 監控映像檔
snyk container monitor nginx:latest

選擇建議

使用情境建議工具
已使用 Docker 生態系統Docker Scout
需要開源且快速的方案Trivy
企業級功能與支援Snyk
需要 IaC 掃描整合Trivy 或 Snyk
注重修復建議品質Docker Scout 或 Snyk
預算有限Trivy

多工具整合策略

在實際生產環境中,建議結合多種工具以獲得更全面的安全覆蓋:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 多工具掃描 GitHub Actions 範例
name: Multi-tool Security Scan

on:
  push:
    branches: [main]

jobs:
  security-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build image
        run: docker build -t myapp:${{ github.sha }} .

      # Docker Scout 掃描
      - name: Docker Scout Scan
        uses: docker/scout-action@v1
        with:
          command: cves
          image: myapp:${{ github.sha }}
          sarif-file: scout-results.sarif

      # Trivy 掃描
      - name: Trivy Scan
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: myapp:${{ github.sha }}
          format: sarif
          output: trivy-results.sarif

      # Snyk 掃描
      - name: Snyk Scan
        uses: snyk/actions/docker@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        with:
          image: myapp:${{ github.sha }}
          args: --sarif-file-output=snyk-results.sarif

      # 上傳所有結果到 GitHub Security
      - name: Upload SARIF results
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: .

最佳實踐

1. 建立安全基線

1
2
3
4
5
# 定期掃描基礎映像檔
docker scout cves alpine:3.19 --format json > baseline-alpine.json

# 比較應用程式映像檔與基線
docker scout compare myapp:latest --to alpine:3.19

2. 自動化漏洞通知

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#!/bin/bash
# daily-scan.sh

IMAGES=("myapp:production" "myapi:production" "myworker:production")
THRESHOLD="high"

for image in "${IMAGES[@]}"; do
    result=$(docker scout cves "$image" --only-severity critical,high --format json)
    count=$(echo "$result" | jq '.vulnerabilities | length')

    if [ "$count" -gt 0 ]; then
        echo "⚠️ $image has $count $THRESHOLD+ vulnerabilities" | \
            mail -s "Security Alert: $image" security@example.com
    fi
done

3. 映像檔標籤策略

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Dockerfile 最佳實踐
# 使用固定版本標籤
FROM alpine:3.19.1@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b

# 使用非 root 使用者
RUN adduser -D appuser
USER appuser

# 最小化安裝
RUN apk add --no-cache python3 && \
    rm -rf /var/cache/apk/*

4. 持續監控

1
2
3
4
5
# 啟用持續監控
docker scout watch myorg/myapp

# 設定 Webhook 通知
docker scout config set webhook-url https://hooks.slack.com/services/xxx

結論

Docker Scout 作為 Docker 官方推出的容器安全掃描工具,提供了完整的漏洞掃描、SBOM 生成、政策評估等功能。其與 Docker 生態系統的原生整合使其成為使用 Docker 的團隊的理想選擇。

透過本文介紹的各項功能和 CI/CD 整合方法,您可以將容器安全檢查融入軟體開發生命週期的各個階段,實現「左移安全」(Shift Left Security)的目標。

無論您選擇使用 Docker Scout、Trivy 還是 Snyk,重要的是建立持續的安全掃描流程,及時發現並修復漏洞,確保容器化應用程式的安全性。


參考資源

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy