Docker上でHarborを構築:Trivyとイメージ署名でセキュアなプライベートコンテナレジストリをHomeLabにセルフホストする

HomeLab tutorial - IT technology blog
HomeLab tutorial - IT technology blog

現実の課題:無料レジストリの制限と未検証コンテナの限界

数か月前、私のHomeLab環境でのビルドが突如として完全に停止しました。ローカルでマイクロサービスをビルドする3台のGitLab Runner、テストイメージをプルする4ノードのk3sクラスタ、そしてメンテナンスタスクを実行する複数のcronジョブを動かしていたところ、すべてのパイプラインが突然429 Too Many Requestsエラーで失敗したのです。Docker Hubが匿名ユーザーに対して適用している「6時間あたり100回」という厳格なプル制限が、外部IPに引っかかってしまったことが原因でした。

しかし、プルの上限以上に危険な問題が私の環境に潜んでいました。それが「盲目的な信頼」です。ベースイメージのテストや実験的なコンテナのプルを行う際、脆弱性の自動チェックを一切行っていませんでした。リモートコード実行などの致命的な脆弱性を抱えたベースイメージが、検知されないまま何カ月もノード上に居座り続ける可能性があったのです。さらに悪いことに、ワーカーノードはタグが一致するバイナリであれば、正規のビルドパイプラインで作成されたものかという暗号学的な検証もなしにそのままプルして実行していました。

原因分析:Docker Hubや最小限のレジストリでは不十分な理由

多くのHomeLabエンジニアは、パブリックなSaaSレジストリに依存するか、最小構成の標準コンテナであるregistry:2を立ち上げるかのどちらかからスタートします。

しかし、ラボの規模が数台のマシンを超えて成長すると、どちらのモデルもすぐに破綻します。

  • 帯域の浪費とアップストリームのレイテンシ:家庭用の50Mbpsの上り回線を経由して1.2GBのマイクロサービスコンテナを外部レジストリにプッシュするのは苦痛です。さらに、同じローカルのギガビットスイッチに接続されたサーバーへ、そのイメージをわざわざ外部からプルし直すのは全く合理的ではありません。
  • 自動セキュリティチェックの欠如:標準のregistry:2コンテナは、実質的にディスク上のフォルダを公開するHTTP APIにすぎません。脆弱性検知エンジンもCVEデータベースも備えておらず、イメージに危険な脆弱性が含まれていてもデプロイを阻止する仕組みがありません。
  • 出所証明とポリシー制御の不在:最小限のレジストリには、きめ細かなロールベースアクセス制御(RBAC)、タグのイミュータビリティ(不変性)、デジタル署名検証が備わっていません。ローカルネットワーク内の誰もが、未テストのコードや壊れたコードでlatestタグを上書きできてしまいます。

ソリューションの比較:HomeLabに最適なレジストリの選定

HomeLab専用のレジストリプラットフォームを選定するにあたり、主要な3つの候補を比較検討しました。

ソリューション リソース消費量 セキュリティ&脆弱性スキャン イメージ署名対応 最適な用途
Docker Registry v2 最小限(RAM約50〜100MB) なし(外部CLIツールが必要) なし セキュリティ要件のない一時的なローカル検証環境。
Nexus OSS / JFrog Artifactory 大(RAM 4GB以上、JVMベース) 有償版のみ(XrayやPro機能) 複雑なプラグイン設定が必要 複数のアーティファクトを統合管理するエンタープライズ環境(Maven、npm、PyPI、Dockerなど)。
Project Harbor 中程度(RAM約2〜3GB) Trivyスキャナの統合機能を標準搭載 CosignおよびNotaryのネイティブサポート HomeLab、GitOpsパイプライン、コンテナのガバナンス管理。

Docker Registry v2は軽量ですが、コンテナセキュリティが完全に度外視されています。NexusやArtifactoryはシステムリソースを大量に消費し、自動脆弱性スキャナ機能は高額な商用ライセンスに限定されています。Harborはその点、理想的なバランスを実現しています。CNCFを卒業(Graduated)したオープンソースプロジェクトであり、高額なエンタープライズライセンスを必要とせず、標準でTrivyスキャン、タグのイミュータビリティ、ロボットアカウント、イメージ検証機能を提供してくれます。

最適なアプローチ:TrivyとCosignを統合したHarborのDockerデプロイ手順

以下は、Ubuntu 24.04 LTSホスト上でDocker Composeを使用し、TrivyによるセキュリティスキャンとCosignによる署名機能を完備したHarborを運用するための、実績のある構成手順です。

ステップ 1:ホストの前提条件

最低でも2 vCPU、4GBのRAM、50GBの空きストレージを持つ仮想マシンまたはベアメタルホストを用意します。Docker EngineおよびComposeプラグインのインストール状況を確認します。

# DockerとComposeのインストール状況を確認
docker --version
docker compose version

# Harbor用の作業ディレクトリを作成
sudo mkdir -p /opt/harbor
cd /opt/harbor

ステップ 2:証明書の生成とローカルトラストストアの設定

最新のコンテナエンジンは、非セキュアなHTTPレジストリとの通信をデフォルトで拒否します。Step-CAやpfSenseなどの内部CAを運用している場合は、core.harbor.local用の証明書を発行してください。そうでない場合は、OpenSSLを使用して専用のローカル認証局(CA)とサーバー証明書を生成します。

# ルートCAの秘密鍵と証明書を生成(有効期限10年)
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -sha512 -days 3650 \
  -subj "/C=US/ST=Lab/L=Home/O=HomeLab/CN=HomeLab-RootCA" \
  -key ca.key -out ca.crt

# サーバー秘密鍵と証明書署名要求(CSR)を生成
openssl genrsa -out harbor.local.key 4096
openssl req -sha512 -new \
  -subj "/C=US/ST=Lab/L=Home/O=HomeLab/CN=core.harbor.local" \
  -key harbor.local.key -out harbor.local.csr

# Subject Alternative Names(SAN)を定義
cat > v3.ext <<EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1 = core.harbor.local
DNS.2 = harbor.local
EOF

# ローカルCAでサーバー証明書に署名
openssl x509 -req -sha512 -days 365 \
  -extfile v3.ext \
  -CA ca.crt -CAkey ca.key -CAcreateserial \
  -in harbor.local.csr -out harbor.local.crt

# Harborの証明書ディレクトリに証明書を配置
sudo mkdir -p /data/cert
sudo cp harbor.local.crt /data/cert/
sudo cp harbor.local.key /data/cert/

ステップ 3:Harborのダウンロードと設定

デプロイ中のネットワーク遅延を防ぐため、GitHubから最新のオフラインインストーラーパッケージをダウンロードします。

cd /opt/harbor
wget https://github.com/goharbor/harbor/releases/download/v2.10.0/harbor-offline-installer-v2.10.0.tgz
tar xvf harbor-offline-installer-v2.10.0.tgz
cp harbor.yml.tmpl harbor.yml

harbor.ymlを開き、ホスト名、証明書のパス、管理者認証情報を調整します。

# harbor.yml 基本設定
hostname: core.harbor.local

# HTTPトラフィックのリダイレクト、または内部プロキシ用
http:
  port: 80

https:
  port: 443
  certificate: /data/cert/harbor.local.crt
  private_key: /data/cert/harbor.local.key

# 強力な管理者パスワードを設定
harbor_admin_password: ChangeThisStrongSecret2026!

# データ永続化ディレクトリ(イメージ、データベース、チャートリポジトリ)
data_volume: /data/harbor

ステップ 4:Trivyスキャナを有効にしてインストーラーを実行

--with-trivyフラグを指定してHarborを起動し、Trivyを有効化します。インストーラーによってdocker-compose.ymlが生成され、連携する9つのサービスが一括で立ち上がります。

sudo ./install.sh --with-trivy

# すべてのコンテナが正常に稼働していることを確認
docker compose ps

ステップ 5:DockerクライアントとビルドノードでルートCAを信頼

ローカルルートCAが信頼されるまで、DockerやCosignなどのツールは接続を拒否します。Harborと通信を行うすべてのワークステーション、CIランナー、またはクライアントサーバーで以下のコマンドを実行してください。

# 1. Dockerデーモンの信頼パスを設定
sudo mkdir -p /etc/docker/certs.d/core.harbor.local
sudo cp /opt/harbor/ca.crt /etc/docker/certs.d/core.harbor.local/ca.crt

# 2. OSのルートストアにCAを追加してCosignやcurlから信頼させる
sudo cp /opt/harbor/ca.crt /usr/local/share/ca-certificates/homelab-ca.crt
sudo update-ca-certificates

# 3. Dockerデーモンを再起動して変更を適用
sudo systemctl restart docker

また、内部DNS(Pi-holeやAdGuard Homeなど)または/etc/hostsへのエントリ追加により、クライアント側でcore.harbor.localがHarborホストのIPアドレスに正しく名前解決できることを確認してください。

ステップ 6:Web UIで脆弱性ポリシーを自動化

  1. 管理(Administration)> 診断サービス(Interrogation Services)を開き、Trivyがアクティブであることを確認します。cronスケジュール(例:0 0 * * *)を設定し、脆弱性データベースが毎晩自動更新されるようにします。
  2. プロジェクト(Projects)を選択し、新規プロジェクト(New Project)をクリックしてプロジェクト名をproductionに設定し、アクセスレベルがプライベートになっていることを確認します。
  3. プロジェクトの設定タブを開きます。プッシュ時にイメージを自動スキャン(Automatically scan images on push)にチェックを入れます。
  4. 脆弱性のあるイメージの実行を防止(Prevent vulnerable images from running)を有効にし、HighまたはCriticalを選択します。これにより、パッチが適用されていない高重要度のCVEを含むイメージの下流へのプルが自動的にブロックされます。

ステップ 7:Cosignでコンテナイメージに署名

脆弱性スキャンは既知の欠陥を検知しますが、暗号署名はイメージの出所を保証し、改ざんを防止します。ワークステーションまたはCIランナーにCosignをインストールし、Harbor内のイメージに直接署名を行います。

# 署名用キーペアを生成(cosign.keyの安全なパスワードを設定)
cosign generate-key-pair

# Harborレジストリに対してDockerで認証
docker login core.harbor.local -u admin

# サンプルコンテナのタグ付けとプッシュ
docker tag alpine:latest core.harbor.local/production/my-app:1.0.0
docker push core.harbor.local/production/my-app:1.0.0

# Harbor内のイメージダイジェストに直接署名
cosign sign --key cosign.key core.harbor.local/production/my-app:1.0.0

# イメージの署名を検証
cosign verify --key cosign.pub core.harbor.local/production/my-app:1.0.0

Harbor UIのproductionプロジェクトを確認します。タグの横に、詳細なTrivy CVEの内訳と、Cosignによる署名検証済みを示す緑色のチェックマークという2つのバッジが表示されます。

独自のHarborレジストリを運用することで、HomeLab環境を外部のレート制限から解放できます。ローカルネットワーク経由でのプル時間は数秒に短縮され、何よりエンタープライズ規模のクラスタと同等のスキャンおよび署名によるセキュリティガードレールをHomeLabに導入することが可能になります。

Share: