Docker Hardened Images トライアルを最大限に活用する (パート 1)

最初のステップ ~ セキュアで本番運用に耐えるイメージを実行する

コンテナーのベース イメージは、アプリケーション セキュリティの土台そのものです。もしその土台に脆弱性が含まれていれば、その上に構築されるあらゆるサービスが同じリスクを引き継ぐことになります。

Docker Hardened Images は、この課題を根本から解決します。不要なパッケージを取り除き、必要なパッチを適宜適用し、サプライ チェーンの証跡も備えた、継続的にメンテナンスされるセキュアな最小構成のベース イメージです。独自にハードニングしたベースを管理したり、公式イメージに含まれる脆弱性を受け入れたりする代わりに、ほぼゼロ CVE で、コンプライアンス メタデータも組み込まれた本番対応の基盤を利用できます。

30 日間のトライアルで何が得られるのか?

30 日あれば、Docker Hardened Images が自社環境に適しているかどうかを判断するには十分です。つまり、セキュリティ リスクを減らしつつ、運用の手間を増やさずに済むかを見極めるための期間です。

ただし、DHI が本番グレードのイメージを提供しているとはいえ、このトライアルの目的は、いきなり本番投入することではありません。主な目的は学習的なもので、実際の自社サービスでハードニング済みのベース イメージを試し、サプライ チェーンのセキュリティ向上効果を確認することです。

トライアル終了時には、以下のような具体的な成果を得られているはずです。

  • 移行前後の CVE (既知の脆弱性) 数の比較
  • イメージ移行にかかったエンジニアリング工数
  • チームが実際に使いたいと思えるかどうか

実際のプロジェクトで試すことほど、確実な検証方法はありません。

DHI のクイックスタート ガイドには基本的な手順がまとめられていますが、本記事ではドキュメントに載っていない、以下について解説します。

  • つまずきやすいポイント
  • 重視すべき指標
  • 結果を簡単に評価する方法

ステップ 1 ~ DHI カタログを理解する

無料トライアルを始めるには、組織のオーナーまたは編集者である必要があります。これにより、イメージをミラーリングできる独自のリポジトリが利用可能になります (これについては後ほど詳しく説明します)。

すでに Docker Hub に慣れているなら、DHI カタログも見慣れたものに感じるはずです。

最も分かりやすい違いは、ハードニング済みイメージであることを示す小さな錠前のアイコンです。しかし、これが具体的に何を意味するのでしょうか?

ハードニング済みイメージの基本的な考え方は、攻撃対象を最小化することです。実際には、必要最小限のものだけを含むイメージということです (Ubuntu や Debian のような「バッテリー同梱型」のディストリビューションとは異なります)。

イメージとしては、ディストリビューションのコアな特性 (libc、ファイルシステムの階層、パッケージ名など) は維持しつつ、攻撃対象を増やす便利機能 (パッケージ マネージャー、追加ユーティリティ、デバッグ ツールなど) を取り除いています。そのため、DHI の各イメージに表示されている「OS」の表記は、このイメージが元のディストリビューションをベースにしていることを示していますが、セキュリティ強化とパッケージの最小化が施されているということです。

開発やテストの目的で、こうした便利な Linux ユーティリティが必要になることもあります。そのような場合に登場するのがバリアント (Variants) です。

カタログには、各ベース イメージに対して複数のバリアント (標準バージョン、(dev) バージョン、(fips) バージョンなど) が用意されています。

どのバリアントを選ぶかは、セキュリティの姿勢に影響します。最終イメージにパッケージ マネージャーを含めずにアプリケーションを実行できる場合 (たとえばマルチステージ ビルドを利用する場合) は、必ず標準バリアントを選びましょう。コンテナー内のツールが少なければ少ないほど、潜在的な脆弱性も減ります。

それぞれのバリアントの意味は次の通りです。

  • 標準バリアント (例: node-base:24-debian13)
    • 最小限のランタイム イメージ
    • パッケージ マネージャーなし (apk、apt、yum は削除)
    • 本番環境対応
    • 攻撃対象を最小化
  • FIPS バリアント (例: node-base:24-debian13-fips)
    • ランタイムとビルド用の両方のバリアントが存在
    • FIPS 140 (米国政府の安全な暗号化運用基準) で検証済みの暗号モジュールを使用
    • 高度に規制された環境で必須
  • Dev バリアント (例: node-base:24-debian13-dev)
    • 追加の依存関係をインストールするためのパッケージ マネージャーを含む
    • 開発中やビルド時にパッケージを追加する場合に便利
    • 攻撃対象は大きめ (ただしハードニング済み)
    • 本番環境には推奨されない

カタログには、言語ランタイム (Python、Node、Go)、ディストリビューション (Alpine、Ubuntu、Debian)、専用ツール (nginx、Redis) など、数十種類のイメージが含まれています。

すべてを最初から評価しようとせず、まずはよく使うイメージ (Alpine、Python、Node などの一般的な出発点) を一つ選んで、最初のテストを行うのがおすすめです。

「Entitlements」と「Mirroring」が意味すること

DHI カタログから直接 docker pull することはできません。まず、イメージを組織の名前空間にミラーリングする必要があります。手順は次の通りです。

  1. トライアルでは、組織はミラーリングを通じて一定数の DHI にアクセスできます。これを Entitlements (権利) と呼びます。
  2. 組織のオーナーは、まず DHI イメージのコピーを自分の名前空間 (例: yourorg/dhi-node) に作成します。これによりミラーリングされ、リポジトリ内のイメージは自動的に更新されます。
  3. チームは Docker のカタログではなく、組織の名前空間からイメージを取得します。
  4. ミラーリングには数分かかり、利用可能なタグがすべてコピーされます。完了すると、通常のイメージと同様に組織のリポジトリに表示されます。

この方式である理由は 2 つです。

  • アクセス制御: 組織の管理者が、チームが使用できるハードニング済みイメージを管理できる
  • 可用性: サブスクリプションが変わっても、ミラーされたイメージは利用可能

初めて「このイメージをリポジトリにミラーする」と聞くと面倒に感じるかもしれません。しかし、一度ベース イメージごとに設定すれば (タグごとではない)、納得できます。たとえば node-base を一度ミラーすれば、現在および将来のすべての Node バージョンにアクセスできます。

ハードニング済みイメージのミラーリングが完了したら、実際のプロジェクトでテストする段階です。目的は、リスクの低いうちに、早い段階で問題点を見つけることです。

ステップ 2 ~ 最初の実際の移行テスト

次の条件を満たすプロジェクトを選びます。

  • 何か問題が起きても迅速にデバッグできるほどシンプル(可動部分が少ない)
  • 実際のワークロードをある程度反映している
  • 自社の技術スタックをよく反映している

ドロップインで置き換え

Dockerfile を開き、FROM 命令を探します。移行は非常に簡単です。

# 変更前
FROM node:22-bookworm-slim
# 変更後
FROM <your-org-namespace>/dhi-node:22-debian13-fips

組織の名前空間を置き換え、適切なタグを選びます。たとえば node:22 のような汎用タグを使っていた場合は、ハードニング済みカタログの特定バージョン (例:22-debian13-fips) に切り替えます。特定バージョンを固定することはベストプラクティスであり、ハードニング済みイメージはそれを明示化してくれます。

他の言語ランタイムでも同様です。

# Python の例
FROM python:3.12-slim
# 変更後
FROM <your-org-namespace>/dhi-python-base:3.12-bookworm

# Node の例
FROM node:20-alpine
# 変更後
FROM <your-org-namespace>/dhi-node-base:20.18-alpine3.20

新しいベースでイメージをビルド

docker build . -t my-service-hardened

ビルド出力を確認してください。Dockerfile が特定のユーティリティ (wget、curl、パッケージ マネージャーなど) を前提としている場合、ビルドは失敗することがあります。これは想定通りです。ハードニング済みのベースは、攻撃対象を減らすために不要なツールを削除しています。

よくあるビルド失敗と対応方法は以下の通りです。

  • パッケージ マネージャーがない (apt, yum)
    • Dockerfile 内でパッケージをインストールする場合は、(dev) バリアントを使用し、マルチステージ ビルドを検討します。ビルド用ステージで依存関係をインストールし、その成果物を最小ランタイム ステージにコピーします。
  • ユーティリティがない (wget, curl, bash)
    • ネットワーク ツールはデバッグ バリアント以外では削除されています。
    • 対策: 必要なツールをビルダー段階で明示的にインストールするか、本当にランタイムで必要か確認します。
  • デフォルト ユーザーが異なる
    • ハードニング済みイメージは非 root で実行される場合があります。
    • アプリが特定ディレクトリに書き込む場合は、権限を調整するか、USER 指令を適切に使用します。

この記事の例である Node.js のテストでは、ビルドは変更なしで成功しました。ハードニング済みの Node ベースにはランタイムに必要なものがすべて含まれており、削除されたのはアプリケーションが使用しないシステム ユーティリティだけでした。

実行確認

ビルドが成功したからといって、ランタイムでの動作が保証されるわけではありません。コンテナーを起動して、正しく動作するか確認します。

docker run --rm -p 3000:3000 my-service-hardened
  • エラーなく起動するか?
  • API エンドポイントが正しく応答するか?
  • ログは正しく出力されるか?
  • データベースや外部サービスに接続できるか?

ステップ 3 ~ 変更点の比較

測定に進む前に、オリジナル バージョンとハードニング バージョンを並行してビルドします。

# メイン ブランチに切り替え
git checkout main
# オリジナル バージョンをビルド
docker build . -t my-service-original

# ハードニング済みベースのテスト ブランチに切り替え
git checkout dhi-test
# ハードニング バージョンをビルド
docker build . -t my-service-hardened

これで、公式ベースとハードニング ベースの 2 つのイメージを比較できます。

Docker Scout による比較

Docker Scout を使うと、イメージ間の脆弱性、パッケージ差異、サイズ変化をレポートできます。組織を Scout に登録していない場合は、まず登録が必要です (比較機能は無料です)。

Node ベースの比較例:

docker scout compare --to <your-org-namespace>/dhi-node:24.11-debian13-fips node:24-bookworm-slim

Scout は詳細な内訳を出力します。公式 Node.js イメージとハードニング済みイメージを比較した結果は以下の通りです。

1. 脆弱性の削減

CVE 数 (重要度別):

公式 Nodeハードニング DHI
Critical (重大)00
High (高)00
Medium (中)10 ← 削除
Low (低)240 ← 削除
合計250

ハードニング済みイメージでは、すべての脆弱性が除去されました。公式イメージは Critical/High がゼロでしたが、Medium 1 件、Low 24 件が残っていました。これらはすべてハードニング バージョンで除去されています。

Medium や Low の脆弱性も、SOC2 や ISO 27001 などのコンプライアンスにおいて重要です。全てゼロにすることで、監査が大幅に簡略化されます。

2. パッケージの削減

パッケージ数の比較:

公式 Nodeハードニング DHI
総パッケージ数32132
削減数289 (90%)

削除されたパッケージ例:

  • apt (パッケージ マネージャー)
  • gcc-12 (コンパイラ一式)
  • perl (スクリプト言語)
  • bash (最小シェルに置換)
  • dpkg-dev (Debian パッケージ ツール)
  • gnupg2, gzip, bzip2 (圧縮/暗号化ユーティリティ)
  • その他ライブラリやシステム ユーティリティ多数

Node.js アプリがランタイムで使用しないツールを削除することで、攻撃対象を大幅に減らせます。90% の削減は、潜在的な攻撃対象を 90% 減らすことを意味します。

3. イメージ サイズの差

公式 Nodeハードニング DHI
イメージサイズ82 MB48 MB
削減量34 MB (41.5%)

ハードニング済みイメージは 41.5% 小さくなりました。単一のサービスではわずかに感じるかもしれませんが、数十〜数百のマイクロサービスに適用すると、イメージのプル速度向上やストレージコストの削減、ネットワーク転送量の削減などのメリットが大きくなります。

4. SBOM の抽出と確認

ハードニング済みイメージには SBOM (Software Bill of Materials) が組み込まれており、脆弱性管理やコンプライアンス対応に便利です。

docker scout sbom <your-org-namespace>/dhi-node:24.11-debian13-fips --format list

出力例:

名前バージョンタイプ
base-files13.8+deb13u1deb
ca-certificates20250419deb
glibc2.41-12deb
nodejs24.11.0dhi
openssl3.5.4dhi
openssl-provider-fips3.1.2dhi
  • 「タイプ」列の意味:
    • deb: Debian システム パッケージ
    • dhi: Docker Hardened Images 独自パッケージ (FIPS 認定 OpenSSL など)
    • docker: Docker 管理のランタイム コンポーネント

SBOM は、名前、バージョン、ライセンス、パッケージ URL を含み、脆弱性追跡やコンプライアンス レポートに必要な情報をすべて提供します。

SPDX や CycloneDX 形式で出力し、脆弱性追跡ツールに取り込むことも可能です:

# SPDX 形式
docker scout sbom <your-org>/dhi-node:24.11-debian13-fips \
  --format spdx \
  --output node-sbom.json

# CycloneDX 形式
docker scout sbom <your-org>/dhi-node:24.11-debian13-fips \
  --format cyclonedx \
  --output node-sbom-cyclonedx.json

さらにハードニング済みイメージには、SLSA プロビナンス、FIPS コンプライアンス、STIG スキャン、脆弱性スキャンなど、17 種類の証跡が含まれています。これらの確認方法や活用法は、ブログ シリーズのパート 2 で詳しく解説します。

DHI を信頼するだけでなく、適切に検証する

ここまでで
✅ 脆弱性を 100% 排除 (25 CVE → 0)
✅ 攻撃対象を 90% 減少 (321 パッケージ → 32)
✅ イメージ サイズを 41.5% 縮小 (82 MB → 48 MB)
✅ SBOM を抽出してコンプライアンス追跡可能

数字上の結果は良好に見えますが、実際に検証して初めて本番環境での信頼性が確認できます。

パート 2 では、以下を含む独立した検証方法を紹介します。

  • すべての証跡の暗号署名の確認
  • 公開 GitHub リポジトリに紐づくビルド プロビナンスの確認
  • FIPS、STIG、CIS コンプライアンス証跡の詳細な検証
  • SBOM に基づく脆弱性分析 (悪用可能性のコンテキスト付き)

エクセルソフトは Docker の Preferred Reseller として、Docker Desktop を販売しています。Docker 製品のライセンスや機能に関するご質問、製品デモのご要望を承っています。お問い合わせはこちらから。

*本記事は、Docker 社が提供している以下の記事から抜粋・転載したものです。

Docker強化イメージの活用 トライアル – パート 1

Docker の最新情報をお届けするエクセルソフトのメールニュース登録はこちら

タイトルとURLをコピーしました