Kritis Signer を使用した脆弱性スキャン統合

このガイドでは、Kritis Signer を使用し、Container Analysis の脆弱性スキャンに基づいて Binary Authorization 証明書を作成する方法について説明します。

Kritis Signer の概要

ソフトウェアの脆弱性は、偶発的なシステム障害の原因になる場合や、意図的に悪用される可能性がある弱点です。 脆弱性のあるイメージのデプロイを防ぐことは、サプライ チェーンのセキュリティの重要な側面です。

Kritis Signer は、脆弱性スキャンなどの CI/CD パイプライン サービスに基づいた Binary Authorization 証明書を作成できるオープンソースのコマンドライン ツールです。Cloud Build カスタム ビルダーとして Kritis Signer を使用すると、Container Analysis の脆弱性スキャンの結果を取得し、構成した脆弱性ポリシーに照らして結果を確認できます。

脆弱性の結果内の特定された脆弱性がすべて脆弱性署名ポリシーを満たす場合、Kritis Signer は、関連するイメージの Binary Authorization 証明書を作成します。

脆弱性の結果内の特定された脆弱性のいずれかが脆弱性ポリシーに違反する場合、Kritis Signer は証明書を作成しません。

検証された証明書がなければ、Binary Authorization 施行者はイメージのデプロイを拒否します。

目標

このガイドでは、次のことを行います。

  1. Kritis Signer を Cloud Build カスタム ビルダーとして設定します。
  2. 脆弱性署名ポリシーを表示します。
  3. 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 プロジェクトの ID です。

  1. 以降のステップのために、プロジェクト番号を環境変数に保存します。

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

    このガイドで必要なサービスが有効になっていることを確認するには、次のコマンドを実行します。

    gcloud --project=$PROJECT_ID services enable \
      cloudbuild.googleapis.com \
      containerregistry.googleapis.com \
      containeranalysis.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 を取得、ビルド、プッシュしたら、どの Cloud Build パイプラインでも使用できます。

このセクションでは、次の方法について説明します。

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

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

  1. 次のコマンドで Kritis リポジトリのクローンを作成します。

     git clone --branch signer-v1.0.0 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 --project=$PROJECT_ID builds submit . --config deploy/kritis-signer/cloudbuild.yaml
    

既存の脆弱性署名ポリシーの表示

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

Kritis Signer は、Container Analysis によって特定された脆弱性をこのポリシーと照合します。

このポリシーを編集して許可リストに登録することができます。

  • 特定された脆弱性に関連付けられた認定済みの重大度スコア(CVSS 仕様に記載)。
  • 特定の脆弱性(CVE)

脆弱性署名ポリシーを表示するには:

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-2020-10543
    - projects/goog-vulnz/notes/CVE-2020-10878
    - projects/goog-vulnz/notes/CVE-2020-14155

ここで

  • maximumUnfixableSeveritymaximumFixableSeverity は、次のいずれかになります。

    • CRITICAL: CVSS 仕様に基づく Critical のスコア
    • HIGH: CVSS 仕様に基づく High のスコア
    • MEDIUM: CVSS 仕様に基づく Medium のスコア
    • LOW: CVSS 仕様に基づく Low のスコア
    • BLOCK_ALL: 脆弱性が見つかると、証明書は作成されません。
    • ALLOW_ALL: 脆弱性が特定されても証明書が作成されます。
  • allowlistCVEs は脆弱性のリストです。各エントリはメモの名前と完全に一致する必要があります。

Cloud KMS 署名鍵を作成する

Cloud Key Management Service 鍵を使用して、認証者と証明書を作成します。

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

    gcloud --project=$PROJECT_ID kms keyrings create my-key-ring-1 \
       --location global
    
  2. キーリング内に my-signing-key-1 という新しい Cloud KMS 鍵を作成します。

    gcloud --project=$PROJECT_ID kms keys create my-signing-key-1 \
        --keyring my-key-ring-1 \
        --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/my-key-ring-1/cryptoKeys/my-signing-key-1/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 --project=$PROJECT_ID 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. ビルド出力の Build ID をメモしておきます。

    $BUILD_ID 環境変数を build-id に設定します。

    export BUILD_ID=build-id
    

    この変数は次のステップで使用します。

  4. 次のコマンドを実行して、最新ビルドのビルド ID を確認することもできます。

    gcloud builds list --limit 1
    

    最初に返されるフィールドはビルド ID です。 他のビルドを表示するには、--limit 値を変更します。すべてのビルドを表示するには、フラグをすべて削除します。

  5. 結果を確認します。

     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 --project=$PROJECT_ID 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 をメモして、$BUILD_ID 環境変数に保存してください。

    export BUILD_ID=build-id
    
  4. 最後に、以下のコマンドを入力して結果を確認します。

    gcloud --project=$PROJECT_ID builds describe $BUILD_ID | grep status
    

次のステップ