LoginSignup
1
1

More than 3 years have passed since last update.

GCPのBinary Authorization (Container Image署名のApproval)を試してみた

Posted at

チュートリアルベースでの評価メモ。

  • GCP (Google Cloud Platform)が提供するBinary Authorizationのうち、Attestor(証人 / 署名者)によるContainer Image署名の検証機能を確認。
  • GKE上でのContainer Deploy(kubectl run)において、署名を登録したImageが許可され、署名されていないImageは拒否されることを確認。

概要

  • Binary Authorizationは、GKE上で実行するContainer Imageを、信頼されたものに限定するための仕掛け。以下の2種類の制限機能がサポートされている(本記事は、Attestorについて記載)。
    • Policy
      • 特定のレジストリ(Domainに対するパターンマッチング)から取得したContainer Imageに限定する。
    • Attestors
      • AttestorによるPGP署名が事前登録されたContainer Imageに限定する。

環境

  • OS
    • Debian GNU/Linux 9 (GCP Cloud Shell)
  • GKE Version
    • v1.13.11-gke.14

特記事項

  • 本評価時点でBetaのため、以下で言及している機能は今後変更される可能性あり。
  • Attestor機能を有効にするためには、GKE Clusterを、--enable-binauthzオプションを指定して作成する必要がある。
  • ポリシーの制限は、デフォルトルール(Project単位)、と除外ルール(Cluster単位)の2種類で指定できる。
  • Attestorに関連付けて登録したImage署名の削除コマンドが見当たらない。
    • gcloud beta container binauthz attestations createで署名を登録できるが、delete操作が見当たらない (Attestor自体を再作成する必要がある?)。

手順

APの有効化

前提となるCloud APIの有効化。

gcloud services enable \
    container.googleapis.com \
    containeranalysis.googleapis.com \
    binaryauthorization.googleapis.com

前提設定(環境変数の設定)

PROJECT_ID="$(gcloud config get-value project)"
NOTE_ID="Sample-Attestor-Note"
ATTESTOR="Sample-Attestor"
ATTESTOR_EMAIL="$(gcloud config get-value core/account)"
PGP_PUB_KEY="key.pgp"

Attestor Noteの作成

まずは、Attestor情報を関連付けるためのNoteを作成する必要がある。

cat > note.json << EOF
{
  "name": "projects/${PROJECT_ID}/notes/${NOTE_ID}",
  "attestation_authority": {
    "hint": {
      "human_readable_name": "SampleName"
    }
  }
}
EOF

curl -X POST \
       -H "Content-Type: application/json" \
       -H "Authorization: Bearer $(gcloud auth print-access-token)"  \
       --data-binary @note.json \
"https://containeranalysis.googleapis.com/v1beta1/projects/${PROJECT_ID}/notes/?noteId=${NOTE_ID}"

署名用PGP Keyの作成

(十分なエントロピーを確保するための)乱数生成用パッケージをインストール。

sudo apt install rng-tools -y

sudo rngd -r /dev/urandom

署名用のPGP鍵を生成し、ファイルにエクスポートする(パスワードを求められるが、今回は空のパスワードを指定)。

gpg --quick-generate-key --yes ${ATTESTOR_EMAIL}
gpg --armor --export "${ATTESTOR_EMAIL}" > ${PGP_PUB_KEY}

Attestorの作成&PGP鍵登録

上記で作成したAttestor Noteを指定して、Attestor情報を登録。

gcloud --project="${PROJECT_ID}" \
     beta container binauthz attestors create "${ATTESTOR}" \
     --attestation-authority-note="${NOTE_ID}" \
     --attestation-authority-note-project="${PROJECT_ID}"

登録したAttestorに対して、PGP鍵を登録。

gcloud --project="${PROJECT_ID}" \
     beta container binauthz attestors public-keys add \
     --attestor="${ATTESTOR}" \
     --pgp-public-key-file="${PGP_PUB_KEY}"

GKE Clusterの設定

クラスタを作成。--enable-binauthzオプションを有効にする必要がある。

gcloud container clusters create sample-cluster --zone us-central1-a --enable-binauthz

Attestationを有効にするポリシーを定義(Attestorによる署名が存在しないイメージを拒否するように設定する)。

cat > policy.yaml << EOF
    defaultAdmissionRule:
      evaluationMode: REQUIRE_ATTESTATION
      enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
      requireAttestationsBy:
        - projects/${PROJECT_ID}/attestors/${ATTESTOR}
    name: projects/${PROJECT_ID}/policy
EOF
gcloud container binauthz policy import policy.yaml

対象のContainer ImageのDigestの情報を取得。

IMAGE_PATH="gcr.io/google-samples/hello-app"
IMAGE_DIGEST="$(gcloud container images list-tags --format='get(digest)' $IMAGE_PATH | head -1)"

デプロイ確認(失敗)

このコンテナの署名は未登録のため、この段階で実行するとエラー終了する(上記で設定したPolicyにより拒否される)。

kubectl run hello-server --generator=run-pod/v1 --image ${IMAGE_PATH}@${IMAGE_DIGEST} --port 8080

Error from server (Forbidden): pods "hello-server" is forbidden: image policy webhook backend denied one or more images: Denied by default admission rule. Denied by Attestor. Image gcr.io/google-samples/hello-app denied by projects/qwiklabs-gcp-01-351cba835b68/attestors/Sample-Attestor: Attestor cannot attest to an image deployed by tag

署名済みイメージの作成

署名用のPGP鍵のFinger Printを取得。

PGP_FINGERPRINT="$(gpg --list-keys ${ATTESTOR_EMAIL} | head -2 | tail -1 | awk '{print $1}')"

署名を作成。

gcloud beta container binauthz create-signature-payload \
    --artifact-url="${IMAGE_PATH}@${IMAGE_DIGEST}" > payload.json
gpg --local-user "${ATTESTOR_EMAIL}" \
      --armor \
      --output signature.json \
      --sign payload.json

署名情報をAttestationとして登録。

gcloud beta container binauthz attestations create \
    --artifact-url="${IMAGE_PATH}@${IMAGE_DIGEST}" \
    --attestor="projects/${PROJECT_ID}/attestors/${ATTESTOR}" \
    --signature-file=signature.json \
    --public-key-id="${PGP_FINGERPRINT}"

デプロイ確認(成功)

署名したイメージを指定してデプロイすると正常終了する。

kubectl run hello-server --generator=run-pod/v1 --image ${IMAGE_PATH}@${IMAGE_DIGEST} --port 8080

参考資料

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1