לפני שאפליקציה שולחת מידע רגיש למכונה וירטואלית (VM), היא יכולה לאמת את הזהות של המכונה באמצעות אסימוני זהות של מכונות שנחתמו על ידי Google. לכל מכונה יש אסימון JWT (JSON Web Token) ייחודי שכולל פרטים על המכונה וגם את חתימת RS256 של Google. האפליקציות שלכם יכולות לאמת את החתימה באמצעות אישורי Oauth2 ציבוריים של Google כדי לוודא את הזהות של המופע שאליו הן מתחברות.
מערכת Compute Engine יוצרת אסימונים חתומים של מכונות רק כשמכונה מבקשת אותם ממטא-נתונים של מכונה. המכונות יכולות לגשת רק לאסימון הייחודי שלהן, ולא לאסימונים של מכונות אחרות.
כדאי לאמת את הזהויות של המופעים בתרחישים הבאים:
- כשמפעילים מופע בפעם הראשונה, יכול להיות שהאפליקציות יצטרכו לוודא שלמופע שאליו הן מתחברות יש זהות תקפה לפני שהן מעבירות אליו מידע רגיש.
- כאשר דרישות המדיניות שלכם מחייבות אתכם לאחסן את פרטי הכניסה מחוץ לסביבת Compute Engine, ואתם שולחים את פרטי הכניסה האלה באופן קבוע למופעים לשימוש זמני. האפליקציות שלכם יכולות לאמת את הזהויות של המכונות בכל פעם שהן צריכות להעביר פרטי כניסה.
לשיטות האימות של Google למופעים יש את היתרונות הבאים:
- בכל פעם שמכונה מבקשת אסימון, Compute Engine יוצר אסימון ייחודי שתוקפו פג תוך שעה. אתם יכולים להגדיר את האפליקציות כך שיקבלו את טוקן הזהות של מופע רק פעם אחת, וכך להקטין את הסיכון שמערכת לא מורשית תוכל לעשות שימוש חוזר בטוקן.
- אסימוני מטא-נתונים חתומים מבוססים על תקן התעשייה הפתוח RFC 7519 ועל שכבת הזהות OpenID Connect 1.0, כך שכלי וספריות קיימים יפעלו בצורה חלקה עם אסימוני הזהות.
לפני שמתחילים
- איך מאחזרים ערכים של מטא-נתונים של מכונות
- כדאי להבין את היסודות של טוקנים של JSON Web כדי לדעת איך להשתמש בהם באפליקציות שלכם.
- איך יוצרים ומפעילים חשבונות שירות במכונות. למופעים צריך להיות משויך חשבון שירות כדי שהם יוכלו לאחזר את אסימוני הזהות שלהם. חשבון השירות לא צריך הרשאות IAM כדי לאחזר את אסימוני הזהות האלה.
-
אם עדיין לא עשיתם את זה, תצטרכו להגדיר אימות.
אימות הוא התהליך שבו מאמתים את הזהות שלכם כדי לקבל גישה לממשקי API ולשירותים של Google Cloud . כדי להריץ קוד או דוגמאות מסביבת פיתוח מקומית, אפשר לבצע אימות ל-Compute Engine באחת מהדרכים הבאות:
כדי להשתמש בסביבת פיתוח מקומית בדוגמאות של Python שבדף הזה, מתקינים ומפעילים את ה-CLI של gcloud, ואז מגדירים את Application Default Credentials באמצעות פרטי הכניסה של המשתמש.
-
התקינו את ה-CLI של Google Cloud.
-
אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.
-
אם אתם משתמשים במעטפת מקומית, צרו פרטי כניסה לאימות מקומי בחשבון המשתמש:
gcloud auth application-default login
אם אתם משתמשים ב-Cloud Shell, אתם לא צריכים לעשות את זה.
אם מוחזרת שגיאת אימות ואתם משתמשים בספק זהויות חיצוני (IdP), ודאו ש נכנסתם ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.
מידע נוסף זמין במאמר הגדרת אימות לסביבת פיתוח מקומית.
-
אימות הזהות של מכונה
במקרים מסוימים, האפליקציות צריכות לאמת את הזהות של מופע שפועל ב-Compute Engine לפני שהן מעבירות אליו נתונים רגישים. בדוגמה אופיינית אחת, יש מערכת אחת שפועלת מחוץ ל-Compute Engine שנקראת Host1 ומכונה ב-Compute Engine שנקראת VM1. המכונה הווירטואלית VM1 יכולה להתחבר למארח Host1 ולאמת את הזהות של המופע הזה באמצעות התהליך הבא:
VM1 יוצר חיבור מאובטח ל-Host1 באמצעות פרוטוקול חיבור מאובטח לבחירתכם, כמו HTTPS.
VM1 מבקש את אסימון הזהות הייחודי שלו משרת המטא-נתונים ומציין את הקהל של האסימון. בדוגמה הזו, ערך הקהל הוא ה-URI של Host1. הבקשה לשרת המטא-נתונים כוללת את ה-URI של קהל היעד, כדי שמארח 1 יוכל לבדוק את הערך מאוחר יותר במהלך שלב אימות הטוקן.
Google יוצרת אסימון חדש של זהות מופע ייחודי בפורמט JWT ומספקת אותו למכונה וירטואלית 1. המטען הייעודי (payload) של האסימון כולל כמה פרטים על המכונה וגם את ה-URI של הקהל. תיאור מלא של תוכן האסימון מופיע במאמר תוכן האסימון.
VM1 שולחת את אסימון הזהות ל-Host1 דרך החיבור המאובטח הקיים.
Host1 מפענח את אסימון הזהות כדי לקבל את ערכי הכותרת והמטען הייעודי (payload) של האסימון.
מארח 1 מאמת שהאסימון נחתם על ידי Google על ידי בדיקת ערך הקהל ואימות חתימת האישור מול האישור הציבורי של Google.
אם האסימון תקף, המארח Host1 ממשיך בהעברה וסוגר את החיבור כשהוא מסתיים. Host1 ומערכות אחרות צריכות לבקש אסימון חדש לכל החיבורים הבאים ל-VM1.
קבלת אסימון זהות של המכונה
כשמופנית למכונה וירטואלית בקשה לספק את אסימון הזהות שלה, המכונה מבקשת את האסימון משרת המטא-נתונים באמצעות התהליך הרגיל של קבלת מטא-נתונים של מכונה. לדוגמה, אפשר להשתמש באחת מהשיטות הבאות:
cURL
יוצרים בקשת curl וכוללים ערך בפרמטר audience.
אפשר גם לכלול את הפרמטר format כדי לציין אם רוצים לכלול פרטים על הפרויקט והמופע במטען הייעודי (payload). אם משתמשים בפורמט full, אפשר לכלול את הפרמטר licenses כדי לציין אם רוצים לכלול קודי רישיון במטען הייעודי (payload).
curl -H "Metadata-Flavor: Google" \ 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=AUDIENCE&format=FORMAT&licenses=LICENSES'
מחליפים את מה שכתוב בשדות הבאים:
-
AUDIENCE: ה-URI הייחודי שמוסכם על המכונה ועל המערכת שמאמתת את זהות המכונה. לדוגמה, הקהל יכול להיות כתובת URL של החיבור בין שתי המערכות. -
FORMAT: פרמטר אופציונלי שמציין אם פרטי הפרויקט והמכונה כלולים במטען הייעודי (payload). מצייניםfullכדי לכלול את המידע הזה במטען הייעודי (payload), אוstandardכדי להשמיט את המידע מהמטען הייעודי. ערך ברירת המחדל הואstandard. מידע נוסף זמין במאמר פורמט של אסימון זהות. -
LICENSES: פרמטר אופציונלי שמציין אם קודי הרישיון של התמונות שמשויכות למופע הזה כלולים במטען הייעודי (payload). מצייניםTRUEכדי לכלול את המידע הזה אוFALSEכדי להשמיט את המידע הזה ממטען הייעודי. ערך ברירת המחדל הואFALSE. אין השפעה אלא אםformatהואfull
שרת המטא-נתונים מגיב לבקשה הזו עם JSON Web Token (אסימון אינטרנט בפורמט JSON) שחתום באמצעות האלגוריתם RS256. האסימון כולל חתימה של Google ומידע נוסף במטען הייעודי (payload). אפשר לשלוח את האסימון הזה למערכות ולאפליקציות אחרות כדי שהן יוכלו לאמת את האסימון ולאשר את הזהות של המופע שלכם.
Python
אפשר לשלוח בקשה פשוטה מהמופע לשרת המטא-נתונים באמצעות שיטות בספריית Python requests. בדוגמה הבאה מוצגת בקשה לאסימון זהות של מכונה והדפסה שלו. הטוקן ייחודי למופע ששולח את הבקשה הזו.
שרת המטא-נתונים מגיב לבקשה הזו עם JSON Web Token (אסימון אינטרנט בפורמט JSON) שחתום באמצעות האלגוריתם RS256. האסימון כולל חתימה של Google ומידע נוסף במטען הייעודי (payload). אפשר לשלוח את האסימון הזה למערכות ולאפליקציות אחרות כדי שהן יוכלו לאמת את האסימון ולאשר את הזהות של המופע שלכם.
אימות הטוקן
אחרי שהאפליקציה מקבלת טוקן של זהות מופע ממכונת VM ב-Compute Engine, היא יכולה לאמת את הטוקן באמצעות התהליך הבא.
מקבלים את האסימון מהמכונה הווירטואלית, מפענחים את האסימון באמצעות מפענח JWT מסוג RS256 וקוראים את תוכן הכותרת כדי לקבל את הערך
kid.מוודאים שהאסימון חתום על ידי בדיקת האסימון מול האישור הציבורי של Google. לכל אישור ציבורי יש ערך
kidשמתאים לערךkidבכותרת של האסימון.אם האסימון תקף, משווים את תוכן המטען הייעודי (payload) לערכים הצפויים. אם מטען הייעודי (payload) של האסימון כולל פרטים על המופע והפרויקט, האפליקציה יכולה לבדוק את הערכים
instance_id,project_idו-zone. הערכים האלה הם טאפל ייחודי גלובלית שמאשר שהאפליקציה שלכם מתקשרת עם המופע הנכון בפרויקט הרצוי.
אפשר לפענח ולאמת את הטוקן באמצעות כל כלי שרוצים, אבל שיטה נפוצה היא להשתמש בספריות של השפה שבחרתם. לדוגמה, אתם יכולים להשתמש ב-method verify_token מספריית Google OAuth 2.0 ל-Python. השיטה verify_token מתאימה את הערך kid לאישור המתאים, מאמתת את החתימה, בודקת את טענת הקהל ומחזירה את תוכן המטען הייעודי (payload) מהטוקן.
אחרי שהאפליקציה מאמתת את הטוקן ואת התוכן שלו, היא יכולה להמשיך לתקשר עם המופע הזה באמצעות חיבור מאובטח, ואז לסגור את החיבור כשהיא מסיימת. לחיבורים הבאים, צריך לבקש טוקן חדש מהמופע ולאמת מחדש את הזהות של המופע.
תוכן הטוקן
אסימון הזהות של המופע מכיל שלושה חלקים עיקריים:
כותרת
הכותרת כוללת את הערך kid כדי לזהות באילו אישורי OAuth2 ציבוריים צריך להשתמש כדי לאמת את החתימה. הכותרת כוללת גם את הערך alg כדי לאשר שהחתימה נוצרה באמצעות אלגוריתם RS256.
{
"alg": "RS256",
"kid": "511a3e85d2452aee960ed557e2666a8c5cedd8ae",
}
Payload
המטען הייעודי (payload) מכיל את טענת הקהל aud. אם המופע צוין format=full כשנשלחה הבקשה לאסימון, מטען הייעודי (payload) כולל גם הצהרות לגבי מופע המכונה הווירטואלית והפרויקט שלה.
כשמבקשים אסימון בפורמט מלא, ציון licenses=TRUE יכלול גם הצהרות לגבי הרישיונות שמשויכים למכונה.
{
"iss": "[TOKEN_ISSUER]",
"iat": [ISSUED_TIME],
"exp": [EXPIRED_TIME],
"aud": "[AUDIENCE]",
"sub": "[SUBJECT]",
"azp": "[AUTHORIZED_PARTY]",
"email": "[EMAIL]",
"email_verified": "[EMAIL_VERIFIED]",
"google": {
"compute_engine": {
"project_id": "[PROJECT_ID]",
"project_number": [PROJECT_NUMBER],
"zone": "[ZONE]",
"instance_id": "[INSTANCE_ID]",
"instance_name": "[INSTANCE_NAME]",
"instance_creation_timestamp": [CREATION_TIMESTAMP],
"instance_confidentiality": [INSTANCE_CONFIDENTIALITY],
"license_id": [
"[LICENSE_1]",
...
"[LICENSE_N]"
]
}
}
}
כאשר:
-
[TOKEN_ISSUER]: כתובת URL שמזהה את הגורם שהנפיק את האסימון. ב-Compute Engine, הערך הזה הואhttps://accounts.google.com. -
[ISSUED_TIME]: חותמת זמן של מערכת Unix שמציינת מתי הונפק האסימון. הערך הזה מתעדכן בכל פעם שהמכונה מבקשת אסימון משרת המטא-נתונים. [EXPIRED_TIME]: חותמת זמן של מערכת Unix שמציינת מתי יפוג תוקף האסימון.-
[AUDIENCE]: מזהה משאבים אחיד (URI) ייחודי שמוסכם על המופע ועל המערכת שמאמתת את זהות המופע. לדוגמה, הקהל יכול להיות כתובת URL לחיבור בין שתי המערכות. -
[SUBJECT]: הנושא של האסימון, שהוא המזהה הייחודי של חשבון השירות ששייכתם למופע. -
[AUTHORIZED_PARTY]: הצד שאליו הונפק טוקן של מזהה, שהוא המזהה הייחודי של חשבון השירות ששייכתם למכונה. [EMAIL]: כתובת האימייל של חשבון השירות שמשויך למופע.-
[EMAIL_VERIFIED]:trueאם כתובת האימייל של חשבון השירות אומתה. -
[PROJECT_ID]: המזהה של הפרויקט שבו יצרתם את המופע. -
[PROJECT_NUMBER]: המספר הייחודי של הפרויקט שבו יצרתם את המופע. -
[ZONE]: האזור שבו נמצאת המכונה. -
[INSTANCE_ID]: המזהה הייחודי של המופע שאליו משויך האסימון הזה. המזהה הזה ייחודי בתוך הפרויקט והתחום. -
[INSTANCE_NAME]: השם של המכונה שאליה שייך האסימון. אם בפרויקט שלכם נעשה שימוש ב-DNS אזורי, אפשר להשתמש בשם הזה שוב באזורים שונים, ולכן צריך להשתמש בשילוב של הערכיםproject_id,zoneו-instance_idכדי לזהות מזהה מכונה ייחודי. בפרויקטים שבהם מופעל DNS גלובלי, לכל מכונה יש שם ייחודי בפרויקט. -
[CREATION_TIMESTAMP]: חותמת זמן של מערכת Unix שמציינת מתי יצרתם את המופע. -
[INSTANCE_CONFIDENTIALITY]: הערך1אם המכונה היא מכונה וירטואלית (VM) חסויה. -
[LICENSE_1]עד[LICENSE_N]: קודי הרישיון של התמונות שמשויכות למכונה הזו.
המטען הייעודי (payload) עשוי להיראות כמו בדוגמה הבאה:
{
"iss": "https://accounts.google.com",
"iat": 1496953245,
"exp": 1496956845,
"aud": "https://www.example.com",
"sub": "107517467455664443765",
"azp": "107517467455664443765",
"email": "739419398126-compute@developer.gserviceaccount.com",
"email_verified": true,
"google": {
"compute_engine": {
"project_id": "my-project",
"project_number": 739419398126,
"zone": "us-west1-a",
"instance_id": "152986662232938449",
"instance_name": "example",
"instance_creation_timestamp": 1496952205,
"instance_confidentiality": 1,
"license_id": [
"1000204"
]
}
}
}
חתימה
Google יוצרת את החתימה על ידי קידוד Base64URL של הכותרת ושל המטען הייעודי (payload), ושרשור שני הערכים. כדי לאמת את האסימון, אפשר להשוות את הערך הזה לאישורים ציבוריים של Oauth2.
המאמרים הבאים
- כדאי לעיין ב-Google Cloud Well-Architected Framework.
- אימות של עומסי עבודה לעומסי עבודה אחרים באמצעות mTLS.