במאמר הזה מתוארים אמצעי מניעה ותגובות נפוצים לאירועי אבטחה פוטנציאליים באשכולות ובקונטיינרים של Google Kubernetes Engine (GKE).
המסמך הזה מיועד למומחי אבטחה שמחפשים הנחיות לתגובה לאירועי אבטחה ב-GKE. כדי לקבל מידע נוסף על תפקידים נפוצים ועל משימות לדוגמה שאנחנו מתייחסים אליהן ב Google Cloud תוכן, אפשר לעיין במאמר תפקידים נפוצים של משתמשי GKE ומשימות.
ההצעות במאמר הקשחת האבטחה באשכול יכולות לשפר את האבטחה של עומסי העבודה ב-GKE. עם זאת, אירועי אבטחה יכולים לקרות גם כשמיושמים אמצעים להגנה על עומסי העבודה.
זיהוי אירועים
כדי לזהות אירועים פוטנציאליים, מומלץ להגדיר תהליך לאיסוף ולמעקב אחרי היומנים של עומס העבודה. לאחר מכן, מגדירים התראות על סמך אירועים חריגים שזוהו ביומנים. התראות מודיעות לצוות האבטחה שלכם כשמזוהה משהו חריג. צוות האבטחה שלכם יכול לבדוק את האירוע הפוטנציאלי.
אפשר להתאים אישית את ההתראות על סמך מדדים או פעולות ספציפיים. לדוגמה, התראות על שימוש גבוה במעבד בצמתי GKE עשויות להצביע על כך שהם נפרצו לצורך כריית מטבעות קריפטוגרפיים.
ההתראות צריכות להיווצר במקום שבו אתם מסכמים את היומנים והמדדים. לדוגמה, אפשר להשתמש ביומני ביקורת של GKE בשילוב עם התראות שמבוססות על יומנים ב-Cloud Logging.
מידע נוסף על שאילתות שקשורות לאבטחה זמין במאמר בנושא יומני ביקורת.
תגובה לאירוע אבטחה
אחרי שמתקבלת התראה על אירוע, צריך לפעול. אם אפשר, כדאי לתקן את נקודת החולשה. אם אינכם יודעים מהו שורש הבעיה של נקודת החולשה או שאין לכם תיקון מוכן, החילו אמצעי צמצום.
הפעולות שתוכלו לבצע תלויות בחומרת האירוע ובמידת הוודאות שלכם לגבי זיהוי הבעיה.
במדריך הזה מוסבר על פעולות שאפשר לבצע אחרי שמזהים אירוע בעומס עבודה שפועל ב-GKE. יכול להיות שתוכלו, בסדר עולה של חומרת הבעיה:
- יוצרים תמונת מצב של הדיסק של המכונה הווירטואלית המארחת. תמונת מצב מאפשרת לבצע פורנזיקה דיגיטלית של מצב ה-VM בזמן החריגה, אחרי שעומס העבודה נפרס מחדש או נמחק.
בדיקת המכונה הווירטואלית בזמן שהעומס ממשיך לפעול. התחברות למכונת ה-VM המארחת או למאגר של עומס העבודה יכולה לספק מידע על הפעולות של התוקף. מומלץ לצמצם את הגישה לפני שבודקים את המכונה הווירטואלית הפעילה.
פריסה מחדש של מאגר תגים. פריסה מחדש מסיימת תהליכים שפועלים כרגע בקונטיינר המושפע ומפעילה אותם מחדש.
מחיקת עומס עבודה מחיקת עומס העבודה מסיימת את התהליכים שפועלים כרגע במאגר המושפע בלי הפעלה מחדש.
המיטיגציות האלה מתוארות בקטעים הבאים.
לפני שמתחילים
השיטות שמתוארות בנושא הזה משתמשות במידע הבא:
- השם של הפודים שלדעתך נפרצו, או
POD_NAME. - השם של המכונה הווירטואלית המארחת שמריצה את הקונטיינר או את ה-Pods, או
NODE_NAME.
בנוסף, לפני שמבצעים פעולה כלשהי, כדאי לשקול אם התגובה של התוקף תהיה שלילית אם הוא יגלה שזיהו אותו. יכול להיות שהתוקף יחליט למחוק נתונים או להרוס עומסי עבודה. אם הסיכון גבוה מדי, כדאי לשקול אמצעי צמצום סיכונים קיצוניים יותר, כמו מחיקת עומס עבודה לפני שמבצעים חקירה נוספת.
יצירת snapshot של הדיסק של ה-VM
יצירת תמונת מצב של הדיסק של המכונה הווירטואלית מאפשרת לבצע חקירה משפטית אחרי פריסה מחדש או מחיקה של עומס העבודה. אפשר ליצור תמונות מצב בזמן שהדיסקים מצורפים למופעים פעילים.
כדי ליצור תמונת מצב של דיסק אחסון מתמיד, קודם צריך למצוא את הדיסקים שמצורפים למכונת ה-VM. מריצים את הפקודה הבאה ומסתכלים על השדה
source:gcloud compute instances describe NODE_NAME --zone COMPUTE_ZONE \ --format="flattened([disks])"חפשו את השורות שמכילות את
disks[NUMBER].source. הפלט אמור להיראות כך:disks[0].source: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/zones/COMPUTE_ZONE/disks/DISK_NAMEשם הדיסק הוא החלק של שם המקור אחרי הסלאש האחרון. לדוגמה, שם הדיסק הוא
gke-cluster-pool-1-abcdeffff-zgt8.כדי להשלים את יצירת התמונה, מריצים את הפקודה הבאה:
gcloud compute disks snapshot DISK_NAME
מידע נוסף זמין במאמר בנושא יצירת תמונות מצב של דיסקי אחסון מתמידים במסמכי התיעוד של Compute Engine.
בדיקת המכונה הווירטואלית
לפני שמבצעים פעולה, כדאי לחשוב איזו גישה יכולה להיות לתוקף. אם יש לכם חשד שפריצה בוצעה לקונטיינר ואתם חוששים ליידע את התוקף, אתם יכולים להתחבר לקונטיינר ולבדוק אותו בלי לשבש את עומסי העבודה. הבדיקה שימושית לחקירה מהירה לפני ביצוע פעולות שעלולות לשבש את הפעילות. בדיקה היא גם הגישה הכי פחות משבשת לעומס העבודה, אבל היא לא עוצרת את האירוע.
לחלופין, כדי להימנע מרישום ביומן למחשב עם הרשאות מיוחדות, אפשר לנתח את עומסי העבודה באמצעות הגדרת פורנזיקה דיגיטלית בזמן אמת (כמו GRR Rapid Response), סוכנים בצמתים או סינון רשת.
צמצום הגישה לפני בדיקת המכונה הווירטואלית הפעילה
באמצעות cordoning, draining והגבלת הגישה לרשת למכונה הווירטואלית שמארחת קונטיינר שנפרץ, אפשר לבודד את הקונטיינר שנפרץ באופן חלקי משאר האשכול. הגבלת הגישה ל-VM מצמצמת את הסיכון, אבל לא מונעת מתוקף לנוע לרוחב בסביבה שלכם אם הוא מנצל נקודת חולשה קריטית.
הגבלת הגישה לצומת והעברת עומסי העבודה האחרים ממנו
הגבלת גישה לצומת והפסקת הפעילות שלו מעבירות עומסי עבודה שמוצבים יחד עם הקונטיינר שנפרץ למכונות וירטואליות אחרות באשכול. הגבלת הגישה וניקוי הנתונים מצמצמים את היכולת של התוקף להשפיע על עומסי עבודה אחרים באותו צומת. היא לא בהכרח מונעת מהם לבדוק את המצב המתמשך של עומס עבודה (לדוגמה, על ידי בדיקת התוכן של קובץ אימג' של קונטיינר).
משתמשים בפקודה
kubectlכדי לתחום את הצומת ולוודא שלא מתוזמנים בו פודים אחרים:kubectl cordon NODE_NAMEאחרי שמגדירים את הצומת כ-cordoned, מרוקנים את הצומת מ-Pods אחרים.
נותנים תווית ל-Pod שמועבר להסגר:
kubectl label pods POD_NAME quarantine=trueמחליפים את
POD_NAMEבשם של ה-Pod שרוצים להכניס להסגר.מרוקנים את הצומת מ-Pods שלא מסומנים בתווית
quarantine:kubectl drain NODE_NAME --pod-selector='!quarantine'
הגבלת הגישה לרשת לצומת
מומלץ לחסום את הגישה למכונה הווירטואלית של המארח לתנועה פנימית וחיצונית. לאחר מכן, מאפשרים חיבורים נכנסים ממכונה וירטואלית ספציפית ברשת או ב-VPC לחיבור למכונה הווירטואלית שהוכנסה להסגר.
השלב הראשון הוא להוציא את המכונה הווירטואלית מקבוצת מופעי מכונה מנוהלים שבבעלותה. אם תפסיקו את השימוש במכונה הווירטואלית, הצומת לא יסומן כלא תקין ולא יתוקן אוטומטית (ייווצר מחדש) לפני שתסיימו את הבדיקה.
כדי לבטל את מכונת ה-VM, מריצים את הפקודה הבאה:
gcloud compute instance-groups managed abandon-instances INSTANCE_GROUP_NAME \
--instances=NODE_NAME
חומת אש של מכונת ה-VM
יצירת חומת אש בין הקונטיינר המושפע לבין עומסי עבודה אחרים באותה רשת עוזרת למנוע מהתוקף לעבור לחלקים אחרים בסביבה שלכם בזמן שאתם מבצעים ניתוח נוסף. מכיוון שהוצאתם כבר את כל הקונטיינרים האחרים מהמכונה הווירטואלית, הפעולה הזו משפיעה רק על הקונטיינר שהוכנס להסגר.
ההוראות הבאות לגבי חומת אש ב-VM מונעות:
- חיבורים חדשים יוצאים למכונות וירטואליות אחרות באשכול באמצעות כלל תעבורת נתונים יוצאת (egress).
- חיבורים נכנסים למכונה הווירטואלית שנפרצה באמצעות כלל כניסה.
כדי להגדיר חומת אש למכונת ה-VM כך שלא תהיה לה גישה למופעים אחרים, צריך לבצע את השלבים הבאים עבור הצומת שמארח את ה-Pod שרוצים להכניס להסגר:
מתייגים את המופע כדי שתוכלו להחיל כלל חדש של חומת אש.
gcloud compute instances add-tags NODE_NAME \ --zone COMPUTE_ZONE \ --tags quarantineיוצרים כלל חומת אש שדוחה את כל תעבורת הנתונים היוצאת מסוג TCP מהמכונות עם התג
quarantine:gcloud compute firewall-rules create quarantine-egress-deny \ --network NETWORK_NAME \ --action deny \ --direction egress \ --rules tcp \ --destination-ranges 0.0.0.0/0 \ --priority 0 \ --target-tags quarantineיוצרים כלל חומת אש שדוחה את כל תעבורת הנתונים הנכנסת (ingress) מסוג TCP אל מכונות עם התג
quarantine. נותנים לכלל הכניסה הזה את הערךpriorityשל1, כדי שתוכלו לבטל אותו באמצעות כלל אחר שמאפשר SSH ממכונה וירטואלית ספציפית.gcloud compute firewall-rules create quarantine-ingress-deny \ --network NETWORK_NAME \ --action deny \ --direction ingress \ --rules tcp \ --source-ranges 0.0.0.0/0 \ --priority 1 \ --target-tags quarantine
הסרת כתובת ה-IP החיצונית של המכונה הווירטואלית
הסרת כתובת ה-IP החיצונית של המכונה הווירטואלית תנתק את כל החיבורים הקיימים לרשת מחוץ ל-VPC.
כדי להסיר את הכתובת החיצונית של מכונה וירטואלית, מבצעים את השלבים הבאים:
מאתרים ומוחקים את הגדרת הגישה שמקשרת את כתובת ה-IP החיצונית למכונה הווירטואלית. קודם כל, מתארים את המכונה הווירטואלית כדי למצוא את הגדרת הגישה:
gcloud compute instances describe NODE_NAME \ --zone COMPUTE_ZONE --format="flattened([networkInterfaces])"חפשו את השורות שמכילות את התווים
nameו-natIP. הן נראות כך:networkInterfaces[0].accessConfigs[0].name: ACCESS_CONFIG_NAME networkInterfaces[0].accessConfigs[0].natIP: EXTERNAL_IP_ADDRESSמוצאים את הערך של
natIPשמתאים לכתובת ה-IP החיצונית שרוצים להסיר. רושמים את השם של הגדרת הגישה.כדי להסיר את כתובת ה-IP החיצונית, מריצים את הפקודה הבאה:
gcloud compute instances delete-access-config NODE_NAME \ --access-config-name "ACCESS_CONFIG_NAME"
התחברות ב-SSH למכונה הווירטואלית המארחת דרך מכונה וירטואלית ביניים
אחרי שמסירים את כתובת ה-IP החיצונית של המכונה הווירטואלית המארחת, אי אפשר להשתמש ב-SSH מחוץ ל-VPC. אתם ניגשים אליו ממכונה וירטואלית אחרת באותה רשת. בהמשך הקטע הזה, נתייחס ל-VM הזה כאל מכונה וירטואלית ביניים.
דרישות מוקדמות
- מכונה וירטואלית ביניים עם גישה לרשת המשנה של המכונה הווירטואלית המארחת. אם עדיין אין לכם מכונה וירטואלית, צריך ליצור אחת למטרה הזו.
- כתובת ה-IP הפנימית של המכונה הווירטואלית המתווכת.
- מפתח ציבורי SSH ממכונת ה-VM המתווכת. מידע נוסף זמין במאמר ניהול מפתחות SSH.
התחברות למכונת ה-VM המארחת
- מוסיפים את המפתח הציבורי של מכונת ה-VM הביניים למכונת ה-VM המארחת. מידע נוסף זמין במאמר הוספה והסרה של מפתחות SSH במאמרי העזרה של Compute Engine.
מוסיפים תג למכונה הווירטואלית של הביניים.
gcloud compute instances add-tags INTERMEDIATE_NODE_NAME \ --zone COMPUTE_ZONE \ --tags intermediateמוסיפים כלל הרשאה לכניסה כדי לשנות את כלל הדחייה שהוספתם קודם. כדי להוסיף את הכלל, מריצים את הפקודה הבאה.
gcloud compute firewall-rules create quarantine-ingress-allow \ --network NETWORK_NAME \ --action allow \ --direction ingress \ --rules tcp:22 \ --source-tags intermediate \ --priority 0 \ --target-tags quarantineהכלל הזה מאפשר תנועה נכנסת ביציאה 22 (SSH) ממכונות וירטואליות ברשת עם התג
intermediate. היא מבטלת את כלל הדחייה עםpriorityשל0.מתחברים למכונה הווירטואלית שהוכנסה להסגר באמצעות כתובת ה-IP הפנימית שלה:
ssh -i KEY_PATH USER@QUARANTINED_VM_INTERNAL_IPמחליפים את מה שכתוב בשדות הבאים:
-
KEY_PATH: הנתיב למפתח ה-SSH הפרטי. -
USER: כתובת האימייל של חשבון Google Cloud שלכם. -
QUARANTINED_VM_INTERNAL_IP: כתובת ה-IP הפנימית.
-
פריסה מחדש של מאגר תגים
כשפורסים מחדש את מאגר התגים, מתחילים עם עותק חדש של מאגר התגים ומוחקים את מאגר התגים שנפרץ.
כדי לפרוס מחדש מאגר, צריך למחוק את ה-Pod שמארח אותו. אם ה-Pod מנוהל על ידי מבנה Kubernetes ברמה גבוהה יותר (לדוגמה, Deployment או DaemonSet), מחיקת ה-Pod מתזמנת Pod חדש. ה-Pod הזה מפעיל קונטיינרים חדשים.
פריסה מחדש הגיונית במקרים הבאים:
- אתם כבר יודעים מה הגורם לפגיעות.
- לדעתכם, תוקף יצטרך להשקיע מאמץ רב או זמן רב כדי לפרוץ שוב למאגר התגים שלכם.
- אתם חושבים שהמאגר עלול להיפרץ שוב במהירות ואתם לא רוצים להעביר אותו למצב אופליין, ולכן אתם מתכננים להעביר אותו לארגז חול כדי להגביל את ההשפעה.
כשפורסים מחדש את עומס העבודה, אם יש סיכוי גבוה לפשרה נוספת, כדאי למקם את עומס העבודה בסביבת ארגז חול כמו GKE Sandbox. הרצה בארגז חול מגבילה את הגישה לליבת צומת המארח אם התוקף פוגע שוב בקונטיינר.
כדי לפרוס מחדש קונטיינר ב-Kubernetes, צריך למחוק את ה-Pod שמכיל אותו:
kubectl delete pods POD_NAME --grace-period=10
אם הקונטיינרים ב-Pod שנמחק ממשיכים לפעול, אפשר למחוק את עומס העבודה.
כדי לפרוס מחדש את הקונטיינר בארגז חול, פועלים לפי ההוראות במאמר הגברת הבידוד של עומסי עבודה באמצעות GKE Sandbox.
מחיקת עומס עבודה
אם מוחקים עומס עבודה, כמו Deployment או DaemonSet, כל ה-Pods ששייכים לו נמחקים. כל מאגרי התגים ב-Pods האלה מפסיקים לפעול. מחיקת עומס עבודה יכולה להיות הגיונית במקרים הבאים:
- רוצים להפסיק מתקפה שמתרחשת כרגע.
- אתם מוכנים להעביר את עומס העבודה למצב אופליין.
- הפסקת המתקפה באופן מיידי חשובה יותר מזמינות האפליקציה או מניתוח משפטי.
כדי למחוק עומס עבודה, משתמשים ב-kubectl delete CONTROLLER_TYPE.
לדוגמה, כדי למחוק פריסה, מריצים את הפקודה הבאה:
kubectl delete deployments DEPLOYMENT
אם מחיקת עומס העבודה לא מוחקת את כל ה-Pods או הקונטיינרים המשויכים, אפשר למחוק את הקונטיינרים באופן ידני באמצעות crictl, כלי ה-CLI של זמן הריצה של הקונטיינר.
אפשר להפסיק או להסיר קונטיינרים באמצעות crictl.
כדי לעצור קונטיינר ב-containerd, מריצים את הפקודה הבאה:
crictl stop CONTAINER
כדי להסיר מאגר ב-containerd, מריצים את הפקודה הבאה:
crictl rm -f CONTAINER
מחיקת מכונת ה-VM המארחת
.אם אין לכם אפשרות למחוק או להסיר את הקונטיינר, אתם יכולים למחוק את המכונה הווירטואלית שמארחת את הקונטיינר המושפע.
אם ה-Pod עדיין גלוי, אפשר למצוא את השם של המכונה הווירטואלית המארחת באמצעות הפקודה הבאה:
kubectl get pods --all-namespaces \
-o=custom-columns=POD_NAME:.metadata.name,INSTANCE_NAME:.spec.nodeName \
--field-selector=metadata.name=POD_NAME
כדי למחוק את מכונת ה-VM המארחת, מריצים את הפקודה gcloud הבאה:
gcloud compute instance-groups managed delete-instances INSTANCE_GROUP_NAME \
--instances=NODE_NAME
הפסקת השימוש במופע מקבוצת המופעים המנוהלים מקטינה את גודל הקבוצה במכונה וירטואלית אחת. אפשר להוסיף מופע אחד בחזרה לקבוצה באופן ידני באמצעות הפקודה הבאה:
gcloud compute instance-groups managed resize INSTANCE_GROUP_NAME \
--size=SIZE