מידע על Codelab זה
1. מבוא
Container Analysis מספק סריקת נקודות חולשה ואחסון מטא-נתונים בקונטיינרים. שירות הסריקה מבצע בדיקות לאיתור נקודות חולשה בתמונות ב-Artifact Registry וב-Container Registry. אחר כך מאחסן את המטא-נתונים שמתקבלים והופך אותם לזמינים לצריכה באמצעות API. אחסון מטא-נתונים מאפשר לאחסן מידע ממקורות שונים, כולל סריקה של נקודות חולשה, שירותי Google Cloud וספקי צד שלישי.
סריקת נקודות חולשה יכולה להתרחש באופן אוטומטי או על פי דרישה:
- כשהאפשרות סריקה אוטומטית מופעלת, הסריקה מופעלת באופן אוטומטי בכל פעם שדוחפים תמונה חדשה ל-Artifact Registry או ל-Container Registry. המידע על נקודות חולשה מתעדכן באופן קבוע כאשר מתגלות נקודות חולשה חדשות.
- כשהאפשרות On-Demand Scanning מופעלת, צריך להריץ פקודה כדי לסרוק תמונה מקומית או תמונה ב-Artifact Registry או ב-Container Registry. סריקה לפי דרישה מאפשרת גמישות בסריקת קונטיינרים. לדוגמה, אפשר לסרוק תמונה שפותחה באופן מקומי ולתקן נקודות חולשה לפני אחסונה במרשם. תוצאות הסריקה זמינות למשך עד 48 שעות לאחר השלמת הסריקה, והמידע על נקודות החולשה לא מתעדכן לאחר הסריקה.
כשמשלבים את Container Analysis בצינור עיבוד הנתונים של CI/CD, אפשר לקבל החלטות על סמך המטא-נתונים האלה. לדוגמה, אפשר להשתמש ב-Binary Authorization כדי ליצור מדיניות פריסה שמאפשרת פריסות רק של תמונות תואמות מרשמים מהימנים.
מה תלמדו
- איך מפעילים סריקה אוטומטית
- איך מבצעים סריקה לפי דרישה
- איך לשלב סריקה בצינור עיבוד נתונים של build
- איך חותמים על תמונות שאושרו
- איך משתמשים בבקרים של כניסה ל-GKE כדי לחסום תמונות
- איך להגדיר את GKE כך לאפשר רק תמונות חתומות שאושרו
2. הגדרה ודרישות
הגדרת סביבה בקצב אישי
- נכנסים למסוף Google Cloud ויוצרים פרויקט חדש או עושים שימוש חוזר בפרויקט קיים. אם אין לכם עדיין חשבון Gmail או חשבון Google Workspace, עליכם ליצור חשבון.
- Project name הוא השם המוצג של המשתתפים בפרויקט. זו מחרוזת תווים שלא משמשת את Google APIs. אפשר לעדכן אותו בכל שלב.
- Project ID הוא ייחודי בכל הפרויקטים ב-Google Cloud ואי אפשר לשנות אותו (אי אפשר לשנות אותו אחרי שמגדירים אותו). מסוף Cloud יוצר מחרוזת ייחודית באופן אוטומטי; בדרך כלל לא מעניין אותך מה זה. ברוב ה-Codelabs תצטרכו להפנות אל מזהה הפרויקט (בדרך כלל הוא מזוהה כ-
PROJECT_ID
). אם המזהה שנוצר לא מוצא חן בעיניך, יש לך אפשרות ליצור מזהה אקראי אחר. לחלופין, אפשר לנסות תבנית משלך ולבדוק אם היא זמינה. לא ניתן לשנות אותו אחרי השלב הזה, והוא יישאר למשך הפרויקט. - לידיעתך, יש ערך שלישי – Project Number (מספר פרויקט), שחלק מממשקי ה-API משתמשים בו. מידע נוסף על כל שלושת הערכים האלה זמין במסמכי התיעוד.
- בשלב הבא צריך להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבים או בממשקי API של Cloud. מעבר ב-Codelab הזה לא אמור לעלות הרבה, אם בכלל. כדי להשבית את המשאבים ולא לצבור חיובים מעבר למדריך הזה, אתם יכולים למחוק את המשאבים שיצרתם או למחוק את הפרויקט כולו. משתמשים חדשים ב-Google Cloud זכאים להצטרף לתוכנית תקופת ניסיון בחינם בשווי 1,200 ש"ח.
הפעלת Cloudshell Editor
שיעור ה-Lab הזה תוכנן ונבדק לשימוש עם Google Cloud Shell Editor. כדי לגשת לכלי העריכה:
- ניגשים לפרויקט Google בכתובת https://console.cloud.google.com.
- בפינה השמאלית העליונה, לוחצים על סמל העורך של Cloud Shell
- חלונית חדשה תיפתח בחלק התחתון של החלון
הגדרת סביבה
ב-Cloud Shell, מגדירים את מזהה הפרויקט ואת מספר הפרויקט. שומרים אותם כמשתנים מסוג 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
בשיעור ה-Lab הזה תשתמשו ב-Artifact Registry כדי לאחסן ולסרוק את התמונות. יוצרים את המאגר באמצעות הפקודה הבאה.
gcloud artifacts repositories create artifact-scanning-repo \
--repository-format=docker \
--location=us-central1 \
--description="Docker repository"
הגדרת Docer לשימוש בפרטי הכניסה של gcloud בגישה ל-Artifact Registry.
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
בדיקת פרטי התמונה
בסיום תהליך ה-build, צריך לבדוק את תוצאות התמונות ונקודות החולשה בלוח הבקרה של Artifact Registry.
- פותחים את Artifact Registry במסוף Cloud
- כדי להציג את התוכן, לוחצים על המאגר לסריקת ארטיפקטים.
- לוחצים לפתיחת פרטי התמונה
- לוחצים כדי להציג את התקציר האחרון של התמונה
- בסיום הסריקה, לוחצים על כרטיסיית נקודות החולשה של התמונה
בכרטיסיית נקודות החולשה תוכלו לראות את תוצאות הסריקה האוטומטית של התמונה שיצרתם כרגע.
סריקה אוטומטית מופעלת כברירת מחדל. בודקים בהגדרות של 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
בדיקת קובץ הפלט
כדאי להקדיש רגע כדי לבדוק את הפלט של השלב הקודם שנשמר בקובץ Scanner_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. סריקת צינור עיבוד נתונים לבניית
בקטע הזה תיצרו צינור עיבוד נתונים אוטומטי לפיתוח גרסת build כדי ליצור קובץ אימג' בקונטיינר, לסרוק אותו ולאחר מכן להעריך את התוצאות. אם לא יימצאו נקודות חולשה קריטיות, תתבצע דחיפה של התמונה למאגר. אם יימצאו נקודות חולשה CRIT עליהן, ה-build ייכשל ותתבצע יציאה.
מתן גישה לחשבון השירות ב-Cloud Build
ל-Cloud Build נדרשות הרשאות כדי לגשת לממשק ה-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 בספרייה שלכם שישמש לתהליך האוטומטי. בדוגמה הזו, השלבים מוגבלים לתהליך ה-build של הקונטיינר. עם זאת, בפועל צריך לכלול הוראות ובדיקות ספציפיות לאפליקציה בנוסף לשלבים של מאגר התגים.
יוצרים את הקובץ באמצעות הפקודה הבאה.
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
צריך לשלוח את ה-build לעיבוד כדי לאמת את ההפסקות ל-build אם מתגלה פרצת אבטחה חמורה.
gcloud builds submit
כשל ב-Build של הביקורת
גרסת ה-build ששלחת תיכשל כי התמונה מכילה נקודות חולשה קריטיות.
אפשר לבדוק את כשל ה-build בדף היסטוריה של Cloud Build
איך לתקן את פרצת האבטחה
מעדכנים את קובץ ה-Docker כך שישתמש בתמונת בסיס שלא מכילה נקודות חולשה מאוד קריטיות.
מחליפים את קובץ ה-Docker כדי להשתמש בתמונה של 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
מריצים את תהליך ה-CI עם התמונה הטובה
צריך לשלוח את ה-build לעיבוד כדי לוודא שה-build יצליח אם לא נמצאו נקודות חולשה בחומרה קריטית.
gcloud builds submit
בדיקת הצלחה ב-Build
ה-build ששלחת עכשיו יצליח כי התמונה המעודכנת לא מכילה נקודות חולשה קריטיות.
לבדוק את הצלחת ה-build בדף היסטוריית השימוש ב-Cloud Build.
בדיקת תוצאות הסריקה
בדיקת התמונה הטובה במרשם של Artifact
- פותחים את Artifact Registry במסוף Cloud
- כדי להציג את התוכן, לוחצים על המאגר לסריקת ארטיפקטים.
- לוחצים לפתיחת פרטי התמונה
- לוחצים כדי להציג את התקציר האחרון של התמונה
- יש ללחוץ על כרטיסיית נקודות החולשה של התמונה
6. תמונות של חתימה
יצירה של הערת גורם מאמת
הערת גורם מאמת היא קטע נתונים קטן שמשמש כתווית לסוג החתימה שמיושמת. לדוגמה, הערה אחת עשויה להצביע על סריקת נקודות חולשה, והערה אחרת עשויה לשמש ליציאה לבקרת איכות. תתבצע הפניה להערה בתהליך החתימה.
יצירת הערה
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
בפרויקט כאשר אתם מריצים build שיוצר תמונות. הפקודה שלמעלה מחזירה שני גורמים מאמתים, vulnz-attestor
ו-built-by-cloud-build
. אחרי שמסיימים לבנות את התמונות, Cloud Build חותם ויוצר להן אימותים באופן אוטומטי.
הוספת תפקיד IAM
לחשבון השירות Binary Authorization נדרשות הרשאות כדי לצפות בהערות האימות. מספקים את הגישה באמצעות הקריאה הבאה ל-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"
המפתח אמור להופיע בדף של KMS במסוף Google Cloud.
בשלב הזה, משייכים את המפתח למאמת באמצעות הפקודה 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
יצירת הצהרה חתומה
בשלב הזה כבר הגדרת את התכונות שמאפשרות לך לחתום על תמונות. משתמשים בגורם המאמת שיצרתם קודם כדי לחתום על תמונת הקונטיינר שאיתה אתם עובדים.
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 כדי ליצור את האימות (attestation). הפקודה פשוט לוקחת את הפרטים של המפתח שבו רוצים להשתמש לצורך חתימה, ואת תמונת הקונטיינר הספציפית שרוצים לאשר.
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, ייווצר אירוע חדש ותצרף אותו להערה של המאמת. כדי להבטיח שהכול יפעל כמו שצריך, אפשר לרשום את האימותים (attestation) שלך
gcloud container binauthz attestations list \
--attestor=$ATTESTOR_ID --attestor-project=${PROJECT_ID}
7. חתימה באמצעות Cloud Build
הפעלת חתימת תמונה והשתמשת באופן ידני במאמת כדי לחתום את התמונה לדוגמה. בפועל, כדאי להחיל הצהרות במהלך תהליכים אוטומטיים, כמו צינורות עיבוד נתונים של CI/CD.
בקטע הזה מגדירים את Cloud Build כדי לאמת תמונות באופן אוטומטי
תפקידים
הוספת התפקיד 'Binary Authorization Attestor Viewer' לחשבון השירות של Cloud Build:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/binaryauthorization.attestorsViewer
הוספת תפקיד חותם/מאמת של CryptoKey ב-Cloud KMS לחשבון שירות ב-Cloud Build (חתימה מבוססת-KMS):
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/cloudkms.signerVerifier
הוספת תפקיד Container Analysis Notes Attacher לחשבון שירות ב-Cloud Build:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/containeranalysis.notes.attacher
הכנת השלב של build בהתאמה אישית ב-Cloud Build
תשתמשו בשלב Custom Build ב-Cloud Build כדי לפשט את תהליך האימות. Google מספקת את שלב ה-build בהתאמה אישית שכולל פונקציות מסייעות כדי לייעל את התהליך. לפני השימוש, הקוד של שלב ה-build המותאם אישית צריך להיות מובנה בקונטיינר ולהעביר אותו ל-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
הרצת ה-build
gcloud builds submit
בדיקת ה-build בהיסטוריה של Cloud Build
פותחים את מסוף Cloud בדף ההיסטוריה של Cloud Build, ובודקים את ה-build האחרון ואת הביצוע של שלבי ה-build.
8. מדיניות בקרה על אישור בקשות
Binary Authorization היא תכונה ב-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
- פריסת 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
- שנה את המדיניות
בכלי לעריכת טקסט, משנים את ערך ההערכה מ-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
- פותחים את 'טרמינל' ומחילים את המדיניות החדשה וממתינים כמה שניות עד שהשינוי ייכנס לתוקף
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
כדי להתיר את כל סוגי האירועים, צריך לבטל את המדיניות
לפני שממשיכים לקטע הבא, חשוב לבטל את שינויי המדיניות
- שנה את המדיניות
בכלי לעריכת טקסט, משנים את ערך ההערכה מ-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
בחלק הזה תשלבו את מה שלמדתם עד עכשיו באמצעות הטמעת צינור עיבוד נתונים של CI/CD עם Cloud Build שסורק את התמונות, ולאחר מכן מחפש נקודות חולשה לפני שחותמים על התמונה ומנסים לפרוס אותה. מערכת GKE תשתמש ב-Binary Authorization כדי לאמת שהתמונה כוללת חתימה מסריקת נקודות החולשה לפני שמאפשרת לתמונה לפעול.
עדכון המדיניות של GKE לדרישת אימות (attestation)
לדרוש שתמונות חתומות על ידי המאמת על ידי הוספת clusterAdmissionRules למדיניות BinAuth ב-GKE.
מחליפים את המדיניות בהגדרות האישיות המעודכנות באמצעות הפקודה הבאה.
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. מעולה!
כל הכבוד, סיימת את ה-Codelab!
נושאים שטיפלנו בהם:
- איך מפעילים סריקה אוטומטית
- איך מבצעים סריקה לפי דרישה
- איך לשלב סריקה בצינור עיבוד נתונים של build
- איך חותמים על תמונות שאושרו
- איך משתמשים בבקרים של כניסה ל-GKE כדי לחסום תמונות
- איך להגדיר את GKE כך לאפשר רק תמונות חתומות שאושרו
השלב הבא:
- אבטחת פריסות של תמונות ל-Cloud Run ול-Google Kubernetes Engine | משאבי עזרה ל-Cloud Build
- מדריך למתחילים: הגדרת מדיניות Binary Authorization באמצעות GKE | Google Cloud
הסרת המשאבים
כדי להימנע מצבירת חיובים בחשבון Google Cloud על המשאבים שנעשה בהם שימוש במדריך הזה, צריך למחוק את הפרויקט שמכיל את המשאבים או לשמור את הפרויקט ולמחוק את המשאבים הספציפיים.
מחיקת הפרויקט
הדרך הקלה ביותר לבטל את החיוב היא למחוק את הפרויקט שיצרתם בשביל המדריך הזה.