סקירה כללית של מדיניות ההרשאות
בניגוד לאפליקציה מונוליתית שפועלת במקום אחד, אפליקציות של מיקרו-שירותים שמופצות באופן גלובלי מבצעות קריאות חוצות-רשת. זה אומר שיש יותר נקודות כניסה לאפליקציות, ויותר הזדמנויות להתקפות זדוניות. בנוסף, מכיוון של-Kubernetes pods יש כתובות IP זמניות, כללי חומת אש רגילים שמבוססים על כתובות IP לא מספיקים כדי לאבטח את הגישה בין עומסי העבודה. בארכיטקטורת מיקרו-שירותים, נדרשת גישה חדשה לאבטחה. בנוסף לתכונות האבטחה כמו חשבונות שירות של Kubernetes וכללי מדיניות האבטחה של Istio, ב-Cloud Service Mesh יש יכולות נוספות שיעזרו לכם לאבטח את האפליקציות.
בדף הזה מופיעה סקירה כללית על AuthorizationPolicy (משאב בהתאמה אישית) למפעילי אפליקציות. כללי מדיניות הרשאה מאפשרים לכם להפעיל בקרת גישה על עומסי עבודה בשכבות האפליקציה (L7) והתעבורה (L3/4). מגדירים כללי מדיניות הרשאה כדי לציין הרשאות – מה מותר לשירות או למשתמש לעשות?
מדיניות הרשאות
כברירת מחדל, מותר לשלוח בקשות בין שירותים ברשת (ובין משתמשי קצה לשירותים). משתמשים ב-CR של AuthorizationPolicy כדי להגדיר מדיניות מפורטת לעומסי העבודה. אחרי שמחילים את כללי מדיניות ההרשאה, Cloud Service Mesh מפיץ אותם לקובצי העזר החיצוניים. כשהבקשות מגיעות לעומס עבודה, קובץ העזר החיצוני בודק את מדיניות ההרשאות כדי לקבוע אם לאשר או לדחות את הבקשה.
בקטע תכונות נתמכות מפורט אילו שדות של AuthorizationPolicy CR נתמכים בכל פלטפורמה.
היקף המדיניות
אפשר להחיל מדיניות על כל Service mesh, על מרחב שמות או על עומס עבודה ספציפי.
כדי להחיל מדיניות על כל הרשת, מציינים את מרחב השמות הבסיסי,
istio-system, בשדהmetadata:namespace:apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "mesh-wide" namespace: istio-system spec: ...כדי להחיל מדיניות על מרחב שמות, מציינים את מרחב השמות בשדה
metadata:namespace:apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "currencyservice" namespace: currencyservice spec: ...כדי להגביל מדיניות לעומס עבודה ספציפי, צריך לכלול את השדה
selector.apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "frontend" namespace: demo spec: selector: matchLabels: app: frontend ...
מבנה בסיסי
מדיניות הרשאה כוללת את היקף המדיניות, action ורשימה של rules:
כפי שמתואר בקטע הקודם, היקף המדיניות יכול להיות כל הרשת, מרחב שמות או עומס עבודה ספציפי. אם כוללים את השדה
selector, הוא מציין את היעד של המדיניות.השדה
actionמציין אםALLOWאוDENYאת הבקשה. אם לא מציינים פעולה, הפעולה שמוגדרת כברירת מחדל היאALLOW. כדי שהפקודה תהיה ברורה, מומלץ תמיד לציין את הפעולה. (כללי מדיניות ההרשאה תומכים גם בפעולותAUDITו-CUSTOM. הפעולהAUDITנתמכת רק בחלק מהפלטפורמות. לפרטים, ראו תכונות נתמכות.השדות
rulesמציינים מתי להפעיל את הפעולה.
בדוגמה הבאה:
המדיניות חלה על בקשות לשירות
frontendבמרחב השמותdemo.הבקשות מותרות כשה-request header של הבקשה כולל את "hello:world", אחרת הבקשות נדחות.
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
name: "hello-world"
namespace: demo
spec:
selector:
matchLabels:
app: frontend
action: ALLOW
rules:
- when:
- key: request.headers[hello]
values: ["world"]
בקרת גישה לפעולת בקשה
כדי לשלוט בגישה לפעולות ספציפיות של בקשות, כמו שיטות HTTP או יציאות TCP, מוסיפים קטע to מתחת ל-rules.
בדוגמה הבאה, רק השיטות GET ו-POST של HTTP מותרות ל-currencyservice במרחב השמות demo.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: currencyservice
namespace: demo
spec:
selector:
matchLabels:
app: currencyservice
action: ALLOW
rules:
- to:
- operation:
methods: ["GET", "POST"]
בקרת גישה לזהות מאומתת
בדוגמאות הקודמות, כללי המדיניות מאפשרים בקשות מעומסי עבודה לא מאומתים. אם הפעלתם את STRICT Mutual TLS (mTLS), אתם יכולים להגביל את הגישה לפי הזהות של עומס העבודה או מרחב השמות שממנו נשלחה הבקשה בקטע source.
משתמשים בשדה
principalsאוnotPrincipalכדי לשלוט בגישה ברמת עומס העבודה.משתמשים בשדה
namespacesאוnotNamespacesכדי לשלוט בגישה ברמת מרחב השמות.
כדי להשתמש בכל השדות שלמעלה, צריך להפעיל את STRICT mTLS. אם אתם לא יכולים להגדיר mTLS ב-STRICT, תוכלו למצוא פתרון חלופי במאמר דחיית בקשות טקסט פשוט.
עומס העבודה שזוהה
בדוגמה הבאה, בקשות ל-currencyservice מותרות רק מהשירות frontend. בקשות ל-currencyservice מעומסי עבודה אחרים נדחות.
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
name: "currencyservice"
namespace: demo
spec:
selector:
matchLabels:
app: currencyservice
action: ALLOW
rules:
- from:
- source:
principals: ["example-project-1234.svc.id.goog/ns/demo/sa/frontend-sa"]
כדי לציין חשבון שירות, הערך של principals צריך להיות בפורמט הבא:
principals: ["PROJECT_ID.svc.id.goog/ns/NAMESPACE/sa/SERVICE_ACCOUNT_NAME"]
אם אתם משתמשים ב-Cloud Service Mesh באשכול עם Citadel CA, אז cluster.local הוא מתחם האמון. בכל שאר המקרים, PROJECT_ID.svc.id.goog הוא מתחם האמון של הרשת.
מתחם אמון (trust domain) תואם ל-Root of Trust (קיצור: RoT) של מערכת, והוא חלק מ-Workload Identity.
ב-Cloud Service Mesh, מתחם האמון משמש ליצירת כל הזהויות בתוך רשת. לדוגמה, במזהה SPIFFE
spiffe://mytrustdomain.com/ns/default/sa/myname, מחרוזת המשנה mytrustdomain.com מציינת שעומס העבודה הוא ממתחם אמון שנקרא mytrustdomain.com.
כשמשתמשים ברשות האישורים של Cloud Service Mesh, מתחם האמון נוצר באופן אוטומטי על ידי Cloud Service Mesh. הוא מבוסס על מאגר עומסי העבודה של האשכול.
יכולים להיות לכם כמה מתחמי אמון ברשת עם כמה אשכולות, כל עוד לאשכולות יש את אותו שורש אמון.
מרחב השמות שזוהה
בדוגמה הבאה מוצגת מדיניות שדוחה בקשות אם המקור הוא לא מרחב השמות foo:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: httpbin-deny
namespace: foo
spec:
selector:
matchLabels:
app: httpbin
version: v1
action: DENY
rules:
- from:
- source:
notNamespaces: ["foo"]
התאמת ערכים
רוב השדות במדיניות ההרשאה תומכים בכל סכימות ההתאמה הבאות:
- התאמה מדויקת: התאמה מדויקת של מחרוזת.
- התאמה של תו כללי לחיפוש באמצעות התו הכללי לחיפוש
"*":- התאמת קידומת: מחרוזת שמסתיימת ב-
"*". לדוגמה,"test.example.*"תואם ל-"test.example.com"או ל-"test.example.com.cn". - התאמת סיומת: מחרוזת שמתחילה ב-
"*". לדוגמה,"*.example.com"תואם ל-"eng.example.com"או ל-"test.eng.example.com".
- התאמת קידומת: מחרוזת שמסתיימת ב-
- התאמה לנוכחות: כדי לציין ששדה חייב להיות קיים ולא ריק, משתמשים בפורמט
fieldname: ["*"]. זה שונה מהשארת שדה לא מוגדר, שמשמעותה היא התאמה לכל דבר, כולל שדה ריק.
יש כמה מקרים חריגים. לדוגמה, השדות הבאים תומכים רק בהתאמה מדויקת:
- השדה
keyבקטעwhen - האפשרות
ipBlocksבקטעsource - השדה
portsבקטעto
מדיניות לדוגמה שמאפשרת גישה לנתיבים עם הקידומת /test/* או הסיומת */info:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: tester
namespace: default
spec:
selector:
matchLabels:
app: products
action: ALLOW
rules:
- to:
- operation:
paths: ["/test/*", "*/info"]
התאמה להחרגה
כדי להתאים תנאים שליליים כמו notValues בשדה when, notIpBlocks בשדה source ו-notPorts בשדה to, ב-Cloud Service Mesh יש תמיכה בהתאמה להחרגה. בדוגמה הבאה נדרשת בקשה חוקית principals, שנובעת מאימות JWT, אם נתיב הבקשה הוא לא /healthz. לכן, המדיניות מחריגה בקשות לנתיב /healthz מאימות JWT:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: disable-jwt-for-healthz
namespace: default
spec:
selector:
matchLabels:
app: products
action: ALLOW
rules:
- to:
- operation:
notPaths: ["/healthz"]
from:
- source:
requestPrincipals: ["*"]
דחיית בקשות בטקסט פשוט
ב-Cloud Service Mesh, פרוטוקול mTLS מופעל אוטומטית כברירת מחדל. עם mTLS אוטומטי, קובץ עזר חיצוני בצד הלקוח מזהה באופן אוטומטי אם לשרת יש קובץ עזר חיצוני. ה-sidecar של הלקוח שולח mTLS לעומסי עבודה עם sidecars ושולח טקסט פשוט לעומסי עבודה בלי sidecars. כדי ליהנות מהאבטחה הטובה ביותר, מומלץ להפעיל את STRICT mTLS.
אם אתם לא מצליחים להפעיל mTLS במצב STRICT לעומס עבודה או למרחב שמות, אתם יכולים:
- ליצור מדיניות הרשאה שתאפשר באופן מפורש תנועה עם
namespacesלא ריק אוprincipalsלא ריק, או - לדחות תנועה עם
namespacesאוprincipalsריקים.
מכיוון שאפשר לחלץ את namespaces ו-principals רק באמצעות בקשת mTLS, כללי המדיניות האלה דוחים בפועל כל תנועה בטקסט פשוט.
המדיניות הבאה דוחה את הבקשה אם חשבון המשתמש בבקשה ריק (כמו בבקשות טקסט פשוט). המדיניות מאפשרת בקשות אם החשבון הראשי לא ריק. הערך ["*"] מייצג התאמה לא ריקה, והשימוש ב-notPrincipals מייצג התאמה לחשבון משתמש ריק.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: require-mtls
namespace: NAMESPACE
spec:
action: DENY
rules:
- from:
- source:
notPrincipals: ["*"]
קדימות של מדיניות הרשאות
אפשר להגדיר מדיניות הרשאה נפרדת ל-ALLOW ול-DENY, אבל צריך להבין את סדר הקדימויות של המדיניות ואת התנהגות ברירת המחדל כדי לוודא שהמדיניות פועלת כמו שרוצים. בתרשים הבא מתוארת קדימות המדיניות.
כללי המדיניות לדוגמה בקטעים הבאים ממחישים חלק מהתנהגות ברירת המחדל, ומצבים שבהם הם יכולים להועיל.
לא לאשר כלום
בדוגמה הבאה מוצגת מדיניות ALLOW שלא תואמת לשום דבר. כברירת מחדל, אם אין כללי מדיניות אחרים של ALLOW, הבקשות תמיד נדחות.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
spec:
action: ALLOW
שיטת אבטחה מומלצת היא להתחיל עם מדיניות allow-nothing, ולהוסיף בהדרגה עוד כללי מדיניות של ALLOW כדי לפתוח יותר גישה לעומס עבודה.
דחיית כל בקשות הגישה
בדוגמה הבאה מוצגת מדיניות DENY שתואמת לכל דבר. מכיוון שכללי המדיניות של DENY נבדקים לפני כללי המדיניות של ALLOW, כל הבקשות נדחות גם אם יש מדיניות ALLOW שתואמת לבקשה.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-all
spec:
action: DENY
rules:
- {}
מדיניות דחיית הכול שימושית אם רוצים להשבית באופן זמני את כל הגישה לעומס עבודה.
אישור גישה מלאה
בדוגמה הבאה מוצגת מדיניות ALLOW שתואמת לכל דבר ומאפשרת גישה מלאה לעומס עבודה. מדיניות שמאפשרת הכול הופכת כללי מדיניות אחרים של ALLOW לחסרי תועלת, כי היא תמיד מאפשרת את הבקשה.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-all
spec:
action: ALLOW
rules:
- {}
מדיניות allow-all שימושית אם רוצים לחשוף באופן זמני גישה מלאה לעומס עבודה. אם יש כללי מדיניות של DENY, יכול להיות שהבקשות עדיין יידחו כי כללי המדיניות של DENY נבדקים לפני כללי המדיניות של ALLOW.
שיטות מומלצות
יוצרים חשבון שירות של Kubernetes לכל שירות, ומציינים את חשבון השירות ב-Deployment. לדוגמה:
apiVersion: v1 kind: ServiceAccount metadata: name: frontend-sa namespace: demo --- apiVersion: apps/v1 kind: Deployment metadata: name: frontend namespace:demo spec: selector: matchLabels: app: frontend template: metadata: labels: app: frontend spec: serviceAccountName: frontend-sa ...מתחילים עם מדיניות allow-nothing ומוסיפים בהדרגה עוד כללי מדיניות של
ALLOWכדי לפתוח גישה נוספת לעומסי עבודה.אם אתם משתמשים באסימוני JWT בשירות שלכם:
יוצרים מדיניות
DENYכדי לחסום בקשות לא מאומתות, לדוגמה:apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: requireJWT namespace: admin spec: action: DENY rules: - from: - source: notRequestPrincipals: ["*"]החלת מדיניות של "לא לאפשר כלום".
מגדירים כללי מדיניות של
ALLOWלכל עומס עבודה. לדוגמאות, ראו אסימון JWT.
המאמרים הבאים
מידע נוסף על אמצעי האבטחה של Cloud Service Mesh:
- הגדרת אימות משתמשים ב-Cloud Service Mesh
- הגדרת כללי מדיניות ביקורת לשירותים
- הגדרת אבטחת תעבורה
- שילוב של שרת proxy לאימות זהויות (IAP) עם Cloud Service Mesh
- שיטות מומלצות לשימוש בשערי תעבורה יוצאת של Cloud Service Mesh באשכולות GKE
מידע נוסף על כללי מדיניות הרשאה זמין במסמכי התיעוד של Istio: