פתרון בעיות אבטחה ב-Cloud Service Mesh

בקטע הזה מוסבר על בעיות נפוצות ב-Cloud Service Mesh עם Istio APIs ואיך לפתור אותן. לקבלת עזרה נוספת, אפשר לעיין במאמר בנושא קבלת תמיכה.

ב-Cloud Service Mesh, רשות האישורים של Cloud Service Mesh או Istiod מנפיקות אישורים לעומסי עבודה בכל האשכולות ברשת. מדיניות אימות (לדוגמה, mTLS) ומדיניות הרשאה (לדוגמה, הרשאה או דחייה) נדחפות לכל אשכול. כללי המדיניות האלה קובעים אילו עומסי עבודה יכולים לתקשר ואיך.

בעיות ב-TLS

בקטעים הבאים מוסבר איך לפתור בעיות שקשורות ל-TLS ב-Cloud Service Mesh.

בדוגמאות שבקטע הזה נעשה שימוש במשתנה ${CTX}, שהוא שם ההקשר בקובץ התצורה של ברירת המחדל של Kubernetes שמשמש לגישה לאשכול. מגדירים את המשתנה ${CTX} כמו בדוגמה הבאה:

export CTX=gke_PROJECT_ID_CLUSTER_LOCATION_CLUSTER_NAME

אימות האכיפה של TLS

מוודאים שבקשות טקסט רגיל אסורות בשירות, אם השירות דורש חיבורי TLS:

kubectl exec SOURCE_POD -n SOURCE_NAMESPACE -c \
    SOURCE_CONTAINER -- curl -v DESTINATION_URL

בהנחה שהשירות דורש חיבורי TLS, הבקשה הקודמת בטקסט רגיל אמורה להיכשל, והפלט שיתקבל יהיה דומה לזה:

curl: (56) Recv failure: Connection reset by peer command terminated with exit code 56

בדיקת אישורי mTLS

כש-mTLS מופעל, אפשר לבדוק את אישור ה-mTLS של עומס העבודה על ידי הצגת הכותרת X-Forwarded-Client-Cert. כדי לעשות את זה, פועלים לפי השלבים הבאים:

  1. פורסים את שירות הדוגמה httpbin, שיכול להציג את הכותרות שהוא מקבל.

  2. משתמשים ב-curl כדי להציג את הכותרת X-Forwarded-Client-Cert:

    kubectl exec --context=${CTX} SOURCE_POD -n SOURCE_NAMESPACE -c \
    SOURCE_CONTAINER -- curl http://httpbin.sample:8000/headers -s | \
    grep X-Forwarded-Client-Cert

    בכותרת X-Forwarded-Client-Cert מוצג מידע על אישורי mTLS, כמו בדוגמה הבאה:

    X-Forwarded-Client-Cert": "By=spiffe://lt-multicluster-t2-5-15-2020.svc.id.goog/ns/sample/sa/httpbin;Hash=0781d68adfdab85b08b6758ed502f352464e81166f065cc6acde9433337b4494;Subject=\"OU=istio_v1_cloud_workload,O=Google LLC,L=Mountain View,ST=California,C=US\";URI=spiffe://lt-multicluster-t2-5-15-2020.svc.id.goog/ns/sample/sa/sleep
  3. אפשר גם להשתמש ב-openssl ב-sidecar כדי לראות את כל שרשרת האישורים:

    kubectl debug --image istio/base --target istio-proxy -it --context=${CTX} SOURCE_POD \
    -n SOURCE_NAMESPACE -- openssl s_client -alpn istio -showcerts -connect httpbin.sample:8000

    הפלט יציג את שרשרת האישורים. אם אתם משתמשים ב-Mesh CA, ודאו ש-CN של אישור הבסיס מכיל istio_v1_cloud_workload_root-signer-.... אם אתם משתמשים ב-Istiod כרשות אישורים, ודאו שאישור הבסיס מוגדר באמצעות O = <var>YOUR_TRUST_DOMAIN</var>.

שגיאות TLS bad certificate ביומני Istiod

אם אתם רואים שגיאות של לחיצת יד בפרוטוקול TLS‏ bad certificate ביומנים, יכול להיות ש-Istiod לא מצליח ליצור חיבור TLS לשירות.

אפשר להשתמש במחרוזת הביטוי הרגולרי TLS handshake error.*bad certificate כדי למצוא את השגיאות האלה ביומנים.

בדרך כלל השגיאות האלה הן אינפורמטיביות וזמניות. אבל אם הבעיות נמשכות, יכול להיות שהן מצביעות על בעיה במערכת.

  1. מוודאים של-istio-sidecar-injector MutatingWebhookConfiguration יש חבילת אישורים.

    ה-webhook של sidecar injector (שמשמש להזרקת sidecar אוטומטית) דורש חבילת CA כדי ליצור חיבורים מאובטחים עם שרת ה-API ועם Istiod. חבילת אישורים של רשות אישורים מוטמעת בהגדרה על ידי istiod, אבל לפעמים אפשר להחליף אותה (לדוגמה, אם מפעילים מחדש את הגדרת ה-webhook).

  2. בודקים אם חבילת האישורים קיימת:

    kubectl get mutatingwebhookconfiguration -l app=sidecar-injector -o=jsonpath='{.items[0].webhooks[0].clientConfig.caBundle}'
    

    אם הפלט לא ריק, חבילת אישורי ה-CA מוגדרת. אם חבילת אישורי ה-CA חסרה, מפעילים מחדש את istiod כדי שהמערכת תסרוק מחדש את ה-webhook ותתקין מחדש את חבילת אישורי ה-CA.

רישום ביומן של דחיות במדיניות ההרשאות

מידע על רישום ביומן של דחיות במדיניות הרשאות זמין במאמר בנושא רישום ביומן של דחיות.

אין אכיפה של מדיניות הרשאות

אם אתם רואים סימנים לכך שמדיניות ההרשאות לא נאכפת, אתם יכולים להשתמש בפקודה הבאה כדי לאמת אותה:

kubectl exec --context=${CTX} -it SOURCE_POD -n SOURCE_NAMESPACE \
    -c SOURCE_CONTAINER -- curl DESTINATION_URL

בפלט, הודעות access denied מציינות שמדיניות ההרשאות נאכפת בצורה תקינה, כמו בדוגמה הבאה:

RBAC: access denied

אם תאשרו שמדיניות ההרשאות לא נאכפת, תדחו את הגישה למרחב השמות. בדוגמה הבאה נדחית הגישה למרחב השמות שנקרא authz-ns:

kubectl apply --context=${CTX} -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: deny-authz-ns
  namespace: authz-ns
spec:
  {}
EOF

השגיאה 'customresourcedefinitions.apiextensions.k8s.io is forbidden' ביומני Istiod

יכול להיות שיוצגו שגיאות דומות לאלה:

error failed to list CRDs: customresourcedefinitions.apiextensions.k8s.io is forbidden: User "system:serviceaccount:istio-system:istiod-service-account" cannot list resource "customresourcedefinitions" in API group "apiextensions.k8s.io" at the cluster scope

אפשר להשתמש במחרוזת הביטוי הרגולרי /error.*cannot list resource/ כדי למצוא את השגיאות האלה ביומנים.

השגיאה הזו יכולה לקרות אם לפריסת Istiod חסר הקישור הנכון של IAM, או אם אין לה הרשאות RBAC מספיקות לקריאת משאב בהתאמה אישית.

  1. בודקים אם חסר בחשבון שלכם קישור IAM. קודם כל, צריך לוודא שהגדרתם את פרטי הכניסה וההרשאות בצורה נכונה. לאחר מכן, מריצים את הפקודה הבאה כדי לוודא שהקישור של IAM קיים. בדוגמה הזו, PROJECT_ID הוא הפלט של gcloud config get-value project ו-PROJECT_NUMBER הוא הפלט של gcloud projects list --filter="project_id=${PROJECT_ID}" --format="value(project_number)":

    gcloud projects add-iam-policy-binding ${PROJECT_ID} --member "serviceAccount:service-${PROJECT_NUMBER}@gcp-sa-meshdataplane.iam.gserviceaccount.com" --role "roles/meshdataplane.serviceAgent"
  2. בודקים שכללי ה-RBAC מותקנים בצורה נכונה.

  3. אם כללי ה-RBAC חסרים, מריצים מחדש את הפקודה asmcli install כדי ליצור אותם מחדש.

  4. אם כללי ה-RBAC קיימים והשגיאות נמשכות, צריך לבדוק שהפקודות ClusterRoleBindings ו-RoleBindings מצרפות את כללי ה-RBAC לחשבון השירות הנכון של Kubernetes. בנוסף, מוודאים שפריסת istiod משתמשת בחשבון השירות שצוין.

serverca שגיאות בתהליך ביומני Istiod

יכול להיות שיוצגו שגיאות דומות לאלה:

Authentication failed: Authenticator ClientCertAuthenticator at index 0 got error

אפשר להשתמש במחרוזת הביטוי הרגולרי /serverca.*Authentication failed:.*JWT/ כדי למצוא את השגיאות האלה ביומנים.

השגיאה הזו יכולה לקרות אם המוסד המנפיק של ה-JWT לא מוגדר בצורה נכונה, אם לקוח משתמש באסימון שתוקפו פג או אם בעיה אבטחתית אחרת מונעת מחיבור לעבור אימות ל-istiod בצורה נכונה.