1. 簡介
容器分析可為容器提供安全漏洞掃描和中繼資料儲存空間。掃描服務會針對 Artifact Registry 和 Container Registry 中的映像檔執行安全漏洞掃描,然後儲存結果中繼資料,並透過 API 供使用者取用。您可以使用中繼資料儲存空間儲存來自不同來源的資訊,包括漏洞掃描、Google Cloud 服務和第三方供應商。
安全漏洞掃描可自動執行或隨選執行:
- 啟用自動掃描功能後,每次將新映像檔推送至 Artifact Registry 或 Container Registry 時,系統就會自動觸發掃描作業。發現新漏洞時,漏洞資訊會持續更新。
- 啟用隨選掃描功能後,您必須執行指令,才能掃描本機映像檔或 Artifact Registry 或 Container Registry 中的映像檔。隨選掃描功能可讓您彈性安排掃描容器的時間。舉例來說,您可以掃描本機建構的映像檔,並修復漏洞,再將映像檔儲存在登錄檔中。掃描完成後,掃描結果最多可供 48 小時,且掃描後不會更新安全漏洞資訊。
將 Container Analysis 整合至持續整合/持續推送軟體更新管道後,您就能根據中繼資料做出決策。舉例來說,您可以使用二進位授權建立部署政策,只允許部署來自受信任登錄庫的符合規定映像檔。
課程內容
- 如何啟用自動掃描
- 如何執行隨選掃描
- 如何在建構管道中整合掃描功能
- 如何簽署已核准的圖片
- 如何使用 GKE 存取控制器封鎖映像檔
- 如何設定 GKE,只允許已簽署核准的映像檔
2. 設定和需求
自學環境設定
- 登入 Google Cloud 控制台,然後建立新專案或重複使用現有專案。如果您還沒有 Gmail 或 Google Workspace 帳戶,請務必建立帳戶。
- 「Project name」是這個專案參與者的顯示名稱。這是 Google API 不會使用的字元字串。您隨時可以更新。
- 專案 ID 在所有 Google Cloud 專案中都是不重複的值,且無法變更 (設定後即無法變更)。Cloud 控制台會自動產生一個專屬字串,您通常不需要特別留意。在大多數程式碼研究室中,您都需要參照專案 ID (通常會標示為
PROJECT_ID
)。如果您不喜歡系統產生的 ID,可以隨機產生另一組 ID。或者,您也可以自行嘗試,看看是否可用。這項設定在這個步驟後即無法變更,並會在專案期間維持不變。 - 僅供參考,有些 API 會使用第三個值,也就是「專案編號」。如要進一步瞭解這三個值,請參閱說明文件。
- 接下來,您需要在 Cloud 控制台中啟用帳單功能,才能使用 Cloud 資源/API。執行本程式碼研究室時,費用應該不會太高,甚至可能不收費。如要關閉資源,避免產生教學課程以外的費用,您可以刪除已建立的資源,或刪除整個專案。Google Cloud 新使用者可享有 $300 美元的免費試用期。
啟動 Cloudshell 編輯器
本研究室是專為搭配 Google Cloud Shell 編輯器使用而設計及測試。如要存取編輯器,請按照下列步驟操作:
- 前往 https://console.cloud.google.com 存取 Google 專案。
- 按一下右上角的雲端 Shell 編輯器圖示
- 視窗底部會開啟新的窗格
環境設定
在 Cloud Shell 中,設定專案 ID 和專案編號。分別儲存為 PROJECT_ID
和 PROJECT_ID
變數。
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
建立 Artifact Registry 存放區
在本實驗室中,您將使用 Artifact Registry 儲存及掃描圖片。請使用下列指令建立存放區。
gcloud artifacts repositories create artifact-scanning-repo \
--repository-format=docker \
--location=us-central1 \
--description="Docker repository"
設定 Docker,讓其在存取 Artifact Registry 時使用 gcloud 憑證。
gcloud auth configure-docker us-central1-docker.pkg.dev
3. 自動掃描
每次將新映像檔推送至 Artifact Registry 或 Container Registry 時,系統都會自動觸發容器掃描作業。當我們發現新的安全漏洞時,就會持續更新漏洞資訊。在本節中,您將將圖片推送至 Artifact Registry,並查看結果。
建立並變更至工作目錄
mkdir vuln-scan && cd vuln-scan
定義範例圖片
建立名為 Dockerfile 的檔案,並在其中加入下列內容:
cat > ./Dockerfile << EOF
FROM gcr.io/google-appengine/debian9@sha256:ebffcf0df9aa33f342c4e1d4c8428b784fc571cdf6fbab0b31330347ca8af97a
# System
RUN apt update && apt install python3-pip -y
# App
WORKDIR /app
COPY . ./
RUN pip3 install Flask==1.1.4
RUN pip3 install gunicorn==20.1.0
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 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
建構並將圖片推送至 AR
使用 Cloud Build 建構容器,並自動將容器推送至 Artifact Registry。請注意圖片上的標記 bad
。方便您在後續步驟中識別。
gcloud builds submit . -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad
查看圖片詳細資料
建構程序完成後,請在 Artifact Registry 資訊主頁中查看映像檔和安全漏洞結果。
- 在 Cloud Console 中開啟 Artifact Registry
- 按一下「artifact-scanning-repo」檢視內容
- 點選圖片詳細資料
- 點選圖片的最新摘要
- 掃描完成後,請按一下映像檔的「安全漏洞」分頁
您可以在「安全漏洞」分頁中,查看系統自動掃描剛建構的映像檔後的結果。
自動掃描功能預設為啟用。請參閱 Artifact Registry 設定,瞭解如何關閉/開啟自動掃描功能。
4. 隨選掃描
在某些情況下,您可能需要先執行掃描作業,再將映像檔推送至存放區。舉例來說,容器開發人員可以掃描映像檔並修正問題,然後再將程式碼推送至來源控管。在下方範例中,您將在本機建構及分析圖片,然後再根據結果採取行動。
建構映像檔
在這個步驟中,您將使用本機 Docker 將映像檔建構至本機快取。
docker build -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image .
掃描圖片
圖片建構完成後,請要求掃描圖片。掃描結果會儲存在中繼資料伺服器中。工作完成後,中繼資料伺服器會顯示結果的位置。
gcloud artifacts docker images scan \
us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
--format="value(response.scan)" > scan_id.txt
查看輸出檔案
請花點時間查看先前步驟的輸出內容,這些內容儲存在 scan_id.txt 檔案中。請注意中繼資料伺服器中掃描結果的報表位置。
cat scan_id.txt
查看詳細掃描結果
如要查看掃描的實際結果,請在輸出檔案中記錄的報表位置使用 list-vulnerabilities
指令。
gcloud artifacts docker images list-vulnerabilities $(cat scan_id.txt)
輸出內容包含大量關於映像檔中所有安全漏洞的資料。
標記重大問題
人類很少直接使用報表中儲存的資料。通常會由自動化程序使用結果。請使用下列指令讀取報告詳細資料,並記錄是否發現任何重大漏洞
export SEVERITY=CRITICAL
gcloud artifacts docker images list-vulnerabilities $(cat scan_id.txt) --format="value(vulnerability.effectiveSeverity)" | if grep -Fxq ${SEVERITY}; then echo "Failed vulnerability check for ${SEVERITY} level"; else echo "No ${SEVERITY} Vulnerabilities found"; fi
這項指令的輸出內容如下:
Failed vulnerability check for CRITICAL level
5. 建構管道掃描
在本節中,您將建立自動化建構管道,以便建構容器映像檔、掃描該映像檔,然後評估結果。如果沒有發現任何重大安全漏洞,系統就會將映像檔推送至存放區。如果發現「CRITICAL」漏洞,建構作業就會失敗並結束。
為 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 管道
下列指令會在目錄中建立 cloudbuild.yaml 檔案,用於自動化程序。在這個範例中,步驟僅限於容器建構程序。不過,在實際操作中,您除了容器步驟外,還應加入應用程式專屬的操作說明和測試。
使用下列指令建立檔案。
cat > ./cloudbuild.yaml << EOF
steps:
# build
- id: "build"
name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '.']
waitFor: ['-']
#Run a vulnerability scan at _SECURITY level
- id: scan
name: 'gcr.io/cloud-builders/gcloud'
entrypoint: 'bash'
args:
- '-c'
- |
(gcloud artifacts docker images scan \
us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
--location us \
--format="value(response.scan)") > /workspace/scan_id.txt
#Analyze the result of the scan
- id: severity check
name: 'gcr.io/cloud-builders/gcloud'
entrypoint: 'bash'
args:
- '-c'
- |
gcloud artifacts docker images list-vulnerabilities \$(cat /workspace/scan_id.txt) \
--format="value(vulnerability.effectiveSeverity)" | if grep -Fxq CRITICAL; \
then echo "Failed vulnerability check for CRITICAL level" && exit 1; else echo "No CRITICAL vulnerability found, congrats !" && exit 0; fi
#Retag
- id: "retag"
name: 'gcr.io/cloud-builders/docker'
args: ['tag', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', 'us-central1-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', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']
images:
- us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
EOF
執行 CI 管道
提交建構檔案供處理,以便驗證在發現「重大」嚴重程度的安全漏洞時,是否會導致建構中斷。
gcloud builds submit
查看建構作業失敗
由於映像檔含有重大安全漏洞,因此您剛提交的版本會失敗。
在「Cloud Build History」頁面中查看建構失敗原因
修正安全漏洞
更新 Dockerfile,以便使用不含重大安全漏洞的基本映像檔。
使用下列指令覆寫 Dockerfile,以便使用 Debian 10 映像檔
cat > ./Dockerfile << EOF
from python:3.8-slim
# App
WORKDIR /app
COPY . ./
RUN pip3 install Flask==2.1.0
RUN pip3 install gunicorn==20.1.0
CMD exec gunicorn --bind :\$PORT --workers 1 --threads 8 main:app
EOF
使用正確圖片執行持續整合程序
提交建構項目進行處理,確認在未發現重大嚴重性安全漏洞的情況下,建構作業會成功。
gcloud builds submit
查看建構作業是否成功
您剛提交的版本會成功,因為更新後的映像檔不含任何重大漏洞。
在 Cloud Build 記錄頁面中查看建構作業是否成功
查看掃描結果
查看 Artifact Registry 中的正確映像檔
- 在 Cloud Console 中開啟 Artifact Registry
- 按一下「artifact-scanning-repo」檢視內容
- 點選圖片詳細資料
- 點選圖片的最新摘要
- 按一下映像檔的「安全漏洞」分頁
6. 簽署圖片
建立驗證者附註
Attestor Note 只是一小段資料,可做為所套用簽章類型的標籤。舉例來說,一則附註可能表示要進行漏洞掃描,另一則則可能用於品質確保簽核。系統會在簽署程序中參照附註。
建立記事
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}"
建立驗證者
驗證者會執行實際的圖片簽署程序,並將註解的例項附加至圖片,以利日後驗證。建立驗證者,以供日後使用。
建立驗證者
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
認證器。因此,上述指令會傳回兩個認證者:vulnz-attestor
和 built-by-cloud-build
。映像檔建構成功後,Cloud Build 會自動為其簽署並建立認證。
新增 IAM 角色
二進位元授權服務帳戶需要具備查看認證附註的權限。透過下列 API 呼叫提供存取權
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"
新增 KMS 金鑰
認證者需要加密編譯金鑰才能附加附註並提供可驗證的簽名。在這個步驟中,您將在 KMS 中建立及儲存金鑰,以便 Cloud Build 稍後存取。
首先新增一些環境變數來說明新鍵
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"
您應該會在 Google Cloud Console 的 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
建立已簽署的認證
此時,您已設定可用來簽署圖片的功能。使用先前建立的 Attestor 為您目前使用的容器映像檔簽署
CONTAINER_PATH=us-central1-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}"
在容器分析術語中,這會建立新的事件,並附加至認證者的筆記。為確保一切正常運作,您可以列出認證
gcloud container binauthz attestations list \
--attestor=$ATTESTOR_ID --attestor-project=${PROJECT_ID}
7. 使用 Cloud Build 簽署
您已啟用圖片簽署功能,並手動使用 Attestor 為範例圖片簽署。實際上,您應該在自動化程序 (例如持續整合/持續推送軟體更新管道) 中套用認證。
在本節中,您將設定 Cloud Build 自動驗證映像檔
角色
將二進位授權驗證者檢視者角色新增至 Cloud Build 服務帳戶:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/binaryauthorization.attestorsViewer
將 Cloud KMS CryptoKey Signer/Verifier 角色新增至 Cloud Build 服務帳戶 (以 KMS 為基礎的簽署):
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/cloudkms.signerVerifier
將容器分析附註附加者角色新增至 Cloud Build 服務帳戶:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/containeranalysis.notes.attacher
準備自訂建構 Cloud Build 步驟
您將在 Cloud Build 中使用自訂建構步驟,簡化認證程序。Google 提供這個自訂建構步驟,其中包含輔助函式,可簡化程序。使用前,自訂建構步驟的程式碼必須建構至容器,並推送至 Cloud Build。如要這麼做,請執行下列指令:
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 管道。
- 查看要新增的新步驟。
僅限查看。請勿複製
#Sign the image only if the previous severity check passes - id: 'create-attestation' name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest' args: - '--artifact-url' - 'us-central1-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', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '.']
waitFor: ['-']
#Run a vulnerability scan at _SECURITY level
- id: scan
name: 'gcr.io/cloud-builders/gcloud'
entrypoint: 'bash'
args:
- '-c'
- |
(gcloud artifacts docker images scan \
us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
--location us \
--format="value(response.scan)") > /workspace/scan_id.txt
#Analyze the result of the scan
- id: severity check
name: 'gcr.io/cloud-builders/gcloud'
entrypoint: 'bash'
args:
- '-c'
- |
gcloud artifacts docker images list-vulnerabilities \$(cat /workspace/scan_id.txt) \
--format="value(vulnerability.effectiveSeverity)" | if grep -Fxq CRITICAL; \
then echo "Failed vulnerability check for CRITICAL level" && exit 1; else echo "No CRITICAL vulnerability found, congrats !" && exit 0; fi
#Retag
- id: "retag"
name: 'gcr.io/cloud-builders/docker'
args: ['tag', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', 'us-central1-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', 'us-central1-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'
- 'us-central1-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:
- us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good
EOF
執行建構作業
gcloud builds submit
在 Cloud Build 記錄中查看版本
開啟 Cloud 控制台的「Cloud Build History」(Cloud Build 記錄) 頁面,查看最新版本和建構步驟是否已成功執行。
8. 許可控制政策
二進位授權是 GKE 和 Cloud Run 中的一項功能,可在允許執行容器映像檔前驗證規則。系統會在執行映像檔的任何要求上執行驗證作業,無論是來自可信任的 CI/CD 管道,還是使用者嘗試手動部署映像檔。這項功能比單獨使用 CI/CD 管道檢查,更能有效保護執行階段環境。
為了瞭解這項功能,您將修改預設的 GKE 政策,以便強制執行嚴格的授權規則。
建立 GKE 叢集
建立 GKE 叢集:
gcloud beta container clusters create binauthz \
--zone us-central1-a \
--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
- 部署範例,驗證您是否可以部署任何內容
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
- 變更政策
在文字編輯器中,將 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
- 開啟 Terminal 並套用新政策,然後等待幾秒,讓變更生效
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
9. 在 GKE 中封鎖安全漏洞
在本節中,您將結合目前所學,透過 Cloud Build 實作 CI/CD 管道來掃描映像檔,然後在簽署映像檔並嘗試部署前,檢查是否有任何安全漏洞。GKE 會使用二進位授權驗證映像檔是否具有安全漏洞掃描的簽章,然後才允許映像檔執行。
更新 GKE 政策,要求認證
要求映像檔由驗證器簽署,方法是將 clusterAdmissionRules 新增至 GKE BinAuth 政策
使用下列指令,以更新的設定覆寫政策。
COMPUTE_ZONE=us-central1-a
cat > binauth_policy.yaml << EOM
defaultAdmissionRule:
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
evaluationMode: ALWAYS_DENY
globalPolicyEvaluationMode: ENABLE
clusterAdmissionRules:
${COMPUTE_ZONE}.binauthz:
evaluationMode: REQUIRE_ATTESTATION
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
requireAttestationsBy:
- projects/${PROJECT_ID}/attestors/vulnz-attestor
EOM
套用政策
gcloud beta container binauthz policy import binauth_policy.yaml
嘗試部署未簽署的映像檔
使用下列指令,為先前建構的應用程式建立部署描述元。這裡使用的映像檔是您先前建立的映像檔,其中含有重大安全漏洞,且不含已簽署的認證。
GKE 存取控制器需要知道要部署的確切映像檔,才能一貫驗證簽名。如要達成這項目標,您必須使用圖片摘要,而非簡單的標記。
取得錯誤圖片的圖片摘要
CONTAINER_PATH=us-central1-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
部署已簽署的映像檔
取得不良圖片的圖片摘要
CONTAINER_PATH=us-central1-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
查看主控台的工作負載,並注意是否已成功部署映像檔。
10. 恭喜!
恭喜,您已完成程式碼研究室!
課程內容:
- 如何啟用自動掃描
- 如何執行隨選掃描
- 如何在建構管道中整合掃描功能
- 如何簽署已核准的圖片
- 如何使用 GKE 存取控制器封鎖映像檔
- 如何設定 GKE,只允許已簽署核准的映像檔
下一步:
- 將映像檔部署至 Cloud Run 和 Google Kubernetes Engine 的安全措施 | Cloud Build 說明文件
- 快速入門:使用 GKE 設定二進位授權政策 | Google Cloud
清除所用資源
如要避免系統向您的 Google Cloud 帳戶收取本教學課程所用資源的費用,請刪除含有相關資源的專案,或者保留專案但刪除個別資源。
刪除專案
如要避免付費,最簡單的方法就是刪除您為了本教學課程所建立的專案。