Docker レジストリで使用されている SSL 証明書の検証方法

DockerBeginner
オンラインで実践に進む

はじめに

Docker 環境のセキュリティを確保することは非常に重要であり、Docker レジストリで使用される SSL 証明書の検証は、このセキュリティを維持するための不可欠なステップです。このチュートリアルでは、Docker レジストリの SSL 証明書を検証するプロセスを案内し、安全な通信を確保し、SSL 証明書に関連する問題をトラブルシューティングするのに役立ちます。

この実験(Lab)の終わりには、Docker がどのように SSL 証明書を使用しているかを理解し、Docker レジストリで使用されている証明書を検査および検証できるようになり、一般的な証明書の問題を処理する方法を知ることができます。

Docker レジストリの SSL 証明書の理解

Docker レジストリは、Docker イメージが保存および配布されるリポジトリです。これらのレジストリは、Docker クライアントとレジストリサーバー間の通信を保護するために SSL/TLS 証明書を使用します。これらの証明書が何であるか、そしてなぜ重要なのかを理解しましょう。

SSL/TLS 証明書とは?

SSL/TLS 証明書は、以下のことを行うデジタルドキュメントです。

  • クライアントとサーバー間の安全な接続を確立する
  • クライアントとサーバー間で送信されるデータを暗号化する
  • サーバーの身元を確認する

Docker レジストリに接続すると、Docker クライアントはレジストリの SSL 証明書をチェックして、接続が安全であり、正当なレジストリに接続していることを確認します。

OpenSSL を使用した証明書情報の検査

まず、SSL 証明書を扱うための強力なツールである OpenSSL を使用して、証明書情報を確認する方法を見てみましょう。

最初に、実験(Lab)作業用のディレクトリを作成しましょう。

mkdir -p ~/project/ssl-lab
cd ~/project/ssl-lab

次に、一般的な Docker レジストリである Docker Hub の SSL 証明書を確認してみましょう。

openssl s_client -connect hub.docker.com:443 -showcerts < /dev/null

このコマンドは Docker Hub に接続し、その SSL 証明書に関する情報を表示します。出力には、次のような多くの情報が表示されます。

  • 証明書チェーン
  • 発行者情報
  • 証明書の有効期限
  • 公開鍵

より読みやすい形式で、証明書情報だけを抽出してみましょう。

echo | openssl s_client -connect hub.docker.com:443 2> /dev/null | openssl x509 -text -noout | head -20

このコマンドは、証明書の詳細の最初の 20 行を表示します。これには、次のような重要な情報が含まれます。

  • バージョン
  • シリアル番号
  • 署名アルゴリズム
  • 発行者 (認証局)
  • 有効期間
  • 件名 (証明書の所有者)

この情報を理解することが、証明書の信頼性を検証するための最初のステップです。

Docker CLI を使用したレジストリ SSL 証明書の検証

SSL 証明書の基本を理解したところで、Docker CLI を使用して Docker レジストリの証明書を具体的に検証する方法を学びましょう。

docker info を使用したレジストリ設定の確認

Docker CLI は、証明書設定を含むレジストリ設定を検査するためのツールを提供します。

Docker が認識している現在のレジストリ設定を確認してみましょう。

docker info --format '{{json .RegistryConfig.IndexConfigs}}' | python3 -m json.tool

このコマンドは、Docker デーモンが認識しているすべてのレジストリの設定詳細を、読みやすい JSON 構造で出力します。デフォルトでは、Docker Hub (index.docker.io) が設定されていることがわかります。

レジストリへの接続のテスト

Docker Hub に接続して、その証明書を検証してみましょう。

docker login

プロンプトが表示されたら、Ctrl+C を押してログインをキャンセルできます。これは、実際にログインするのではなく、接続をテストしているだけだからです。

Docker クライアントは、ログインプロセス中にレジストリの SSL 証明書を自動的に検証します。証明書が有効な場合は、ログインプロンプトが表示されます。そうでない場合は、Docker はエラーメッセージを表示します。

特定のレジストリを確認するためのファイルの作成

特定のレジストリの証明書をより徹底的に確認するためのスクリプトを作成しましょう。

cat > check_registry_cert.sh << 'EOF'
#!/bin/bash

REGISTRY=${1:-"hub.docker.com"}
PORT=${2:-"443"}

echo "Checking certificate for $REGISTRY:$PORT..."
echo | openssl s_client -connect $REGISTRY:$PORT 2>/dev/null | openssl x509 -noout -dates -issuer -subject

echo -e "\nVerifying certificate chain..."
openssl s_client -connect $REGISTRY:$PORT -showcerts </dev/null 2>/dev/null | grep -A 1 "Certificate chain"
EOF

次に、スクリプトを実行可能にします。

chmod +x check_registry_cert.sh

Docker Hub の証明書を確認するために実行してみましょう。

./check_registry_cert.sh

次のような出力が表示されるはずです。

  • 証明書が発行された日時と有効期限
  • 証明書の発行者
  • 証明書の所有者
  • 証明書チェーンに関する情報

Microsoft のコンテナレジストリである別のレジストリの証明書も確認してみましょう。

./check_registry_cert.sh mcr.microsoft.com

出力を比較して、レジストリ間で証明書がどのように異なるかを確認してください。

SSL 証明書の問題のトラブルシューティング

適切な検証プロセスがあっても、Docker レジストリを操作する際に SSL 証明書の問題が発生する可能性があります。最も一般的な問題を特定し、解決する方法を学びましょう。

一般的な SSL 証明書の問題

最も頻繁に発生する SSL 証明書の問題には、以下が含まれます。

  1. 自己署名証明書
  2. 有効期限切れの証明書
  3. 証明書のホスト名ミスマッチ
  4. 信頼されていない認証局

これらの問題をシミュレートしてトラブルシューティングするために、ディレクトリを作成しましょう。

mkdir -p ~/project/ssl-lab/troubleshooting
cd ~/project/ssl-lab/troubleshooting

テスト用の自己署名証明書の作成

まず、自己署名証明書を作成して、その処理方法を理解しましょう。

openssl req -newkey rsa:2048 -nodes -keyout registry.key -x509 -days 365 -out registry.crt -subj "/CN=registry.example.com"

このコマンドは、以下を作成します。

  • 秘密鍵 (registry.key)
  • 365 日間有効な自己署名証明書 (registry.crt)

自己署名証明書を調べてみましょう。

openssl x509 -in registry.crt -text -noout | grep -E "Issuer|Subject|Not"

自己署名証明書では、証明書が自身に署名しているため、発行者 (Issuer) と件名 (Subject) が同じであることに注意してください。

自己署名証明書を信頼するように Docker を設定する

Docker に自己署名証明書を信頼させるには、通常、それを Docker 証明書ディレクトリに追加します。必要なディレクトリ構造を作成しましょう。

sudo mkdir -p /etc/docker/certs.d/registry.example.com:5000
sudo cp registry.crt /etc/docker/certs.d/registry.example.com:5000/ca.crt

証明書を追加した後、通常は Docker を再起動します。

## この実験(Lab)では実際に Docker を再起動しません
echo "実際の環境では、sudo systemctl restart docker を実行します"

有効期限切れの証明書の処理

有効期限が過去の日付に設定された証明書を作成して、有効期限切れの証明書を確認するシミュレーションを行いましょう。

openssl req -newkey rsa:2048 -nodes -keyout expired.key -x509 -days -30 -out expired.crt -subj "/CN=expired.example.com"

次に、有効期限切れの証明書を調べてみましょう。

openssl x509 -in expired.crt -text -noout | grep -E "Issuer|Subject|Not"

「Not After」の日付が過去になっていることがわかります。これは、証明書の有効期限が切れていることを意味します。

安全でないレジストリの設定

場合によっては、証明書に問題のあるレジストリを使用する必要がある場合があります。Docker では、特定のレジストリを「安全でない」としてマークできます。

cat > daemon.json << 'EOF'
{
  "insecure-registries": [
    "registry.example.com:5000",
    "expired.example.com:5000"
  ]
}
EOF

echo "実際の環境では、このファイルを /etc/docker/daemon.json に配置します"
cat daemon.json

この設定は、Docker に対してこれらのレジストリの証明書検証をスキップするように指示します。これはテスト環境では役立ちますが、本番環境では避けるべきです。

証明書の有効期限を確認するスクリプト

証明書の有効期限が近づいているかどうかを確認するための便利なスクリプトを作成しましょう。

cat > check_expiration.sh << 'EOF'
#!/bin/bash

CERT_FILE=$1
DAYS_WARNING=${2:-30}

if [ ! -f "$CERT_FILE" ]; then
    echo "Certificate file not found: $CERT_FILE"
    exit 1
fi

## Get expiration date in seconds since epoch
EXPIRY=$(openssl x509 -in "$CERT_FILE" -noout -enddate | cut -d= -f2)
EXPIRY_SECONDS=$(date -d "$EXPIRY" +%s)
NOW_SECONDS=$(date +%s)
SECONDS_LEFT=$((EXPIRY_SECONDS - NOW_SECONDS))
DAYS_LEFT=$((SECONDS_LEFT / 86400))

echo "Certificate: $CERT_FILE"
echo "Expires on: $EXPIRY"
echo "Days remaining: $DAYS_LEFT"

if [ $DAYS_LEFT -lt 0 ]; then
    echo "CRITICAL: Certificate has EXPIRED!"
    exit 2
elif [ $DAYS_LEFT -lt $DAYS_WARNING ]; then
    echo "WARNING: Certificate will expire in less than $DAYS_WARNING days!"
    exit 1
else
    echo "OK: Certificate is valid for more than $DAYS_WARNING days."
    exit 0
fi
EOF

chmod +x check_expiration.sh

両方の証明書でスクリプトをテストしてみましょう。

./check_expiration.sh registry.crt
./check_expiration.sh expired.crt

スクリプトが有効な証明書と有効期限切れの証明書を正しく識別することを確認できます。

Docker レジストリ SSL 証明書のベストプラクティス

SSL 証明書の検証とトラブルシューティングの方法を理解したところで、Docker レジストリでの証明書の管理に関するベストプラクティスを探求しましょう。

証明書検証の自動化

予期しない障害を防ぐために、定期的に証明書を検証することが不可欠です。定期的に実行するようにスケジュールできるスクリプトを作成しましょう。

cd ~/project/ssl-lab
cat > monitor_registry_certs.sh << 'EOF'
#!/bin/bash

## チェックするレジストリのリスト
REGISTRIES=(
  "hub.docker.com"
  "mcr.microsoft.com"
  "registry.k8s.io"
  "quay.io"
)

echo "========================================"
echo "Docker Registry Certificate Monitor"
echo "========================================"
echo "Date: $(date)"
echo ""

for registry in "${REGISTRIES[@]}"; do
  echo "Checking $registry..."
  CERT_INFO=$(echo | openssl s_client -connect $registry:443 2>/dev/null | openssl x509 -noout -dates -issuer -subject 2>/dev/null)
  
  if [ -z "$CERT_INFO" ]; then
    echo "ERROR: Could not retrieve certificate for $registry"
  else
    echo "$CERT_INFO"
    
    ## Extract expiry date
    EXPIRY=$(echo "$CERT_INFO" | grep "notAfter" | cut -d= -f2)
    EXPIRY_SECONDS=$(date -d "$EXPIRY" +%s)
    NOW_SECONDS=$(date +%s)
    DAYS_LEFT=$(( (EXPIRY_SECONDS - NOW_SECONDS) / 86400 ))
    
    echo "Days until expiry: $DAYS_LEFT"
    
    if [ $DAYS_LEFT -lt 30 ]; then
      echo "WARNING: Certificate will expire in less than 30 days!"
    fi
  fi
  echo "----------------------------------------"
done
EOF

chmod +x monitor_registry_certs.sh

スクリプトを実行して、その動作を確認しましょう。

./monitor_registry_certs.sh

このスクリプトは複数のレジストリをチェックし、いずれかの証明書の有効期限が近づいている場合に警告を発します。これは、予期しないダウンタイムを防ぐために重要です。

証明書管理のベストプラクティス

Docker レジストリの証明書管理に関するベストプラクティスをまとめたドキュメントを作成しましょう。

cat > certificate_best_practices.md << 'EOF'
## Docker Registry Certificate Management Best Practices

### Certificate Procurement
- Use certificates from trusted Certificate Authorities for production environments
- Use appropriate certificate types (DV, OV, or EV based on needs)
- Ensure certificates match the exact domain names used to access registries
- Consider wildcard certificates for multiple subdomains
- Use appropriate key lengths (minimum 2048 bits for RSA)

### Certificate Deployment
- Store certificates securely
- Use proper file permissions (readable only by the Docker daemon)
- Back up certificates and private keys securely
- Implement proper certificate rotation procedures
- Keep certificate paths consistent across all nodes in a cluster

### Monitoring and Maintenance
- Set up alerts for certificates nearing expiration (at least 30 days in advance)
- Maintain an inventory of all certificates in use
- Document renewal procedures
- Test certificate renewals in a staging environment before production
- Automate certificate renewal where possible (using tools like certbot)

### Security Considerations
- Never use insecure registries in production environments
- Avoid using self-signed certificates in production
- Implement proper certificate revocation procedures
- Regularly audit certificate usage and permissions
- Keep the CA bundle updated on all systems
EOF

cat certificate_best_practices.md

安全なレジストリの設定テンプレートの作成

最後に、安全な Docker レジストリ設定のテンプレートを作成しましょう。

cat > secure_registry_config.yml << 'EOF'
version: '3'

services:
  registry:
    image: registry:2
    ports:
      - 5000:5000
    environment:
      REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt
      REGISTRY_HTTP_TLS_KEY: /certs/domain.key
      ## Additional security settings
      REGISTRY_STORAGE_DELETE_ENABLED: "true"
      REGISTRY_HTTP_HEADERS_X_CONTENT_TYPE_OPTIONS: nosniff
      REGISTRY_HTTP_HEADERS_X_FRAME_OPTIONS: DENY
    volumes:
      - ./certs:/certs
      - ./data:/var/lib/registry
    restart: always
    
  ## Optional: Add a UI for your registry
  registry-ui:
    image: joxit/docker-registry-ui:latest
    ports:
      - 8080:80
    environment:
      - REGISTRY_URL=https://registry:5000
      - REGISTRY_TITLE=Secure Docker Registry
      - SINGLE_REGISTRY=true
    depends_on:
      - registry
EOF

cat secure_registry_config.yml

この設定は、適切な SSL 証明書設定を使用して、安全な Docker レジストリを実行するためのテンプレートを提供します。

SSL 証明書管理手順の概要

Docker を使用した SSL 証明書管理に関するクイックリファレンスを作成しましょう。

cat > ssl_management_summary.txt << 'EOF'
## Docker Registry SSL Certificate Management Summary

1. VERIFY a registry's certificate:
   openssl s_client -connect registry.example.com:443 -showcerts </dev/null

2. ADD a custom certificate for a registry:
   sudo mkdir -p /etc/docker/certs.d/registry.example.com:5000
   sudo cp registry.crt /etc/docker/certs.d/registry.example.com:5000/ca.crt
   sudo systemctl restart docker

3. CONFIGURE an insecure registry (development only):
   Add to /etc/docker/daemon.json:
   { "insecure-registries": ["registry.example.com:5000"] }
   sudo systemctl restart docker

4. CHECK expiration dates regularly:
   openssl x509 -in certificate.crt -noout -dates

5. AUTOMATE certificate monitoring:
   Create and schedule scripts to check certificates regularly
EOF

cat ssl_management_summary.txt

この概要は、Docker レジストリの SSL 証明書に関連する最も一般的な操作のクイックリファレンスとして機能します。

まとめ

この実験(Lab)では、Docker レジストリの SSL 証明書の検証と管理方法を学びました。これで、以下のことができるようになりました。

  • SSL 証明書とは何か、そしてそれが Docker レジストリのセキュリティにとってなぜ不可欠なのかを理解する
  • OpenSSL および Docker CLI コマンドを使用して SSL 証明書を検証する
  • 有効期限切れの証明書や自己署名証明書など、一般的な証明書の問題をトラブルシューティングする
  • 証明書管理のベストプラクティスを実装する
  • さまざまな証明書シナリオで動作するように Docker を設定する
  • 予期しない障害を防ぐために、証明書監視を自動化する

これらのスキルは、安全な Docker 環境を維持するために不可欠であり、特にセキュリティが最優先される本番環境では重要です。Docker レジストリの SSL 証明書を定期的に検証し、適切に管理することで、セキュリティの脆弱性を防ぎ、コンテナ化されたアプリケーションのスムーズな運用を確保できます。