Kritis Signer で証明書を作成する

このチュートリアルでは、Binary Authorization 証明書を作成する前に、Kritis Signer をビルドし、コンテナ イメージの脆弱性をチェックする方法を説明します。

概要

Kritis Signer はオープンソースのコマンドライン ツールで、構成したポリシーに基づいて Binary Authorization 証明書を作成できます。また、Container Analysis により特定されるイメージの脆弱性を確認してから、Kritis Signer を使用して証明書を作成することもできます。

さらに、Cloud Build では、ビルド パイプラインのカスタム ビルダーとして Kritis Signer を実行できます。

このチュートリアルでは、Kritis Signer カスタム ビルダーの 1 回限りのビルドを実行し、サンプルのビルド パイプラインを実行します。各サンプル パイプラインには、次のビルドステップが含まれます。

  1. サンプル コンテナ イメージを作成します。
  2. イメージを Container Registry に push します。
  3. イメージを確認して署名します。ポリシーに基づいて、Kritis Signer を使用して証明書を作成します。

各パイプラインのチェックと署名のビルドステップで、Kritis Signer は以下を行います。

  1. Container Analysis を使用して、新しくビルドされたイメージをスキャンし、脆弱性のリストを取得します。
  2. ポリシー内の脆弱性署名ルールと脆弱性のリストを比較し、以下を行います。
    1. 特定されたすべての脆弱性が脆弱性署名ルールを満たしている場合、Kritis Signer は証明書を作成します。
    2. 特定した脆弱性のいずれかが脆弱性署名ルールに違反している場合、Kritis Signer は証明書を作成しません。

デプロイ時に、Binary Authorization 適用者が検証可能な証明書を確認します。検証可能な証明書がない場合、適用者によりイメージのデプロイが拒否されます。

このチュートリアルでは、Cloud Build パイプラインでチェック専用モードで Kritis Signer を実行する方法についても説明します。このモードでは、Kritis Signer は証明書を作成しないため、脆弱性の結果がポリシーの脆弱性署名ルールを満たすかどうかのみが確認されます。満たす場合、Kritis Signer のビルドステップは成功し、パイプラインは引き続き実行されます。違反する場合、ステップが失敗し、パイプラインが終了します。

目標

このチュートリアルでは、次のことを行います。

  1. Kritis Signer を Cloud Build カスタム ビルダーとして設定します。
  2. 脆弱性署名ルールを含むポリシーを表示します。
  3. Kritis Signer を実行して、脆弱性スキャンの結果に基づいた証明書を作成します。
  4. チェック専用モードで Kritis Signer を実行します。

料金

このチュートリアルでは、次の Google Cloud プロダクトを使用します。

  • Container Registry
  • Container Analysis
  • Cloud Build
  • Cloud Key Management Service

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを出すことができます。

始める前に

このセクションでは、システムを 1 回だけ設定します。

環境の設定

  1. Google Cloud プロジェクトを環境変数に保存します。

    export PROJECT_ID=PROJECT_ID
    

    PROJECT_ID は、Google Cloud プロジェクトに置き換えます。

  2. デフォルトのプロジェクト ID を Google Cloud プロジェクトに設定します。

    gcloud config set project $PROJECT_ID
    
  3. 以降のステップのために、プロジェクト番号を環境変数に保存します。

    export PROJECT_NUMBER=$(gcloud projects list --filter="${PROJECT_ID}" \
     --format="value(PROJECT_NUMBER)")
    
  4. API の有効化:

    このガイドに必要なサービスを有効にするには、次のコマンドを実行します。

    gcloud services enable \
      cloudbuild.googleapis.com \
      containerregistry.googleapis.com \
      containerscanning.googleapis.com \
      cloudkms.googleapis.com
    

IAM ロールを設定する

下記のコマンドを実行して、次のロールを Cloud Build サービス アカウントに構成します。

  • containeranalysis.notes.editor: 認証者を管理するために、Container Analysis のメモの編集者のロールを追加します。
  • containeranalysis.notes.occurrences.viewer: 脆弱性と証明書の両方のオカレンスを管理するために、Container Analysis のメモのオカレンスのロールを追加します。
  • roles/containeranalysis.occurrences.editor: Container Analysis で証明書のオカレンスを作成するために、Container Analysis のオカレンスの編集者のロールを追加します。
  • cloudkms.signer: Cloud KMS CryptoKey の署名者のロールを追加します。これにより、サービス アカウントが Cloud KMS 署名サービスにアクセスできるようになります。

    gcloud projects add-iam-policy-binding $PROJECT_ID --member serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com --role roles/containeranalysis.notes.editor
    gcloud projects add-iam-policy-binding $PROJECT_ID --member serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com --role roles/containeranalysis.notes.occurrences.viewer
    gcloud projects add-iam-policy-binding $PROJECT_ID --member serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com --role roles/containeranalysis.occurrences.editor
    gcloud projects add-iam-policy-binding $PROJECT_ID --member serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com --role roles/cloudkms.signer
    

Kritis Signer カスタム ビルダーを設定する

このセクションでは、Kritis Signer カスタム ビルダーの 1 回限りの設定を行います。Kritis Signer を取得、ビルド、push したら、任意の Cloud Build パイプラインでこれを使用できます。

このセクションでは、次の方法を説明します。

  • Kritis リポジトリのクローンを作成します。
  • Kritis Signer の Cloud Build カスタム ビルダーをビルドします。
  • Cloud Build ビルドステップとして使用できるように Kritis Signer を Container Registry に push します。

次のコマンドを実行して、このガイドで使用されているコードと構成ファイルを取得します。

  1. Kritis リポジトリのクローンを作成します。

    git clone https://github.com/grafeas/kritis.git
    

    このリポジトリには次のものが含まれます。

    • Kritis Signer が含まれている Kritis のソースコード。
    • Cloud Build が Kritis Signer カスタム ビルダーをビルドするために使用する Cloud Build 構成ファイル
    • 脆弱性署名ルールを含むサンプル ポリシー。
    • Cloud Build 構成ファイルの例。各構成ファイルは、脆弱性スキャン パイプラインで Kritis Signer を使用します。
  2. kritis/ ディレクトリに移動します。

    cd kritis
    
  3. Kritis Signer カスタム ビルダーをビルドして登録します。

    この 1 回限りの設定手順では、Kritis Signer カスタム ビルダーをビルドして Cloud Build に登録します。登録すると、カスタム ビルダーを任意の Cloud Build パイプラインで使用できるようになります。

    gcloud builds submit . --config deploy/kritis-signer/cloudbuild.yaml
    

既存のポリシーを表示する

このセクションでは、Kritis Signer ポリシーの例を示します。

このポリシーは、Container Analysis にイメージの脆弱性スキャンをリクエストするように Kritis Signer を構成します。スキャンが完了すると、Kritis Signer は、返された脆弱性の結果をポリシーの脆弱性署名ルールと比較します。

このポリシーの脆弱性署名ルールを編集して、以下に基づいた証明書を作成できます。

  • 特定された脆弱性の重大度。
  • 特定の脆弱性。

証明書を無条件に作成する(ALLOW_ALL)か、作成しない(BLOCK_ALL)かをポリシーを設定することもできます。

Kritis Signer ポリシーを表示するには、次のコマンドを実行します。

cat samples/signer/policy.yaml

このポリシーは次のようになります。

apiVersion: kritis.grafeas.io/v1beta1
kind: VulnzSigningPolicy
metadata:
  name: my-vsp
spec:
  imageVulnerabilityRequirements:
    maximumFixableSeverity: MEDIUM
    maximumUnfixableSeverity: MEDIUM
    allowlistCVEs:
    - projects/goog-vulnz/notes/CVE-2021-20305
    - projects/goog-vulnz/notes/CVE-2020-10543
    - projects/goog-vulnz/notes/CVE-2020-10878
    - projects/goog-vulnz/notes/CVE-2020-14155
    - projects/goog-vulnz/notes/CVE-2019-25013
    - projects/goog-vulnz/notes/CVE-2021-33574
    - projects/goog-vulnz/notes/CVE-2021-3520

ここで

  • maximumUnfixableSeveritymaximumFixableSeverity は、Kritis Signer が証明書を作成する共通脆弱性識別子(CVE)の重大度しきい値を定義します。maximumUnfixableSeverity は、修正が現在利用できない場合の重大度のしきい値を定義します。maximumFixableSeverity は、修正が現在利用できる場合の重大度のしきい値を定義します。maximumUnfixableSeveritymaximumFixableSeverity は、次のいずれかの重大度に設定できます。

    • CRITICAL
    • HIGH
    • MEDIUM
    • LOW

    重大度の詳細については、重大度をご覧ください。

    または、maximumUnfixableSeveritymaximumFixableSeverity を次のように設定できます。

    • BLOCK_ALL: 脆弱性が見つかった場合に証明書は作成されません。
    • ALLOW_ALL: 証明書は常に作成されます。
  • allowlistCVEs は、許可リストに登録する特定の CVE のリストです。Kritis Signer は、証明書を作成するかを評価するときに、このリストの CVE を無視します。許可リストの各エントリは、CVE の Container Analysis ノート名と完全に一致する必要があります。Container Analysis の脆弱性ソースについて詳細を確認する。メモの詳細については、メタデータ ストレージをご覧ください。

Cloud KMS 署名鍵を作成する

Cloud Key Management Service 鍵は証明書の作成に使用されます。

  1. kritis-signer-key-ring という名前の新しい Cloud KMS キーリングを作成します。

    gcloud kms keyrings create kritis-signer-key-ring \
       --location global
    
  2. キーリング内に kritis-signer-key という新しい Cloud KMS 鍵を作成します。

    gcloud kms keys create kritis-signer-key \
        --keyring kritis-signer-key-ring \
        --location global \
        --purpose "asymmetric-signing" \
        --default-algorithm "rsa-sign-pkcs1-2048-sha256"
    
  3. 以降の手順のために、ダイジェスト アルゴリズムと Cloud KMS を環境変数に格納します。

    export KMS_DIGEST_ALG=SHA256
    export KMS_KEY_NAME=projects/$PROJECT_ID/locations/global/keyRings/kritis-signer-key-ring/cryptoKeys/kritis-signer-key/cryptoKeyVersions/1
    

メモ名を定義する

すべての証明書は、Container Analysis のメモを参照します。Kritis Signer は、指定した名前のメモを自動的に作成します。既存のメモ名を再利用することもできます。

export NOTE_ID=my-signer-note
export NOTE_NAME=projects/${PROJECT_ID}/notes/${NOTE_ID}

Cloud Build パイプラインで Kritis Signer を使用して証明書を作成する

このセクションでは、Kritis Signer カスタム クラウド ビルダーを使用して、脆弱性スキャンの結果に基づいた Binary Authorization 証明書を作成する方法を説明します。

次の手順は、Kritis Signer リポジトリのサンプルビルド構成ファイルを使用して Kritis Signer がどのように機能するかを示しています。各構成ファイルのサンプルには、次のビルドステップが含まれています。

  1. Docker コンテナ イメージをビルドする docker build ステップ。
  2. 新しくビルドされたコンテナ イメージを Container Registry に push する docker push ステップ。
  3. 次のことを行ってコンテナ イメージをチェックして署名する vulnsign ステップ。

    1. Container Analysis が新しくビルドされたコンテナ イメージの脆弱性の検出結果を返すまで待機します。
    2. 検出結果をポリシーの脆弱性署名ルールと比較します。
    3. 調査結果が脆弱性ルールに準拠している場合に証明書を作成します。

各サンプルビルドを Cloud Build に送信します。ビルドごとに脆弱性の結果が生成されます。

  • 失敗例: 最初のビルドで脆弱性の結果が脆弱性署名ルールに違反します。このビルドは失敗します。
  • 成功例: 2 番目のビルドでは、脆弱性の結果が脆弱性署名ルールを満たしています。このビルドは成功します。

失敗例のサンプルビルドを送信する

この例では、Debian 9 ベースのコンテナ イメージを作成します。この段階で、イメージには脆弱性署名ルールに違反する脆弱性が含まれています。Kritis Signer カスタム ビルダーは、証明書を生成しません。

  1. (省略可)失敗例のビルド構成ファイルを表示します。

    cat samples/signer/cloudbuild-bad.yaml
    
  2. ビルドを送信します。

    gcloud builds submit \
      --substitutions=_KMS_KEY_NAME=$KMS_KEY_NAME,_KMS_DIGEST_ALG=$KMS_DIGEST_ALG,_NOTE_NAME=$NOTE_NAME \
      --config=samples/signer/cloudbuild-bad.yaml samples/signer
    

    次のような出力が表示されます。

    "ERROR: (gcloud.builds.submit) build BUILD_ID completed with status "FAILURE"
    
  3. 最後のビルドのビルド ID を保存します。

    export BUILD_ID=$(gcloud builds list --limit=1 --format="value('ID')")
    
  4. 結果を確認します。

     gsutil cat gs://${PROJECT_NUMBER}.cloudbuild-logs.googleusercontent.com/log-${BUILD_ID}.txt | grep "does not pass VulnzSigningPolicy"
    

成功例のサンプルビルドを送信する

この例では、脆弱性署名ルールに違反しない脆弱性を含むコンテナ イメージを作成します。Kritis Signer カスタム ビルダーは、証明書を作成します。

成功例のビルドを Cloud Build に送信する手順は次のとおりです。

  1. (省略可)成功例のビルド構成ファイルを表示します

    cat samples/signer/cloudbuild-good.yaml
    
  2. ビルドを送信します。

    gcloud builds submit \
      --substitutions=_KMS_KEY_NAME=$KMS_KEY_NAME,_KMS_DIGEST_ALG=$KMS_DIGEST_ALG,_NOTE_NAME=$NOTE_NAME \
      --config=samples/signer/cloudbuild-good.yaml samples/signer
    
  3. 最後のビルドのビルド ID を保存します。

    export BUILD_ID=$(gcloud builds list --limit=1 --format="value('ID')")
    
  4. 結果を確認します。

    gcloud builds describe $BUILD_ID | grep status
    

チェック専用モードで Kritis Signer を使用する

このセクションでは、check-only モードで Kritis Signer を使用する方法を説明します。このモードでは、Kritis Signer は証明書を作成しません。脆弱性署名ルールに基づいてビルドステップが成功または失敗するまでは、イメージの脆弱性のみがチェックされます。

失敗例のサンプルビルドを送信する

  1. (省略可)失敗例のビルド構成ファイルを表示します。

    cat samples/policy-check/cloudbuild-bad.yaml
    

    Kritis Signer のビルドステップでは、mode フラグが check-only に設定されていることに注意してください。

  2. ビルドを送信します。

    gcloud builds submit \
      --config=samples/policy-check/cloudbuild-bad.yaml samples/policy-check
    

    ビルドが失敗することに注意してください。

  3. 最後のビルドのビルド ID を保存します。

    export BUILD_ID=$(gcloud builds list --limit=1 --format="value('ID')")
    
  4. 結果を確認します。

     gsutil cat gs://${PROJECT_NUMBER}.cloudbuild-logs.googleusercontent.com/log-${BUILD_ID}.txt | grep "does not pass VulnzSigningPolicy"
    

成功例のサンプルビルドを送信する

  1. (省略可)失敗例のビルド構成ファイルを表示します。

    cat samples/policy-check/cloudbuild-good.yaml
    
  2. ビルドを送信します。

    gcloud builds submit \
     --config=samples/policy-check/cloudbuild-good.yaml samples/policy-check
    
  3. 最後のビルドのビルド ID を保存します。

    export BUILD_ID=$(gcloud builds list --limit=1 --format="value('ID')")
    
  4. 結果を確認します。

    gcloud builds describe $BUILD_ID | grep status
    

クリーンアップ

このドキュメントで使用されたリソースをクリーンアップするには、プロジェクトを削除します。

gcloud projects delete ${PROJECT_ID}

次のステップ