Docker強化イメージのカスタマイズ
パート1とパート2では、基準を設定しました。サービスを Docker Hardened Image(DHI)に移行し、脆弱性数がゼロに減少するのを目撃し、DHIを準拠の基盤にしている暗号署名と SLSAの出所 を検証しました。
しかし、どんなにベースイメージが安全でも、アプリケーションを動かせなければ意味がありません。ここで、DHIトライアル中にエンジニアが最もよく尋ねる質問に移ります。も しカスタムイメージが必要になったらどうしますか?
硬化画像は設計上最小限に抑えられています。パッケージマネージャー(apt、apk、yum)、ユーティリティ(wget、curl)、さらにはbashやshのようなシェルも欠けています。これはセキュリティ機能です。悪意のある人物がコンテナに侵入した場合、空のツールボックスを見つけます。
しかし、開発者はセットアップ時にこれらのツールを必要とすることが多いです。監視エージェントのインストール、カスタムのCA証明書、または特定のライブラリをインストールする必要があるかもしれません。
シリーズの最終回では、DHIのカスタマイズ戦略として、Docker Hub UI(プラットフォームチームが「ゴールデンイメージ」を作成するためのもの)とマルチステージビルドパターン(アプリケーション開発開発者向け)について取り上げます。
オプション 1:ゴールデンイメージ(Docker Hub UI)
もしあなたがプラットフォームエンジニアやDevOpsエンジニアであれば、社内チームのために「祝福された」ベースイメージを提供することが目標である可能性が高いです。例えば、 常に 企業のルートCA証明書とセキュリティログエージェントを含む標準Node.jsイメージが欲しいかもしれません。Docker HubのUI がこの件の優先ルートです。Hub UIを使う最も強力な理由はメンテナンスの自動化です。
致命的な機能:自動再構築
UIを通じてイメージをカスタマイズすると、Dockerはカスタムレイヤーとハード化されたベースの関係を認識します。もしDockerが基盤となるDHIベースイメージのパッチ(例:glibcやopensslの修正)をリリースすると、Docker Hubは自動的にカスタムイメージを再構築します。
CIパイプラインをトリガーする必要はありません。CVEフィードを監視する必要はありません。プラットフォームはパッチ適用と再構築を担当し、「ゴールデンイメージ」が最新のセキュリティ基準に準拠していることを保証します。
仕組み
このトライアルのために組織を設定しているので、Docker Hubで直接探索できます。まず、組織ダッシュボードの リポジトリ に移動します。カスタマイズしたい画像(例:dhi-node)を見つけ、カスタマイズタブから「カスタマイズを作成」アクションをクリックします。これにより、以下のカスタマイズワークフローが開始されます:
「Add packages」セクションでは、ディストリビューションのリポジトリから直接OSパッケージを検索し選択できます。例えば、ここではデバッグのためにイメージにbashを追加しています。また、「OCIアーティファクト」を追加して、証明書やエージェントなどのカスタムファイルを注入することもできます。
最後に、ランタイム設定(ユーザー、環境変数)を設定し、ビルドを見直します。Docker Hubは設定を検証し、ビルドをキューに入れます。完成すると、このイメージは組織のプライベートレジストリで利用可能になり、ベースDHIイメージが更新されるたびに自動的に再構築されます。
このオプションは、組織全体で使用される標準化された「ゴールデン」ベース画像の作成に最適です。主な利点は、Docker Hubによる自動再構築によるメンテナンス 不要のセキュリティパッチ適用 です。しかし、個々の開発チームによる迅速かつアプリケーション固有の反復作業には柔軟性が劣ります。
オプション 2:マルチステージビルド
もしあなたが開発者なら、おそらくコードと一緒に環境を定義するDockerfileで管理しているでしょう。柔軟性が必要で、それが自分のマシンでローカルに動作することが重要です。
DHIイメージにはapt-getやcurlがないため、Dockerファイル内でapt-getのインストールmy-libを実行することはできません。失敗するだろう。
代わりに、マルチステージのビルドパターンを用います。コンセプトはシンプルです:
- ステージ 1 (ビルダー):標準的な「ファット」イメージ(debian:bookworm-slimのような)を使って依存関係をダウンロード、コンパイル、準備してください。
- ステージ 2 (ランタイム):得られたアーティファクト のみ を純粋なDHIベースにコピーします。
これにより、最終画像は最小限でroot化されず、安全に保たれつつ、必要なものをインストールできます。
ハンズオンチュートリアル:モニタリングエージェントの追加
地元で試してみよう。一般的な実世界シナリオをシミュレートします。DatadogのAPMライブラリ(dd-trace)をNode.js DHIイメージにグローバルに追加することです。
1。セットアップ
このテスト用に新しいディレクトリを作成し、シンプルなserver.jsファイルを追加します。このスクリプトはdd-traceライブラリを読み込み、インストールの検証を試みます。
アプリ/server.js
// Simple Express server to demonstrate DHI customization
console.log('Node.js version:', process.version);
try {
require('dd-trace');
console.log('dd-trace module loaded successfully!');
} catch (e) {
console.error('Failed to load dd-trace:', e.message);
process.exit(1);
}
console.log('Running as UID:', process.getuid(), 'GID:', process.getgid());
console.log('DHI customization test successful!');
2。ハードンドdockerfile
次に、Dockerファイルを作成します。標準のDebianイメージを使ってライブラリをインストールし、それをDHIのNode.jsイメージにコピーします。このテスト用に新しいディレクトリを作成し、シンプルなserver.jsファイルを追加します。このスクリプトはdd-traceライブラリを読み込み、インストールの検証を試みます。
# Stage 1: Builder - a standard Debian Slim image that has apt, curl, and full shell access.
FROM debian:bookworm-slim AS builder
# Install Node.js (matching our target version) and tools
RUN apt-get update && \
apt-get install -y curl && \
curl -fsSL https://deb.nodesource.com/setup_24.x | bash - && \
apt-get install -y nodejs
# Install Datadog APM agent globally (we force the install prefix to /usr/local so we know exactly where files go)
RUN npm config set prefix /usr/local && \
npm install -g dd-trace@5.0.0
# Stage 2: Runtime - we switch to the Docker Hardened Image.
FROM <your-org-namespace>/dhi-node:24.11-debian13-fips
# Copy only the required library from the builder stage
COPY --from=builder /usr/local/lib/node_modules/dd-trace /usr/local/lib/node_modules/dd-trace
# Environment Configuration
# DHI images are strict. We must explicitly tell Node where to find global modules.
ENV NODE_PATH=/usr/local/lib/node_modules
# Copy application code
COPY app/ /app/
WORKDIR /app
# DHI Best Practice: Use the exec form (["node", ...])
# because there is no shell to process strings.
CMD ["node", "server.js"]
3。ビルド・アンド・ラン
カスタムイメージをビルドします。
docker build -t dhi-monitoring-test .
さあ、実行してください。成功すれば、コンテナは起動し、ライブラリを見つけてきれいに退出します。
docker run --rm dhi-monitoring-test
アウトプット:
Node.js version: v24.11.0
dd-trace module loaded successfully!
Running as UID: 1000 GID: 1000
DHI customization test successful!
成功!カスタムグローバルライブラリを持つ動作するアプリケーションがあり、ハード化された非rootベース上で動作しています。
セキュリティチェック
私たちは画像のカスタマイズに成功しました。しかし、そのセキュリティを損なってしまったのでしょうか?
これがDHIを運用する上で最も重要な教訓です。強化されたベースイメージはOSを守りますが、追加したコードからは守りません。新しいイメージを Docker Scoutで検証してみましょう。
docker scout cves dhi-monitoring-test --only-severity critical,high
サンプル出力:
✗ Detected 1 vulnerable package with 1 vulnerability
...
0C 1H 0M 0L lodash.pick 4.4.0
pkg:npm/lodash.pick@4.4.0
✗ HIGH CVE-2020-8203 [Improperly Controlled Modification of Object Prototype Attributes]
この結果は正確で重要です。ベースイメージ(OS、OpenSSL、Node.jsランタイム)は依然として安全です。しかし、先ほどインストールしたdd-traceライブラリは、高重大度の脆弱性を含む依存関係(lodash.pick)を取り込んでしまいました。
これはあなたの認証パイプラインが機能していることの証明です。
もし カスタム 画像をスキャンしていなければ、「硬化画像」を使っているので安全だと思ったかもしれません。最終的なアーティファクトにDocker Scoutを使ったことで 、カスタマイズによって 生じたサプライチェーンの脆弱性を発見しました。
クリーンベースと比べてどれだけ「膨張」を加えたか見てみましょう。
docker scout compare --to <your-org-namespace>/dhi-node:24.11-debian13-fips dhi-monitoring-test
追加されたサイズはdd-traceライブラリ(~5MB)とアプリケーションコードのみです。私たちは誤ってapt、curl、ビルドキャッシュをビルダー段階から引き継いだわけではありません。攻撃対象は最小限に抑えられています。
出所についての注意:誰が何に署名するのか?
パート 2では、Docker Hardened ImagesのSLSAの出所と暗号署名を検証しました。これは信頼できるサプライチェーンを築くために非常に重要です。画像をカスタマイズする際には、署名を「所有する」人が誰かという問題が重要になります。
- Docker Hub UIのカスタマイズ:Docker Hub UIを通じてイメージをカスタマイズすると、Docker自体がカスタムイメージのビルダーとして機能します。つまり、カスタマイズされた画像はDockerのビルドインフラストラクチャから直接署名済みの出所や認証を受け継承します。ベースのDHIにセキュリティパッチが届くと、Dockerは自動的にカスタムイメージを再構築・再署名し、継続的な信頼を保証します。これはプラットフォームチームにとって「ゴールデンイメージ」を作成する大きな利点です。
- ローカルDockerfile:マルチステージのDockerfileを使ってローカルでカスタムイメージを構築する場合(チュートリアルで行ったように)、 あなたが ビルダーです。dockerビルドコマンドは 新しい イメージと 新しい ダイジェストを生成します。その結果、Dockerの元のDHI署名は最終的なカスタムイメージには適用されません(ビットが変更されており、あなたが新しいビルダーだからです)。
しかし、信頼の連鎖は完全に断たれているわけではありません。 - ベースレイヤー:カスタムイメージ内の基盤となるDHIレイヤーは、元のDocker認証を保持しています。
- カスタムレイヤー:あなたの組織が新しいレイヤーの「ビルダー」となります。
マルチステージビルドを使った本番展開では、カスタムイメージに署名するために Cosign や Docker Content Trust をCI/CDパイプラインに統合してください。これによりループが閉じられ、「MyOrgで作成された画像のみを実行し、検証済みのDHI画像を基に内部署名を持つ」といったポリシーを適用できます。
ROIの測定:チームへの質問
Docker Hardened Imagesのトライアルを終える際には、組織にとってその価値を定量化することが非常に重要です。以下の質問を使って、移行やカスタマイズの具体的な成果を振り返ってください:
- 脆弱性削減:DHIはCVE数にどれほど影響を与えましたか?移行したサービスの「ビフォー・アフター」脆弱性レポートを比較してください。推定されるセキュリティリスク削減額はどのくらいですか?
- エンジニアリングの努力: 画像をDHIに移行するのに実際に必要なエンジニアリング作業は何だったのでしょうか?従来のベースイメージ管理と比べて、パッチ適用、脆弱性トリアージ、セキュリティレビューにかかる時間の節約を考えてみてください。
- ワークフロー:DHIはチームの既存の開発およびCI/CDワークフローにどれほどうまく統合されていますか?開発者はカスタマイズパターン(ゴールデンイメージ/ビルダーパターン)を実用的かつ効率的だと感じていますか?あなたのチームはこれを長期的に採用する可能性はありますか?
コンプライアンスと監査:DHIはSLSAの出所やFIPS準拠により、コンプライアンス報告や監査プロセスを簡素化しましたか?規制負担にどのような影響がありますか?
結論
最後まで読んでくれてありがとうございます!この 3部構成のブログシリーズを通じて、単純な試用から完全な運用ワークフローへと移行しました。
- 移行:標準的なベースイメージをDHIに置き換えると、即座に脆弱性が減少しました。
- 検証:署名、FIPS準拠、SBOMを独立して検証しました。
- カスタマイズ:Hub UI(自動パッチ適用)やマルチステージビルドを使ってDHIを拡張し、自分の依存関係による新たな脆弱性をチェックしながら学びました。
ここでの教訓は、Docker Hardened Imagesの「ハードンド」は魔法の盾ではなく、クリーンな基盤であるということです。それを基盤に構築することで、 チームは数千の 上流の脆弱性と終わりなき戦いを繰り広げるのではなく、アプリケーションコードのセキュリティに時間を割くことができます。