はじめに

Dockerイメージを本番環境にデプロイする際、機能面だけでなくセキュリティ面も重要な検討事項となります。脆弱性を含むイメージをデプロイすれば、サイバー攻撃の格好の標的となりかねません。

本記事では、Dockerイメージのセキュリティ対策として、Docker Scoutによる脆弱性スキャン、信頼できるベースイメージの選定、Docker Content Trustによるイメージ署名、そして最小権限の原則に基づくnon-rootユーザー実行について体系的に解説します。この記事を読み終えると、以下のことができるようになります。

  • Dockerイメージに潜むセキュリティリスクを理解できる
  • Docker Scoutを使って脆弱性スキャンを実施できる
  • 信頼できるベースイメージを適切に選定できる
  • Docker Content Trustでイメージの署名・検証を行える
  • non-rootユーザーでコンテナを安全に実行できる

前提として、Dockerの基本操作とDockerfileの書き方を習得済みであることを想定しています。まだDockerfileの基本を押さえていない場合は、Dockerfile入門 - 基本構文とビルドの流れを参照してください。

Dockerイメージのセキュリティリスク

Dockerイメージに潜むセキュリティリスクを理解することが、適切な対策を講じる第一歩です。

なぜDockerイメージのセキュリティが重要か

コンテナは軽量で高速なデプロイが可能ですが、その反面、脆弱性を含んだイメージが広範囲に拡散するリスクもあります。

リスク 説明
既知の脆弱性(CVE) OSパッケージやライブラリに存在する既知のセキュリティホール
悪意あるイメージ 信頼できないソースからのイメージにマルウェアが含まれる可能性
過剰な権限 rootユーザーでの実行によるホストシステムへの影響
機密情報の漏洩 イメージ内に埋め込まれたAPIキーやパスワード
古いベースイメージ パッチが適用されていない古いバージョンの使用

脆弱性の影響度

脆弱性は一般的にCVSS(Common Vulnerability Scoring System)スコアに基づいて分類されます。

CVSSスコア 深刻度 説明
9.0 - 10.0 Critical(C) 即座に対応が必要な重大な脆弱性
7.0 - 8.9 High(H) 早急な対応が推奨される高リスク
4.0 - 6.9 Medium(M) 計画的な対応が必要
0.1 - 3.9 Low(L) リスクは低いが対応を検討

特にCriticalやHighの脆弱性が検出された場合は、速やかに対応策を講じる必要があります。

セキュリティ対策の全体像

Dockerイメージのセキュリティ対策は、以下の4つの柱で構成されます。

flowchart LR
    subgraph Scan["脆弱性スキャン"]
        Scout["Docker Scout"]
        SBOM["SBOM生成"]
        Monitor["継続的モニタリング"]
    end
    subgraph Base["ベースイメージ選定"]
        Official["公式イメージ"]
        Lightweight["軽量イメージ"]
        Update["定期的な更新"]
    end
    subgraph Sign["イメージ署名"]
        DCT["Docker Content Trust"]
        Verify["署名の検証"]
    end
    subgraph MinPriv["最小権限の原則"]
        NonRoot["non-root実行"]
        ReadOnly["読み取り専用FS"]
        Caps["Capabilities制限"]
    end

以降のセクションで、それぞれの対策を詳しく解説します。

信頼できるベースイメージの選び方

Dockerイメージのセキュリティは、ベースイメージの選択から始まります。適切なベースイメージを選ぶことで、脆弱性のリスクを大幅に低減できます。

公式イメージを優先する

Docker Hubには「Docker Official Images」と呼ばれる公式イメージが用意されています。これらは以下の特徴を持ちます。

  • Dockerが公式にメンテナンスしている
  • セキュリティスキャンが定期的に実施されている
  • ベストプラクティスに基づいて構築されている
  • ドキュメントが充実している

公式イメージは、Docker Hubのイメージ名に「Official Image」バッジが付与されています。

1
2
3
4
5
# 公式イメージを使用(推奨)
FROM node:22-alpine

# 非公式イメージ(信頼性の確認が必要)
FROM some-random-user/node-custom

Docker Hardened Imagesの活用

Dockerは2025年より「Docker Hardened Images」を提供しています。これらは以下の特徴を持つ、セキュリティが強化されたイメージです。

  • 既知の脆弱性(CVE)がゼロまたは最小限
  • 不要なパッケージが削除されている
  • 定期的にセキュリティパッチが適用される
  • SBOM(Software Bill of Materials)が添付されている

Docker Hardened Imagesは、本番環境でのセキュリティ要件が厳しい場合に特に有効です。

軽量ベースイメージの選択

イメージに含まれるパッケージが少ないほど、攻撃対象が狭まります。主な軽量ベースイメージを比較してみましょう。

ベースイメージ サイズ パッケージ数 ユースケース
scratch 0 MB 0 静的バイナリ(Go等)
distroless 約2-20 MB 最小限 本番環境向け
Alpine 約5 MB 基本的なもののみ 汎用的な軽量環境
Debian slim 約30 MB 基本的なもののみ glibc互換が必要な場合
Ubuntu 約70 MB 標準的 開発環境・デバッグ用

軽量イメージを選択する際の考慮点を以下に示します。

1
2
3
4
5
6
7
8
# Alpine: 軽量だがmusl libcを使用(glibc互換性に注意)
FROM node:22-alpine

# Debian slim: glibcベースで互換性が高い
FROM node:22-slim

# distroless: シェルなし、最小構成(デバッグが困難)
FROM gcr.io/distroless/nodejs22-debian12

イメージタグの固定

latestタグを使用すると、予期せぬアップデートでビルドが壊れたり、脆弱性が混入したりする可能性があります。特定のバージョンやダイジェストを指定することを推奨します。

1
2
3
4
5
6
7
8
# 非推奨: latestタグ
FROM node:latest

# 推奨: メジャー・マイナーバージョンを指定
FROM node:22.12-alpine

# より厳密: ダイジェストを指定(完全な再現性)
FROM node:22.12-alpine@sha256:abcd1234...

ベースイメージの定期的な更新

ベースイメージは定期的に更新することが重要です。Docker Scoutを使用すると、古いベースイメージを検出し、更新を推奨してくれます。

1
2
# ベースイメージの更新状況を確認
docker scout quickview myapp:latest

出力例として、ベースイメージの更新が推奨される場合は以下のように表示されます。

Your image  myapp:latest           │    0C     2H     8M     1L
Base image  alpine:3.18            │    0C     1H     3M     0L
Updated base image  alpine:3.21    │    0C     0H     0M     0L
                                   │    0     -1     -3      0

脆弱性スキャンの実践(Docker Scout)

Docker Scoutは、Dockerが提供する脆弱性スキャンおよびソフトウェアサプライチェーン管理ツールです。イメージを分析し、含まれるパッケージの脆弱性を検出します。

Docker Scoutの概要

Docker Scoutは以下の機能を提供します。

  • イメージの脆弱性スキャン
  • SBOM(Software Bill of Materials)の生成
  • ポリシー評価とコンプライアンスチェック
  • ベースイメージの更新推奨
  • CI/CDパイプラインとの統合

Docker DesktopおよびDocker CLIから利用可能で、Docker Hubとも統合されています。

Docker Scoutのセットアップ

Docker Scoutは、Docker Desktop 4.17以降に含まれています。CLIでの利用には、まずDocker Hubにログインする必要があります。

1
2
3
4
5
6
7
8
# Docker Hubにログイン
docker login

# 組織をDocker Scoutに登録(初回のみ)
docker scout enroll YOUR_ORG_NAME

# リポジトリでDocker Scoutを有効化
docker scout repo enable --org YOUR_ORG_NAME YOUR_ORG_NAME/myapp

脆弱性スキャンの実行

docker scoutコマンドを使用して、ローカルイメージの脆弱性をスキャンできます。

1
2
# クイックビュー: 脆弱性の概要を表示
docker scout quickview myapp:latest

出力例は以下のようになります。

    ✓ SBOM of image already cached, 187 packages indexed

  Your image  myapp:latest       │    2C    16H    35M    10L
  Base image  debian:bookworm    │    0C     1H     6M     8L

各列は深刻度別の脆弱性数を示しています。

  • C: Critical(重大)
  • H: High(高)
  • M: Medium(中)
  • L: Low(低)

詳細な脆弱性情報の取得

docker scout cvesコマンドで、検出された脆弱性の詳細を確認できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# すべてのCVEを表示
docker scout cves myapp:latest

# 特定のパッケージの脆弱性のみ表示
docker scout cves --only-package express myapp:latest

# 深刻度でフィルタリング
docker scout cves --only-severity critical,high myapp:latest

# 脆弱なパッケージのみを一覧表示
docker scout cves --format only-packages --only-vuln-packages myapp:latest

出力例を以下に示します。

    ✗ Detected 10 vulnerable packages with a total of 17 vulnerabilities

     Name            Version         Type        Vulnerabilities
───────────────────────────────────────────────────────────────────────────
  openssl     3.0.11              deb      1C     2H     0M     0L
  glibc       2.36-9              deb      0C     1H     3M     0L
  express     4.17.1              npm      0C     1H     0M     0L

SBOMの生成と活用

SBOM(Software Bill of Materials)は、イメージに含まれるソフトウェアコンポーネントの一覧です。Docker Scoutはイメージ分析時に自動的にSBOMを生成しますが、ビルド時にアテステーション(証明)として添付することも可能です。

1
2
# SBOMアテステーション付きでビルド
docker build --sbom=true --provenance=true -t myapp:latest .

SBOMをビルド時に添付することで、以下のメリットがあります。

  • 分析速度の向上(SBOMを再生成する必要がない)
  • 10GBを超える大きなイメージの分析が可能
  • サプライチェーンの透明性向上

ポリシー評価

Docker Scoutはポリシー評価機能を提供し、組織のセキュリティ基準への準拠状況を確認できます。

1
2
3
4
5
# 組織の設定
docker scout config organization YOUR_ORG_NAME

# ポリシー評価を含むクイックビュー
docker scout quickview myapp:latest

デフォルトで以下のようなポリシーが評価されます。

Policy status  FAILED  (2/6 policies met, 2 missing data)

  Status │                  Policy                      │           Results
─────────┼──────────────────────────────────────────────┼──────────────────────────
  ✓      │ No copyleft licenses                         │    0 packages
  !      │ Default non-root user                        │
  !      │ No fixable critical or high vulnerabilities  │    2C    16H     0M     0L
  ✓      │ No high-profile vulnerabilities              │    0C     0H     0M     0L
  ?      │ No outdated base images                      │    No data
  ?      │ Supply chain attestations                    │    No data

ポリシー違反がある場合は、表示された内容に従って修正を行います。

CI/CDパイプラインへの統合

Docker ScoutはGitHub ActionsなどのCI/CDパイプラインに統合できます。以下はGitHub Actionsでの使用例です。

 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
name: Docker Build and Scan

on:
  push:
    branches: [main]

jobs:
  build-and-scan:
    runs-on: ubuntu-latest
    steps:
      - 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 and push
        uses: docker/build-push-action@v6
        with:
          push: true
          tags: ${{ secrets.DOCKERHUB_USERNAME }}/myapp:${{ github.sha }}
          sbom: true
          provenance: true

      - name: Docker Scout Scan
        uses: docker/scout-action@v1
        with:
          command: cves
          image: ${{ secrets.DOCKERHUB_USERNAME }}/myapp:${{ github.sha }}
          only-severities: critical,high
          exit-code: true  # Critical/Highがあれば失敗

イメージ署名とDocker Content Trust

イメージの信頼性を確保するためには、署名と検証の仕組みが重要です。Docker Content Trust(DCT)を使用することで、イメージの発行者と完全性を検証できます。

Docker Content Trustの概要

Docker Content Trust(DCT)は、イメージに対するデジタル署名機能を提供します。

  • 発行者の認証: 署名によりイメージの発行者を確認できる
  • 完全性の保証: イメージが改ざんされていないことを検証できる
  • タグの保護: 署名されたタグのみを信頼して使用できる

DCTはNotaryプロジェクトをベースにしており、署名キーの管理と検証を行います。

注意: Dockerは公式イメージ(DOI)に対するDCTのサポートを段階的に終了し、SigstoreやNotationなど新しい署名ソリューションへの移行を推奨しています。新規プロジェクトでは、これらの代替手段も検討してください。

DCTの有効化

DCTを有効化するには、環境変数DOCKER_CONTENT_TRUSTを設定します。

1
2
3
4
5
# DCTを有効化
export DOCKER_CONTENT_TRUST=1

# DCTを無効化
export DOCKER_CONTENT_TRUST=0

DCTが有効な状態では、以下のコマンドが署名付きイメージのみを対象とします。

  • docker pull
  • docker push
  • docker build
  • docker run
  • docker create

署名キーの生成

イメージに署名するには、まず署名キーを生成する必要があります。

1
2
3
4
5
6
7
8
9
# 署名キーを生成
docker trust key generate your-name

# 出力例
Generating key for your-name...
Enter passphrase for new your-name key with ID abc1234:
Repeat passphrase for new your-name key with ID abc1234:
Successfully generated and loaded private key.
Corresponding public key available: /home/user/your-name.pub

生成されたキーは~/.docker/trust/ディレクトリに保存されます。

イメージへの署名

署名キーを使用してイメージに署名し、レジストリにプッシュします。

1
2
3
4
5
# 署名者を追加(リポジトリごとに初回のみ)
docker trust signer add --key your-name.pub your-name registry.example.com/myapp

# イメージに署名してプッシュ
docker trust sign registry.example.com/myapp:v1.0

または、DCTを有効化した状態で通常のdocker pushを実行すると、自動的に署名が行われます。

1
2
export DOCKER_CONTENT_TRUST=1
docker push registry.example.com/myapp:v1.0

署名の検証

署名されたイメージの情報を確認できます。

1
2
# 署名情報を表示
docker trust inspect --pretty registry.example.com/myapp:v1.0

出力例は以下のようになります。

Signatures for registry.example.com/myapp:v1.0

SIGNED TAG    DIGEST                                    SIGNERS
v1.0          abc123def456789...                        your-name

List of signers and their keys for registry.example.com/myapp:v1.0

SIGNER        KEYS
your-name     abc1234def

Administrative keys for registry.example.com/myapp:v1.0

  Repository Key: 10b5e94c916a0977471cc08fa56c1a5679819b2005ba6a257aa78ce76d3a1e27
  Root Key:       84ca6e4416416d78c4597e754f38517bea95ab427e5f95871f90d460573071fc

署名されていないイメージの拒否

DCTが有効な状態で署名されていないイメージをpullしようとすると、エラーが発生します。

1
2
3
4
5
export DOCKER_CONTENT_TRUST=1
docker pull unsigned-image:latest

# エラー出力
Error: remote trust data does not exist for unsigned-image:latest

ただし、ダイジェスト(SHA256ハッシュ)を指定した場合は、署名がなくてもpull可能です。

1
docker pull myimage@sha256:abc123def456...

キーの管理とバックアップ

署名キーは非常に重要な資産です。特にルートキーを紛失すると、リポジトリの信頼性を回復できなくなります。

1
2
3
4
5
# キーのバックアップ(オフラインストレージに保管)
tar -czf docker-trust-keys-backup.tar.gz ~/.docker/trust/

# キーのインポート
docker trust key load backup-key.pem --name backup-signer

ルートキーはオフラインの安全な場所に保管し、日常的な署名にはデリゲーションキーを使用することを推奨します。

最小権限の原則とnon-root実行

コンテナを最小限の権限で実行することは、セキュリティ対策の基本です。特に、rootユーザーでの実行は大きなリスクとなります。

なぜnon-root実行が重要か

デフォルトでは、Dockerコンテナはrootユーザーとして実行されます。これにはいくつかのリスクがあります。

リスク 説明
コンテナエスケープ 脆弱性を悪用してホストシステムにアクセスされる可能性
ファイルシステムへの影響 マウントされたボリュームをroot権限で操作できる
権限昇格 コンテナ内での権限昇格がホストに波及する可能性
コンプライアンス違反 多くのセキュリティ基準がnon-root実行を要求

Dockerfileでのnon-rootユーザー設定

DockerfileにUSER命令を追加して、非rootユーザーでコンテナを実行します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
FROM node:22-alpine

# アプリケーションディレクトリを作成
WORKDIR /app

# 非rootユーザーを作成
RUN addgroup -g 1001 -S appgroup && \
    adduser -u 1001 -S appuser -G appgroup

# アプリケーションファイルをコピー
COPY --chown=appuser:appgroup package*.json ./
RUN npm ci --only=production

COPY --chown=appuser:appgroup . .

# 非rootユーザーに切り替え
USER appuser

EXPOSE 3000
CMD ["node", "app.js"]

ポイントは以下のとおりです。

  • addgroupadduserでグループとユーザーを作成する
  • --chownオプションでファイルの所有者を設定する
  • USER命令で実行ユーザーを切り替える
  • USER命令以降のRUN、CMD、ENTRYPOINTは指定したユーザーで実行される

既存イメージでのnon-root実行

Dockerfileを変更できない場合でも、実行時にユーザーを指定できます。

1
2
3
4
5
# ユーザーIDを指定して実行
docker run --user 1001:1001 myapp:latest

# ユーザー名を指定して実行(イメージ内にユーザーが存在する場合)
docker run --user appuser myapp:latest

読み取り専用ファイルシステム

コンテナのファイルシステムを読み取り専用にすることで、実行時の改ざんを防止できます。

1
2
3
4
5
# ファイルシステムを読み取り専用で実行
docker run --read-only myapp:latest

# 一時ファイル用のディレクトリを許可する場合
docker run --read-only --tmpfs /tmp --tmpfs /var/run myapp:latest

Docker Composeでの設定例は以下のとおりです。

1
2
3
4
5
6
7
services:
  app:
    image: myapp:latest
    read_only: true
    tmpfs:
      - /tmp
      - /var/run

Capabilitiesの制限

Linuxカーネルのcapabilitiesを制限することで、コンテナの権限をさらに絞り込めます。

1
2
3
4
5
# すべてのcapabilitiesを削除
docker run --cap-drop=ALL myapp:latest

# 必要なcapabilityのみ追加
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE myapp:latest

よく使用されるcapabilitiesは以下のとおりです。

Capability 説明
NET_BIND_SERVICE 1024未満のポートにバインド
CHOWN ファイル所有者の変更
SETUID/SETGID ユーザー/グループIDの変更
SYS_PTRACE プロセスのトレース(デバッグ用)

no-new-privilegesの設定

コンテナ内でのさらなる権限昇格を防止するには、--security-opt=no-new-privilegesを使用します。

1
docker run --security-opt=no-new-privileges myapp:latest

Docker Composeでの設定例は以下のとおりです。

1
2
3
4
5
services:
  app:
    image: myapp:latest
    security_opt:
      - no-new-privileges:true

推奨されるセキュリティ設定の組み合わせ

本番環境で推奨されるセキュリティ設定を組み合わせた例を示します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
services:
  app:
    image: myapp:latest
    user: "1001:1001"
    read_only: true
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE  # 必要な場合のみ
    tmpfs:
      - /tmp:noexec,nosuid,nodev
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 512M

セキュリティ対策のチェックリスト

Dockerイメージのセキュリティ対策をまとめたチェックリストを以下に示します。

ビルド時のチェックリスト

項目 確認内容
ベースイメージ 公式イメージまたはDocker Hardened Imagesを使用しているか
イメージタグ 特定のバージョンまたはダイジェストを指定しているか
軽量化 不要なパッケージやファイルが含まれていないか
non-rootユーザー USER命令で非rootユーザーを指定しているか
機密情報 APIキーやパスワードがイメージに含まれていないか
.dockerignore 不要なファイルがビルドコンテキストから除外されているか

スキャン時のチェックリスト

項目 確認内容
脆弱性スキャン Docker Scoutで脆弱性をスキャンしたか
Critical/High 重大な脆弱性が存在しないか、または対応済みか
ベースイメージ更新 最新のベースイメージを使用しているか
SBOMアテステーション ビルド時にSBOMを添付しているか
ポリシー評価 組織のセキュリティポリシーに準拠しているか

実行時のチェックリスト

項目 確認内容
non-root実行 rootユーザーで実行していないか
読み取り専用FS ファイルシステムを読み取り専用にしているか
Capabilities 不要なcapabilitiesを削除しているか
no-new-privileges 権限昇格を防止しているか
リソース制限 CPU/メモリの制限を設定しているか

まとめ

本記事では、Dockerイメージのセキュリティ対策として、以下の内容を解説しました。

  • セキュリティリスクの理解: Dockerイメージに潜む脆弱性や攻撃リスクを認識することの重要性
  • ベースイメージの選定: 公式イメージ、軽量イメージ、Docker Hardened Imagesの活用
  • Docker Scoutによる脆弱性スキャン: docker scoutコマンドを使ったスキャン、SBOM生成、ポリシー評価
  • Docker Content Trust: イメージ署名による発行者認証と完全性検証
  • 最小権限の原則: non-rootユーザー実行、読み取り専用ファイルシステム、capabilities制限

セキュリティ対策は一度実施すれば終わりではなく、継続的な取り組みが必要です。CI/CDパイプラインにDocker Scoutを組み込み、新たな脆弱性を早期に検出する仕組みを構築することを推奨します。

次のステップとして、Docker環境のログ管理とモニタリングでコンテナの状態監視について学ぶことで、より堅牢な本番運用環境を構築できます。

参考リンク