最初のステップ ~ セキュアで本番運用に耐えるイメージを実行する
コンテナーのベース イメージは、アプリケーション セキュリティの土台そのものです。もしその土台に脆弱性が含まれていれば、その上に構築されるあらゆるサービスが同じリスクを引き継ぐことになります。
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 することはできません。まず、イメージを組織の名前空間にミラーリングする必要があります。手順は次の通りです。
- トライアルでは、組織はミラーリングを通じて一定数の DHI にアクセスできます。これを Entitlements (権利) と呼びます。
- 組織のオーナーは、まず DHI イメージのコピーを自分の名前空間 (例: yourorg/dhi-node) に作成します。これによりミラーリングされ、リポジトリ内のイメージは自動的に更新されます。
- チームは Docker のカタログではなく、組織の名前空間からイメージを取得します。
- ミラーリングには数分かかり、利用可能なタグがすべてコピーされます。完了すると、通常のイメージと同様に組織のリポジトリに表示されます。
この方式である理由は 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 (重大) | 0 | 0 |
| High (高) | 0 | 0 |
| Medium (中) | 1 | 0 ← 削除 |
| Low (低) | 24 | 0 ← 削除 |
| 合計 | 25 | 0 |
ハードニング済みイメージでは、すべての脆弱性が除去されました。公式イメージは Critical/High がゼロでしたが、Medium 1 件、Low 24 件が残っていました。これらはすべてハードニング バージョンで除去されています。
Medium や Low の脆弱性も、SOC2 や ISO 27001 などのコンプライアンスにおいて重要です。全てゼロにすることで、監査が大幅に簡略化されます。
2. パッケージの削減
パッケージ数の比較:
| 公式 Node | ハードニング DHI | |
|---|---|---|
| 総パッケージ数 | 321 | 32 |
| 削減数 | — | 289 (90%) |
削除されたパッケージ例:
- apt (パッケージ マネージャー)
- gcc-12 (コンパイラ一式)
- perl (スクリプト言語)
- bash (最小シェルに置換)
- dpkg-dev (Debian パッケージ ツール)
- gnupg2, gzip, bzip2 (圧縮/暗号化ユーティリティ)
- その他ライブラリやシステム ユーティリティ多数
Node.js アプリがランタイムで使用しないツールを削除することで、攻撃対象を大幅に減らせます。90% の削減は、潜在的な攻撃対象を 90% 減らすことを意味します。
3. イメージ サイズの差
| 公式 Node | ハードニング DHI | |
|---|---|---|
| イメージサイズ | 82 MB | 48 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-files | 13.8+deb13u1 | deb |
| ca-certificates | 20250419 | deb |
| glibc | 2.41-12 | deb |
| nodejs | 24.11.0 | dhi |
| openssl | 3.5.4 | dhi |
| openssl-provider-fips | 3.1.2 | dhi |
- 「タイプ」列の意味:
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 の最新情報をお届けするエクセルソフトのメールニュース登録はこちら。


