אבטחת גרסאות build של קונטיינרים

1. מבוא

ead1609267034bf7.png

נקודות חולשה בתוכנה הן נקודות חולשה שעלולות לגרום לכשל מערכת בטעות או לספק לגורמים זדוניים אמצעי לפגוע בתוכנה. מערכת Container Analysis מספקת שני סוגים של סריקות של מערכת ההפעלה כדי למצוא נקודות חולשה בקונטיינרים:

  • ממשק ה-API לסריקה על פי דרישה מאפשר לסרוק באופן ידני קובצי אימג' בקונטיינרים כדי לאתר נקודות חולשה במערכת ההפעלה, באופן מקומי במחשב או מרחוק ב-Container Registry או ב-Artifact Registry.
  • ה-Container Scanning API מאפשר לכם לבצע אוטומציה של זיהוי נקודות חולשה במערכת ההפעלה, על ידי סריקה בכל פעם שאתם דוחפים קובץ אימג' ל-Container Registry או ל-Artifact Registry. הפעלת ה-API הזה מאפשרת גם לסרוק חבילת שפה כדי לאתר נקודות חולשה ב-Go וב-Java.

ממשק ה-API לסריקה על פי דרישה מאפשר לסרוק תמונות שמאוחסנות באופן מקומי במחשב, או מרחוק ב-Container Registry או ב-Artifact Registry. כך תוכלו לשלוט באופן מדויק בקונטיינרים שבהם אתם רוצים לסרוק נקודות חולשה. אפשר להשתמש בסריקה על פי דרישה כדי לסרוק תמונות בצינור עיבוד הנתונים של CI/CD לפני שמחליטים אם לאחסן אותן במרשם.

מה תלמדו

בשיעור ה-Lab הזה תלמדו:

  • יצירת קובצי אימג' באמצעות Cloud Build
  • שימוש ב-Artifact Registry לקונטיינרים
  • שימוש בסריקה אוטומטית של נקודות חולשה
  • הגדרת סריקה על פי דרישה
  • הוספת סריקה של קובצי אימג' ב-CI/CD ב-Cloud Build

2. הגדרה ודרישות

הגדרת סביבה בקצב אישי

  1. נכנסים למסוף Google Cloud ויוצרים פרויקט חדש או משתמשים מחדש בפרויקט קיים. אם עדיין אין לכם חשבון Gmail או חשבון Google Workspace, עליכם ליצור חשבון.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • שם הפרויקט הוא השם המוצג של המשתתפים בפרויקט. זוהי מחרוזת תווים שלא משמשת את Google APIs. אפשר לעדכן את המיקום הזה בכל שלב.
  • מזהה הפרויקט הוא ייחודי לכל הפרויקטים ב-Google Cloud ואי אפשר לשנות אותו אחרי שמגדירים אותו. מסוף Cloud יוצר באופן אוטומטי מחרוזת ייחודית. בדרך כלל לא משנה מה המחרוזת הזו. ברוב ה-codelabs תצטרכו להפנות למזהה הפרויקט (בדרך כלל הוא מזוהה בתור PROJECT_ID). אם המזהה שנוצר לא מוצא חן בעיניכם, תוכלו ליצור מזהה אקראי אחר. לחלופין, אפשר לנסות שם משלכם ולבדוק אם הוא זמין. לא ניתן לשנות את השם אחרי השלב הזה, והוא יישאר למשך כל תקופת הפרויקט.
  • לידיעתכם, יש ערך שלישי, מספר פרויקט, שמשתמשים בו בחלק מממשקי ה-API. מידע נוסף על כל שלושת הערכים האלה זמין במסמכי העזרה.
  1. בשלב הבא, כדי להשתמש במשאבים או ב-API של Cloud, תצטרכו להפעיל את החיוב במסוף Cloud. השלמת הקודלאב הזה לא אמורה לעלות הרבה, אם בכלל. כדי להשבית את המשאבים ולמנוע חיובים אחרי סיום המדריך, אפשר למחוק את המשאבים שיצרתם או למחוק את הפרויקט כולו. משתמשים חדשים ב-Google Cloud זכאים להשתתף בתוכנית תקופת ניסיון בחינם בסך 300$.

הגדרת הסביבה

ב-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 

3. יצירת קובצי אימג' באמצעות Cloud Build

בקטע הזה תלמדו איך ליצור צינור עיבוד נתונים אוטומטי ל-build, שיוצר את קובץ האימג' בקונטיינר, סורק אותו ומעריך את התוצאות. אם לא יימצאו נקודות חולשה קריטיות, התמונה תועבר למאגר. אם יימצאו נקודות חולשה קריטיות, ה-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"

יצירה של ספריית עבודה ושינוי אליה

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

יצירת צינור עיבוד הנתונים של 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: ['-']


EOF

הפעלת צינור עיבוד הנתונים של CI

שליחת הגרסה היציבה לעיבוד

gcloud builds submit

בדיקת פרטי ה-Build

אחרי שתהליך ה-build יתחיל, תוכלו לבדוק את ההתקדמות בלוח הבקרה של Cloud Build.

  1. פותחים את Cloud Build במסוף Cloud
  2. לוחצים על הגרסה המאוחדת כדי להציג את התוכן

4. Artifact Registry לקונטיינרים

יצירת מאגר ב-Artifact Registry

בשיעור ה-Lab הזה נשתמש ב-Artifact Registry כדי לאחסן ולסרוק את התמונות. יוצרים את המאגר באמצעות הפקודה הבאה.

gcloud artifacts repositories create artifact-scanning-repo \
  --repository-format=docker \
  --location=us-central1 \
  --description="Docker repository"

מגדירים את Docker כך שישתמש בפרטי הכניסה שלכם ב-gcloud כשתיגשו ל-Artifact Registry.

gcloud auth configure-docker us-central1-docker.pkg.dev

עדכון צינור עיבוד הנתונים של Cloud Build

שינוי צינור עיבוד הנתונים ל-build כדי לדחוף את קובץ האימג' שנוצר ל-Artifact Registry

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: ['-']

# push 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']

images:
  - us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
EOF

הפעלת צינור עיבוד הנתונים של CI

שליחת ה-build לעיבוד

gcloud builds submit

5. בדיקת נקודות חולשה אוטומטית

הסריקה של הארטיפקטים מופעלת באופן אוטומטי בכל פעם שדוחפים קובץ אימג' חדש ל-Artifact Registry או ל-Container Registry. המידע על נקודות החולשה מתעדכן כל הזמן כשמתגלות נקודות חולשה חדשות. בקטע הזה נבדוק את התמונה שיצרתם והעברתם ל-Artifact Registry, ונבחן את תוצאות בדיקת נקודות החולשה.

בדיקת פרטי התמונה

אחרי שתהליך ה-build הקודם יושלם, בודקים את התוצאות של האימג' ושל נקודות החולשה בלוח הבקרה של Artifact Registry.

  1. פותחים את Artifact Registry במסוף Cloud
  2. לוחצים על artifact-scanning-repo כדי להציג את התוכן.
  3. לוחצים על פרטי התמונה.
  4. לוחצים על סיכום התמונה האחרון
  5. בסיום הסריקה, לוחצים על הכרטיסייה 'נקודות חולשה' של התמונה.

בכרטיסייה 'נקודות חולשה' יוצגו תוצאות הסריקה האוטומטית של התמונה שיצרתם.

361be7b3bf293fca.png

הסריקה האוטומטית מופעלת כברירת מחדל. כדאי לעיין בהגדרות של Artifact Registry כדי לראות איך אפשר להשבית או להפעיל את הסריקה האוטומטית.

6. סריקה על פי דרישה

יש תרחישים שונים שבהם ייתכן שתצטרכו לבצע סריקה לפני שתשלח את התמונה למאגר. לדוגמה, מפתח קונטיינרים יכול לסרוק קובץ אימג' ולתקן את הבעיות לפני שהוא דוחף את הקוד למערכת בקרת הגרסאות. בדוגמה הבאה נתאר איך יוצרים ומנתחים את התמונה באופן מקומי לפני שמבצעים פעולות על סמך התוצאות.

יצירת קובץ אימג'

בשלב הזה תשתמשו ב-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

7. סריקת CICD באמצעות Cloud 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 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

מריצים את תהליך ה-CI עם התמונה הטובה

שולחים את ה-build לעיבוד כדי לוודא שה-build יצליח אם לא יימצאו נקודות חולשה ברמת קריטיות.

gcloud builds submit

בדיקת הצלחת ה-build

ה-build ששלחת עכשיו יצליח כי קובץ האימג' המעודכן לא מכיל נקודות חולשה קריטיות.

בודקים את הצלחת ה-build בדף Cloud Build History

בדיקת תוצאות הסריקה

בדיקת קובץ האימג' תקין ב-Artifact Registry

  1. פותחים את Artifact Registry במסוף Cloud
  2. לוחצים על artifact-scanning-repo כדי להציג את התוכן.
  3. לוחצים על פרטי התמונה.
  4. לוחצים על סיכום התמונה האחרון
  5. לוחצים על הכרטיסייה 'נקודות חולשה' של התמונה.

8. מעולה!

כל הכבוד, סיימת את הקודלאב!

הנושאים שעסקנו בהם:

  • יצירת קובצי אימג' באמצעות Cloud Build
  • Artifact Registry לקונטיינרים
  • בדיקת נקודות חולשה אוטומטית
  • סריקה על פי דרישה
  • סריקת CICD באמצעות Cloud Build

השלב הבא:

הסרת המשאבים

כדי להימנע מחיובים בחשבון Google Cloud בגלל השימוש במשאבים שנעשה במסגרת המדריך הזה, אפשר למחוק את הפרויקט שמכיל את המשאבים, או להשאיר את הפרויקט ולמחוק את המשאבים הנפרדים.

מחיקת הפרויקט

הדרך הקלה ביותר לבטל את החיוב היא למחוק את הפרויקט שיצרתם בשביל המדריך.

תאריך העדכון האחרון: 21 במרץ 2023