GSP1183

概要
Binary Authorization は、Google Kubernetes Engine(GKE)や Cloud Run に、信頼できるコンテナ イメージのみをデプロイするためのデプロイ時のセキュリティ コントロールです。Binary Authorization を使用すると、開発プロセスにおいて信頼できる機関によるイメージへの署名を必須にして、デプロイ時にその署名を検証できます。検証プロセスを適用することで、適切であると認められたイメージのみがビルドとリリースのプロセスに組み込まれるため、コンテナ環境をより厳格に管理できます。
次の図は、Binary Authorization と Cloud Build の統合環境のコンポーネントを表しています。
Binary Authorization 証明書を作成する Cloud Build パイプライン。
このパイプラインでは次のことが行われます。
- コンテナ イメージをビルドするためのコードが Cloud Source Repositories などのソース リポジトリに push されます。
- 継続的インテグレーション(CI)ツールである Cloud Build が、コンテナをビルドしてテストします。
- ビルドがコンテナ イメージを Container Registry に push するか、ビルドされたイメージを格納する別のレジストリに push します。
-
暗号鍵ペアの鍵管理を行う Cloud Key Management Service が、コンテナ イメージに署名します。生成された署名は、新しく作成された証明書に保存されます。
- デプロイ時に、認証者が鍵ペアの公開鍵を使用して証明書を検証します。Binary Authorization が、コンテナ イメージをデプロイするための署名付き証明書を要求して、ポリシーを適用します。
このラボでは、デプロイされたアーティファクトを保護するためのツールと手法について学びます。ここでは、作成してからまだ特定の環境にデプロイされていないアーティファクト(コンテナ)に焦点を当てます。
学習内容
- イメージの署名
- アドミッション コントロール ポリシー
- スキャンされたイメージへの署名
- 署名付きイメージの承認
- 署名なしイメージのブロック
設定と要件
[ラボを開始] ボタンをクリックする前に
こちらの説明をお読みください。ラボには時間制限があり、一時停止することはできません。タイマーは Google Cloud のリソースを利用できる時間を示しており、[ラボを開始] をクリックするとスタートします。
このハンズオンラボでは、シミュレーションやデモ環境ではなく実際のクラウド環境を使って、ご自身でラボのアクティビティを行います。そのため、ラボの受講中に Google Cloud にログインおよびアクセスするための、新しい一時的な認証情報が提供されます。
このラボを完了するためには、以下が必要です。
- 標準的なインターネット ブラウザ(Chrome を推奨)
注: このラボの実行には、シークレット モードまたはシークレット ブラウジング ウィンドウを使用してください。これにより、個人アカウントと受講者アカウント間の競合を防ぎ、個人アカウントに追加料金が発生しないようにすることができます。
- ラボを完了するための時間(開始後は一時停止できません)
注: すでに個人の Google Cloud アカウントやプロジェクトをお持ちの場合でも、このラボでは使用しないでください。アカウントへの追加料金が発生する可能性があります。
ラボを開始して Google Cloud コンソールにログインする方法
-
[ラボを開始] ボタンをクリックします。ラボの料金をお支払いいただく必要がある場合は、表示されるポップアップでお支払い方法を選択してください。
左側の [ラボの詳細] パネルには、以下が表示されます。
- [Google Cloud コンソールを開く] ボタン
- 残り時間
- このラボで使用する必要がある一時的な認証情報
- このラボを行うために必要なその他の情報(ある場合)
-
[Google Cloud コンソールを開く] をクリックします(Chrome ブラウザを使用している場合は、右クリックして [シークレット ウィンドウで開く] を選択します)。
ラボでリソースがスピンアップし、別のタブで [ログイン] ページが表示されます。
ヒント: タブをそれぞれ別のウィンドウで開き、並べて表示しておきましょう。
注: [アカウントの選択] ダイアログが表示されたら、[別のアカウントを使用] をクリックします。
-
必要に応じて、下のユーザー名をコピーして、[ログイン] ダイアログに貼り付けます。
{{{user_0.username | "Username"}}}
[ラボの詳細] パネルでもユーザー名を確認できます。
-
[次へ] をクリックします。
-
以下のパスワードをコピーして、[ようこそ] ダイアログに貼り付けます。
{{{user_0.password | "Password"}}}
[ラボの詳細] パネルでもパスワードを確認できます。
-
[次へ] をクリックします。
重要: ラボで提供された認証情報を使用する必要があります。Google Cloud アカウントの認証情報は使用しないでください。
注: このラボでご自身の Google Cloud アカウントを使用すると、追加料金が発生する場合があります。
-
その後次のように進みます。
- 利用規約に同意します。
- 一時的なアカウントなので、復元オプションや 2 要素認証プロセスは設定しないでください。
- 無料トライアルには登録しないでください。
その後、このタブで Google Cloud コンソールが開きます。
注: Google Cloud のプロダクトやサービスのリストを含むメニューを表示するには、左上のナビゲーション メニューをクリックします。
Cloud Shell をアクティブにする
Cloud Shell は、開発ツールと一緒に読み込まれる仮想マシンです。5 GB の永続ホーム ディレクトリが用意されており、Google Cloud で稼働します。Cloud Shell を使用すると、コマンドラインで Google Cloud リソースにアクセスできます。
- Google Cloud コンソールの上部にある「Cloud Shell をアクティブにする」アイコン
をクリックします。
接続した時点で認証が完了しており、プロジェクトに各自の Project_ID、 が設定されます。出力には、このセッションの PROJECT_ID を宣言する次の行が含まれています。
Your Cloud Platform project in this session is set to {{{project_0.project_id | "PROJECT_ID"}}}
gcloud は Google Cloud のコマンドライン ツールです。このツールは、Cloud Shell にプリインストールされており、タブ補完がサポートされています。
- (省略可)次のコマンドを使用すると、有効なアカウント名を一覧表示できます。
gcloud auth list
- [承認] をクリックします。
出力:
ACTIVE: *
ACCOUNT: {{{user_0.username | "ACCOUNT"}}}
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- (省略可)次のコマンドを使用すると、プロジェクト ID を一覧表示できます。
gcloud config list project
出力:
[core]
project = {{{project_0.project_id | "PROJECT_ID"}}}
注: Google Cloud における gcloud ドキュメントの全文については、gcloud CLI の概要ガイドをご覧ください。
環境設定
Cloud Shell で、プロジェクトにプロジェクト ID とプロジェクト番号を設定します。これらを変数 PROJECT_ID と PROJECT_NUMBER として保存します。
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID \
--format='value(projectNumber)')
サービスを有効化する
必要なサービスをすべて有効にします。
gcloud services enable \
cloudkms.googleapis.com \
cloudbuild.googleapis.com \
container.googleapis.com \
containerregistry.googleapis.com \
artifactregistry.googleapis.com \
containerscanning.googleapis.com \
ondemandscanning.googleapis.com \
binaryauthorization.googleapis.com
タスク 1. Artifact Registry リポジトリを作成する
このラボでは、Artifact Registry を使用してイメージを保存し、スキャンします。
- 次のコマンドを使用してリポジトリを作成します。
gcloud artifacts repositories create artifact-scanning-repo \
--repository-format=docker \
--location={{{ project_0.default_region | "REGION" }}} \
--description="Docker repository"
- Artifact Registry にアクセスするときに gcloud 認証情報を使用するよう、Docker を構成します。
gcloud auth configure-docker {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev
- 作業ディレクトリを作成し、そのディレクトリに移動します。
mkdir vuln-scan && cd vuln-scan
- 次に、サンプル イメージを定義します。次の内容で
Dockerfile を作成します。
cat > ./Dockerfile << EOF
FROM python:3.8-alpine
# アプリ
WORKDIR /app
COPY . ./
RUN pip3 install Flask==2.1.0
RUN pip3 install gunicorn==20.1.0
RUN pip3 install Werkzeug==2.2.2
CMD exec gunicorn --bind :\$PORT --workers 1 --threads 8 main:app
EOF
- 次の内容で
main.py ファイルを作成します。
cat > ./main.py << EOF
import os
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
name = os.environ.get("NAME", "Worlds")
return "Hello {}!".format(name)
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
EOF
- Cloud Build を使用してコンテナをビルドし、Artifact Registry に自動的に push します。
gcloud builds submit . -t {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。
Artifact Registry リポジトリを作成する。
タスク 2. イメージの署名
認証者とは
- このユーザーまたはプロセスは、システムの信頼チェーンにおけるリンクの 1 つを担当します。
- 暗号鍵を保持し、承認プロセスに合格したイメージに署名する役割を担います。
- ポリシー作成者がポリシーの抽象的な概要を決定するのに対し、認証者はポリシーの特定の側面を具体的に適用します。
- 認証者は、QA テスターやマネージャーなどの実在する人物の場合もあれば、CI システムの bot の場合もあります。
- システムのセキュリティは認証者の信頼性に依存するため、秘密鍵を安全に保管することが重要です。
これらのロールは、組織内の個人またはチームに割り当てることができます。本番環境では、ロールは別の Google Cloud Platform プロジェクトで管理される可能性が高く、リソースへのアクセスは Cloud IAM を使用して制限された状態で共有されます。
Binary Authorization の認証者は Cloud Container Analysis API の上に実装されているため、先にその API の仕組みを説明することが重要です。Container Analysis API は、メタデータを特定のコンテナ イメージに関連付けることができるように設計されています。
たとえば、Heartbleed 脆弱性を追跡するためのメモを作成できます。セキュリティ ベンダーは、コンテナ イメージの脆弱性をテストするスキャナを作成し、侵害された各コンテナに関連付けられるオカレンスを作成します。
Container Analysis は脆弱性の追跡に加えて、汎用メタデータ API の役割を担うように設計されています。Binary Authorization は Container Analysis を使用して、検証するコンテナ イメージに署名を関連付けます。Container Analysis のメモは単一の認証者を表すために使用されます。その認証者が承認した各コンテナに対してオカレンスが作成され、関連付けられます。
Binary Authorization API は「認証者」と「証明書」のコンセプトを使用しますが、これらはそれぞれ Container Analysis API のメモとオカレンスを使用して実装されます。
認証者のメモを作成する
認証者のメモは、適用される署名のタイプを示すラベルとして機能する、ほんの小さなデータです。たとえば、脆弱性スキャンを示すメモもあれば、QA 承認に使用されるメモもあります。メモは署名プロセス中に参照されます。
- メモを作成する
cat > ./vulnz_note.json << EOM
{
"attestation": {
"hint": {
"human_readable_name": "Container Vulnerabilities attestation authority"
}
}
}
EOM
- メモを保存する
NOTE_ID=vulnz_note
curl -vvv -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
--data-binary @./vulnz_note.json \
"https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/?noteId=${NOTE_ID}"
- メモを確認する
curl -vvv \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}"
これで、メモが Container Analysis API に保存されました。
- 認証者の作成
認証者は、実際のイメージ署名プロセスを実施するために使用され、後で検証するためにメモのオカレンスをイメージに添付します。認証者を利用するには、メモを Binary Authorization に登録する必要もあります。
- 認証者を作成する
ATTESTOR_ID=vulnz-attestor
gcloud container binauthz attestors create $ATTESTOR_ID \
--attestation-authority-note=$NOTE_ID \
--attestation-authority-note-project=${PROJECT_ID}
- 認証者を確認する
gcloud container binauthz attestors list
最後の行で NUM_PUBLIC_KEYS: 0 と表示されますが、鍵は後の手順で指定します。
イメージを生成するビルドを実行すると、Cloud Build によって認証者 built-by-cloud-build が自動的に作成されます。したがって、上記のコマンドは 2 つの認証者(vulnz-attestor と built-by-cloud-build)を返します。イメージが正常にビルドされると、Cloud Build が自動的に署名して証明書を作成します。
-
Binary Authorization サービス アカウントには、証明書のメモを閲覧する権限が必要です。次の API 呼び出しを使用して、IAM ロールへのアクセス権を付与します。
PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)")
BINAUTHZ_SA_EMAIL="service-${PROJECT_NUMBER}@gcp-sa-binaryauthorization.iam.gserviceaccount.com"
cat > ./iam_request.json << EOM
{
'resource': 'projects/${PROJECT_ID}/notes/${NOTE_ID}',
'policy': {
'bindings': [
{
'role': 'roles/containeranalysis.notes.occurrences.viewer',
'members': [
'serviceAccount:${BINAUTHZ_SA_EMAIL}'
]
}
]
}
}
EOM
- このファイルを使用して IAM ポリシーを作成します。
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
--data-binary @./iam_request.json \
"https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}:setIamPolicy"
[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。
認証者を作成する。
タスク 3. KMS 鍵を追加する
この認証者を使用するには、コンテナ イメージの署名に使用できる暗号鍵ペアを作成する権限が必要です。これは、Google Cloud Key Management Service(KMS)を使用して行うことができます。
- まず、新しい鍵について記述する環境変数を追加します。
KEY_LOCATION=global
KEYRING=binauthz-keys
KEY_NAME=codelab-key
KEY_VERSION=1
- 鍵のセットを保持するキーリングを作成します。
gcloud kms keyrings create "${KEYRING}" --location="${KEY_LOCATION}"
- 認証者用の新しい非対称署名鍵ペアを作成します。
gcloud kms keys create "${KEY_NAME}" \
--keyring="${KEYRING}" --location="${KEY_LOCATION}" \
--purpose asymmetric-signing \
--default-algorithm="ec-sign-p256-sha256"
Cloud コンソールの KMS ページに鍵が表示されます。
- 次に、gcloud の
binauthz コマンドを使用して、鍵を認証者に関連付けます。
gcloud beta container binauthz attestors public-keys add \
--attestor="${ATTESTOR_ID}" \
--keyversion-project="${PROJECT_ID}" \
--keyversion-location="${KEY_LOCATION}" \
--keyversion-keyring="${KEYRING}" \
--keyversion-key="${KEY_NAME}" \
--keyversion="${KEY_VERSION}"
- 権限リストをもう一度出力すると、登録された鍵が表示されます。
gcloud container binauthz attestors list
[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。
KMS 鍵を追加する。
タスク 4. 署名付き証明書を作成する
イメージに署名できる機能の構成はできました。次に、すでに作成した認証者を使用して、作業中のコンテナ イメージに署名します。

証明書には、認証者が特定のコンテナ イメージを検証し、クラスタで安全に実行できることを示す暗号署名が含まれている必要があります。
- 証明するコンテナ イメージを指定するには、次のコマンドを実行してダイジェストを特定します。
CONTAINER_PATH={{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:latest \
--format='get(image_summary.digest)')
- これで、gcloud を使用して証明書を作成できるようになりました。このコマンドは、署名に使用する鍵の詳細と、承認する特定のコンテナ イメージを取得します。
gcloud beta container binauthz attestations sign-and-create \
--artifact-url="${CONTAINER_PATH}@${DIGEST}" \
--attestor="${ATTESTOR_ID}" \
--attestor-project="${PROJECT_ID}" \
--keyversion-project="${PROJECT_ID}" \
--keyversion-location="${KEY_LOCATION}" \
--keyversion-keyring="${KEYRING}" \
--keyversion-key="${KEY_NAME}" \
--keyversion="${KEY_VERSION}"
Container Analysis の観点では、これにより新しいオカレンスが作成され、それが認証者のメモに添付されます。
- すべてが想定どおりに動作したことを確認するために、次のコマンドを実行して証明書を一覧表示します。
gcloud container binauthz attestations list \
--attestor=$ATTESTOR_ID --attestor-project=${PROJECT_ID}
タスク 5. アドミッション コントロール ポリシー
Binary Authorization は、コンテナ イメージの実行を許可する前にルールを検証できるようにする、GKE と Cloud Run の機能です。どのイメージ実行リクエストに対しても検証が実施されます。これは、信頼できる CI / CD パイプラインからのリクエストであっても、ユーザーが手動でイメージをデプロイしようとするリクエストであっても同様です。この機能により、CI / CD パイプラインのチェックだけでは実現できない、より効果的なランタイム環境の保護が可能になります。
この機能を理解するために、デフォルトの GKE ポリシーを変更して厳格な認可ルールを適用します。
- Binary Authorization を有効にした GKE クラスタを作成します。
gcloud beta container clusters create binauthz \
--zone {{{ project_0.default_zone | "ZONE" }}} \
--binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE
- Cloud Build がこのクラスタにデプロイできるようにします。
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
--role="roles/container.developer"
すべて許可のポリシー
まず、デフォルトのポリシーの状態と、任意のイメージをデプロイできることを確認します。
- 既存のポリシーを確認します。
gcloud container binauthz policy export
- 適用ポリシーが
ALWAYS_ALLOW に設定されていることを確認します。
evaluationMode: ALWAYS_ALLOW
- Sample をデプロイして、任意のイメージをデプロイできることを確認します。
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- デプロイが正常に動作したことを確認します。
kubectl get pods
次のような出力が表示されます。
- デプロイを削除します。
kubectl delete pod hello-server
すべて拒否のポリシー
次に、すべてのイメージを拒否するようにポリシーを更新します。
- 現在のポリシーを編集可能なファイルにエクスポートします。
gcloud container binauthz policy export > policy.yaml
- テキスト エディタで
policy.yaml ファイルを開き、evaluationMode を ALWAYS_ALLOW から ALWAYS_DENY に変更します。
edit policy.yaml
編集したポリシーの YAML ファイルが次のように表示されていることを確認します。
globalPolicyEvaluationMode: ENABLE
defaultAdmissionRule:
evaluationMode: ALWAYS_DENY
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
name: projects/PROJECT_ID/policy
このポリシーは比較的シンプルです。globalPolicyEvaluationMode 行は、Google によって定義されたグローバル ポリシーを拡張することを宣言しています。これにより、すべての公式 GKE コンテナがデフォルトで実行されます。また、他のすべての Pod が拒否されることを示す defaultAdmissionRule を宣言しています。アドミッション ルールには enforcementMode 行が含まれています。これは、このルールに準拠していないすべての Pod がブロックされ、クラスタで実行されないことを示しています。
より複雑なポリシーを構築する方法については、Binary Authorization のドキュメントをご覧ください。
- Cloud Shell で次のコマンドを実行して、新しいポリシーを適用します。
gcloud container binauthz policy import policy.yaml
変更が反映されるまで数秒待ちます。
- サンプル ワークロードのデプロイを試します。
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- デプロイが失敗し、次のメッセージが表示されます。
Error from server (VIOLATES_POLICY): admission webhook "imagepolicywebhook.image-policy.k8s.io" denied the request: Image gcr.io/google-samples/hello-app:1.0 denied by Binary Authorization default admission rule. Denied by always_deny admission rule
ポリシーを元に戻してすべてを許可する
次のセクションに進む前に、ポリシーの変更を元に戻します。
- テキスト エディタで、
evaluationMode を ALWAYS_DENY から ALWAYS_ALLOW に変更します。
edit policy.yaml
変更されたポリシーの YAML ファイルが次のように表示されます。
globalPolicyEvaluationMode: ENABLE
defaultAdmissionRule:
evaluationMode: ALWAYS_ALLOW
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
name: projects/PROJECT_ID/policy
- 元に戻したポリシーを適用します。
gcloud container binauthz policy import policy.yaml
[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。
GKE クラスタを作成してポリシーを更新する。
タスク 6. イメージに自動署名する
これで、イメージ署名を有効にし、認証者を手動で使用してサンプル イメージに署名できました。しかし実際には、CI / CD パイプラインなどの自動化されたプロセスで証明書を適用する必要があるでしょう。
このセクションでは、イメージを自動的に証明するように Cloud Build を構成します。
必要なロール
- Cloud Build サービス アカウントに Binary Authorization 認証者 / 閲覧者のロールを追加します。
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/binaryauthorization.attestorsViewer
- Cloud Build サービス アカウントに Cloud KMS 暗号鍵の署名者 / 検証者のロールを追加します(KMS ベースの署名)。
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/cloudkms.signerVerifier
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com \
--role roles/cloudkms.signerVerifier
- Cloud Build サービス アカウントに Container Analysis メモ添付者のロールを追加します。
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/containeranalysis.notes.attacher
Cloud Build サービス アカウントにアクセス権を付与する
Cloud Build には、On-Demand Scanning API へのアクセス権が必要です。
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
--role="roles/iam.serviceAccountUser"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
--role="roles/ondemandscanning.admin"
Cloud Build のカスタムビルド ステップを準備する
Cloud Build のカスタムビルド ステップを使用して、証明プロセスを簡素化します。このカスタムビルド ステップは Google が提供しており、プロセスを効率化するためのヘルパー関数が含まれています。使用する前に、カスタムビルド ステップのコードをビルドしてコンテナを作成し、Cloud Build に push する必要があります。
git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git
cd cloud-builders-community/binauthz-attestation
gcloud builds submit . --config cloudbuild.yaml
cd ../..
rm -rf cloud-builders-community
cloudbuild.yaml に署名ステップを追加する
Cloud Build パイプラインに証明書ステップを追加します。
- 以下の署名の手順を確認します。
確認専用です。コピーして使用することはできません。
# 前の重大度チェックに合格した場合のみ、イメージに署名します
- id: 'create-attestation'
name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest'
args:
- '--artifact-url'
- '{{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image'
- '--attestor'
- 'projects/${PROJECT_ID}/attestors/$ATTESTOR_ID'
- '--keyversion'
- 'projects/${PROJECT_ID}/locations/$KEY_LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY_NAME/cryptoKeyVersions/$KEY_VERSION'
- 次の完全なパイプラインを含む
cloudbuild.yaml ファイルを作成します。
cat > ./cloudbuild.yaml << EOF
steps:
# build
- id: "build"
name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', '{{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '.']
waitFor: ['-']
# additional CICD checks (not shown)
#Retag
- id: "retag"
name: 'gcr.io/cloud-builders/docker'
args: ['tag', '{{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '{{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']
#pushing to artifact registry
- id: "push"
name: 'gcr.io/cloud-builders/docker'
args: ['push', '{{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']
#Sign the image only if the previous severity check passes
- id: 'create-attestation'
name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest'
args:
- '--artifact-url'
- '{{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good'
- '--attestor'
- 'projects/${PROJECT_ID}/attestors/$ATTESTOR_ID'
- '--keyversion'
- 'projects/${PROJECT_ID}/locations/$KEY_LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY_NAME/cryptoKeyVersions/$KEY_VERSION'
images:
- {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good
EOF
- ビルドを実行します。
gcloud builds submit
Cloud Build の履歴でビルドを確認する
Cloud コンソールで、[Cloud Build] > [ビルド履歴] ページに移動し、最新のビルドと、ビルドステップの実行が成功したことを確認します。
[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。
署名ステップを追加する。
タスク 7. 署名付きイメージを承認する
次に、Binary Authorization を使用して、イメージに脆弱性スキャンの署名があることを検証してからイメージの実行を許可するように、GKE を更新します。
GKE ポリシーを更新して証明書を必須にする
GKE BinAuth ポリシーに clusterAdmissionRules を追加して、認証者によるイメージへの署名を必須にします。
現在、クラスタは 1 つのルール(公式リポジトリのコンテナを許可し、その他をすべて拒否する)を含むポリシーを実行しています。
- 次のコマンドを使用して、更新した構成でポリシーを上書きします。
COMPUTE_ZONE={{{ project_0.default_region | "REGION" }}}
cat > binauth_policy.yaml << EOM
defaultAdmissionRule:
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
evaluationMode: REQUIRE_ATTESTATION
requireAttestationsBy:
- projects/${PROJECT_ID}/attestors/vulnz-attestor
globalPolicyEvaluationMode: ENABLE
clusterAdmissionRules:
${COMPUTE_ZONE}.binauthz:
evaluationMode: REQUIRE_ATTESTATION
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
requireAttestationsBy:
- projects/${PROJECT_ID}/attestors/vulnz-attestor
EOM
- ディスクに
updated_policy.yaml という新しいファイルが作成されます。これにより、デフォルトのルールですべてのイメージが拒否されるのではなく、検証のためにまず認証者を確認するようになります。
- 新しいポリシーを Binary Authorization にアップロードします。
gcloud beta container binauthz policy import binauth_policy.yaml
署名付きイメージをデプロイする
- 署名付きイメージのイメージ ダイジェストを取得します。
CONTAINER_PATH={{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:good \
--format='get(image_summary.digest)')
- Kubernetes 構成でダイジェストを使用します。
cat > deploy.yaml << EOM
apiVersion: v1
kind: Service
metadata:
name: deb-httpd
spec:
selector:
app: deb-httpd
ports:
- protocol: TCP
port: 80
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deb-httpd
spec:
replicas: 1
selector:
matchLabels:
app: deb-httpd
template:
metadata:
labels:
app: deb-httpd
spec:
containers:
- name: deb-httpd
image: ${CONTAINER_PATH}@${DIGEST}
ports:
- containerPort: 8080
env:
- name: PORT
value: "8080"
EOM
- アプリを GKE にデプロイします。
kubectl apply -f deploy.yaml
Cloud コンソールで [Kubernetes Engine] > [ワークロード] に移動し、イメージのデプロイが成功したことを確認します。
[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。
署名付きイメージをデプロイする。
タスク 8. 署名なしイメージのブロック
イメージをビルドする
- ローカル Docker を使用してイメージをビルドし、ローカル キャッシュに保存します。
docker build -t {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad .
- 署名なしイメージをリポジトリに push します。
docker push {{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad
- 署名なしイメージのイメージ ダイジェストを取得します。
CONTAINER_PATH={{{ project_0.default_region | "REGION" }}}-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:bad \
--format='get(image_summary.digest)')
- Kubernetes 構成でダイジェストを使用します。
cat > deploy.yaml << EOM
apiVersion: v1
kind: Service
metadata:
name: deb-httpd
spec:
selector:
app: deb-httpd
ports:
- protocol: TCP
port: 80
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deb-httpd
spec:
replicas: 1
selector:
matchLabels:
app: deb-httpd
template:
metadata:
labels:
app: deb-httpd
spec:
containers:
- name: deb-httpd
image: ${CONTAINER_PATH}@${DIGEST}
ports:
- containerPort: 8080
env:
- name: PORT
value: "8080"
EOM
- アプリの GKE へのデプロイを試みます。
kubectl apply -f deploy.yaml
コンソールでワークロードで、デプロイが拒否されたことを示すエラーを確認します。
No attestations found that were valid and signed by a key trusted by the attestor
[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。
署名なしのイメージをデプロイする。
お疲れさまでした
ここでは、コンテナ イメージの実行を許可する前に、イメージに署名してルールを検証する認証者を作成する方法について学びました。また、Cloud Build に GKE クラスタへのアクセスを許可または拒否するように指示するポリシーを作成する方法を学習しました。さらに、Google Cloud KMS で Binary Authorization を使用してイメージの署名を検証し、署名なしイメージが Kubernetes クラスタにアクセスできないようにしました。
次のステップと詳細情報
Google Cloud トレーニングと認定資格
Google Cloud トレーニングと認定資格を通して、Google Cloud 技術を最大限に活用できるようになります。クラスでは、技術スキルとベスト プラクティスを迅速に身につけ、学習を継続的に進めることができます。トレーニングは基礎レベルから上級レベルまであり、オンデマンド、ライブ、バーチャル参加など、多忙なスケジュールにも対応できるオプションが用意されています。認定資格を取得することで、Google Cloud テクノロジーに関するスキルと知識を証明できます。
マニュアルの最終更新日: 2024 年 9 月 10 日
ラボの最終テスト日: 2024 年 7 月 11 日
Copyright 2024 Google LLC All rights reserved. Google および Google のロゴは、Google LLC の商標です。その他すべての社名および製品名は、それぞれ該当する企業の商標である可能性があります。