1. מבוא
Binary Authorization היא אמצעי אבטחה בזמן פריסה שמבטיחה שרק תמונות קונטיינרים מהימנות ייפרסו ב-Google Kubernetes Engine (GKE) או ב-Cloud Run. באמצעות Binary Authorization, ניתן לדרוש שהתמונות יחתמו על ידי רשויות מהימנות במהלך תהליך הפיתוח, ולאחר מכן לאכוף אימות חתימה במהלך הפריסה. באמצעות אכיפת האימות תוכלו לקבל שליטה הדוקה יותר על סביבת הקונטיינרים, כי רק תמונות מאומתות משולבות בתהליך ה-build וההשקה.
בתרשים הבא מוצגים הרכיבים בהגדרה של Binary Authorization או Cloud Build:
**איור 1.**צינור עיבוד הנתונים של Cloud Build שיוצר אימות ב-Binary Authorization.
בצינור עיבוד הנתונים הזה:
- הקוד לבניית קובץ האימג' בקונטיינר מועבר למאגר מקור, כמו Cloud Source Repositories.
- Cloud Build הוא כלי אינטגרציה רציפה (CI) לפיתוח ובדיקה של הקונטיינר.
- גרסת ה-build מעבירה את קובץ האימג' של הקונטיינר ל-Container Registry או למרשם אחר שמאחסן את התמונות שנוצרו.
- Cloud Key Management Service, שמספק ניהול מפתחות לזוג המפתחות הקריפטוגרפיים, חותם על קובץ האימג' של הקונטיינר. לאחר מכן החתימה שתתקבל נשמרת בתהליך אימות (attestation) חדש שנוצר.
- בזמן הפריסה, המאמת מאמת את האימות באמצעות המפתח הציבורי מזוג המפתחות. Binary Authorization אוכף את המדיניות באמצעות דרישה של אימותים (attestation) חתומים כדי לפרוס את קובץ האימג' בקונטיינר.
בשיעור ה-Lab הזה נתמקד בכלים ובטכניקות לאבטחת ארטיפקטים שנפרסו. שיעור ה-Lab הזה מתמקדים בארטיפקטים (קונטיינרים) אחרי שהם נוצרו אבל לא נפרסו בסביבה מסוימת.
מה תלמדו
- חתימת תמונה
- מדיניות בקרה על אישור בקשות
- חתימה על תמונות סרוקות
- בתהליך הרשאה לתמונות חתומות
- תמונות לא חתומות חסומות
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 ש"ח.
הגדרת סביבה
ב-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
יצירה ושינוי בספריית עבודה
mkdir vuln-scan && cd vuln-scan
הגדרת תמונה לדוגמה
יוצרים קובץ בשם Dockerfile עם התוכן הבא.
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
צור קובץ בשם 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.
gcloud builds submit . -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
3. חתימת תמונה
מהו גורם מאמת
הגורם המאמת
- האדם הזה או התהליך הזה אחראים לקישור אחד בשרשרת האמון של המערכת.
- הם מחזיקים מפתח קריפטוגרפי, וחותמים על תמונה אם היא עוברת את תהליך האישור.
- יוצר המדיניות קובע את המדיניות בצורה מופשטת ברמה גבוהה, אבל הגורם המאמת אחראי לאכוף באופן קונקרטי היבט מסוים של המדיניות.
- הוא יכול להיות אדם אמיתי, כמו בודק של בקרת איכות או מנהל, או להיות בוט במערכת CI.
- אבטחת המערכת תלויה במהימנות שלה, לכן חשוב שהמפתחות הפרטיים שלהם יהיו מאובטחים.
כל אחד מהתפקידים האלה יכול לייצג אדם פרטי או צוות של אנשים בארגון. בסביבת ייצור, סביר להניח שהתפקידים האלה ינוהלו על ידי פרויקטים נפרדים ב-Google Cloud Platform (GCP), והגישה למשאבים ישותפו ביניהם באופן מוגבל באמצעות Cloud IAM.
מאמתים ב-Binary Authorization מוטמעים בנוסף ל-Cloud Container Analysis API, לכן חשוב לתאר איך זה עובד לפני שממשיכים. Container Analysis API נועד לאפשר לשייך מטא-נתונים לתמונות ספציפיות של קונטיינרים.
לדוגמה, ניתן ליצור פתק כדי לעקוב אחר נקודת החולשה Heartbleed. לאחר מכן ספקי אבטחה ייצרו סורקים כדי לבדוק קובצי אימג' של קונטיינרים כדי לאתר את פרצת האבטחה, וליצור אירוע שמשויך לכל קונטיינר שנפגע.
לצד נקודות החולשה במעקב, Container Analysis תוכנן להיות ממשק API כללי למטא-נתונים. ב-Binary Authorization נעשה שימוש ב-Container Analysis כדי לשייך חתימות לתמונות הקונטיינרים שהן מאמתות**.** הערה של ניתוח קונטיינרים משמשת לייצוג מאמת יחיד, וכל אירוע נוצר ומשויך לכל מאגר שהמאמת אושר.
ב-Binary Authorization API נעשה שימוש במושגים של 'גורמים מאמתים' ו-'attestations', אבל הם מיושמים באמצעות הערות ואירועים תואמים ב-Container Analysis API.
יצירה של הערת גורם מאמת
הערת גורם מאמת היא קטע נתונים קטן שמשמש כתווית לסוג החתימה שמיושמת. לדוגמה, הערה אחת עשויה להצביע על סריקת נקודות חולשה, והערה אחרת עשויה לשמש ליציאה לבקרת איכות. תתבצע הפניה להערה בתהליך החתימה.
יצירת הערה
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
בפרויקט כאשר אתם מריצים 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
לפני שתוכלו להשתמש במזהה הזה, ברשות שלכם צריכה ליצור זוג מפתחות קריפטוגרפיים שישמש לחתימה על תמונות קונטיינר. ניתן לעשות זאת באמצעות 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"
המפתח אמור להופיע בדף של 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}
4. מדיניות בקרה על אישור בקשות
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
המדיניות הזו פשוטה יחסית. בשורה globalPolicyEvaluationMode מוצהר שהמדיניות הזו מרחיבה את המדיניות הגלובלית שהוגדרה על ידי Google. כך כל הקונטיינרים הרשמיים של GKE יכולים לפעול כברירת מחדל. בנוסף, המדיניות מצהירה על defaultAdmissionRule, שלפיו כל מערכי ה-Pod האחרים יידחו. כלל הכניסה כולל את השורה enforcementMode, שלפיה צריך לחסום את ההפעלה של כל ה-Pods שלא תואמים לכלל הזה באשכול.
הוראות לפיתוח כללי מדיניות מורכבים יותר מפורטות במסמכי התיעוד של Binary Authorization.
- פותחים את 'טרמינל' ומחילים את המדיניות החדשה וממתינים כמה שניות עד שהשינוי ייכנס לתוקף
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
5. חתימה על תמונות סרוקות
הפעלת חתימת תמונה והשתמשת באופן ידני במאמת כדי לחתום את התמונה לדוגמה. בפועל, כדאי להחיל הצהרות במהלך תהליכים אוטומטיים, כמו צינורות עיבוד נתונים של 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
מתן גישה לחשבון השירות ב-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"
הכנת השלב של 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.
6. בתהליך הרשאה לתמונות חתומות
בקטע הזה מעדכנים את 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
עכשיו אמור להיות קובץ חדש בדיסק בשם updated_policy.yaml. עכשיו, במקום שכלל ברירת המחדל דוחה את כל התמונות, בשלב הראשון הוא בודק את הגורם המאמת.
העלאת המדיניות החדשה ל-Binary Authorization:
gcloud beta container binauthz policy import binauth_policy.yaml
פריסה של תמונה חתומה
תקציר תמונות של תמונה טובה
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
בודקים את עומס העבודה במסוף ורושמים את הפריסה המוצלחת של התמונה.
7. תמונות לא חתומות חסומות
בניית תמונה
בשלב הזה תשתמשו ב-Docker מקומי כדי ליצור את התמונה במטמון המקומי.
docker build -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad .
דחיפת התמונה הלא חתומה למאגר
docker push us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad
קבלת תקציר תמונות של התמונה הגרועה
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
8. מעולה!
כל הכבוד, סיימת את ה-Codelab!
נושאים שטיפלנו בהם:
- חתימת תמונה
- מדיניות בקרה על אישור בקשות
- חתימה על תמונות סרוקות
- בתהליך הרשאה לתמונות חתומות
- תמונות לא חתומות חסומות
השלב הבא:
- אבטחת פריסות של תמונות ל-Cloud Run ול-Google Kubernetes Engine | משאבי עזרה ל-Cloud Build
- מדריך למתחילים: הגדרת מדיניות Binary Authorization באמצעות GKE | Google Cloud
הסרת המשאבים
כדי להימנע מצבירת חיובים בחשבון Google Cloud על המשאבים שנעשה בהם שימוש במדריך הזה, צריך למחוק את הפרויקט שמכיל את המשאבים או לשמור את הפרויקט ולמחוק את המשאבים הספציפיים.
מחיקת הפרויקט
הדרך הקלה ביותר לבטל את החיוב היא למחוק את הפרויקט שיצרתם בשביל המדריך הזה.
—
עדכון אחרון: 21.03.23