הגדרת אימות LDAP באשכולות של חברי צי

במאמר הזה נסביר איך מנהלי אשכולות או מפעילים של אפליקציות יכולים להגדיר אשכולות של Kubernetes כדי לתמוך באימות מספק Lightweight Directory Access Protocol ‏ (LDAP) של צד שלישי, כמו Microsoft Entra ID או Google LDAP. מידע נוסף זמין במאמר מידע על אימות באמצעות זהויות של צד שלישי.

מגבלות

חובה להשתמש בסוג אשכול שתומך ב-LDAP.

לפני שמתחילים

  1. התקינו את ה-CLI של Google Cloud.

  2. אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

  3. כדי לאתחל את ה-CLI של gcloud, הריצו את הפקודה הבאה:

    gcloud init
  4. אחרי שתאתחלו את ה-CLI של gcloud, עדכנו אותו והתקינו את הרכיבים הנדרשים:

    gcloud components update
    gcloud components install kubectl
  5. ודאו שמנהל הפלטפורמה נתן לכם את כל פרטי הספק שאתם צריכים. מידע נוסף זמין במאמר בנושא הגדרת ספקי LDAP לאימות לאשכולות.

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

מילוי הסוד של חשבון השירות ב-LDAP

כדי לאמת את שרת ה-LDAP ולאחזר את פרטי המשתמשים, האשכול צריך סוד של חשבון שירות. אימות LDAP תומך במנגנונים הבאים:

  • אימות בסיסי, שבו משתמשים בשם משתמש ובסיסמה.
  • אימות באמצעות אישור לקוח, שבו משתמשים במפתח פרטי של לקוח ובאישור לקוח.

אתם או האדמין של הפלטפורמה אמורים לקבל את המידע הזה על הספק שלכם מתוך המאמר הגדרת ספקי LDAP לאימות באשכולות. כדי שפרטי הכניסה לשרת ה-LDAP יהיו זמינים לאשכול, צריך ליצור סוד של Kubernetes עם פרטי הכניסה ל-LDAP. בדוגמאות הבאות אפשר לראות איך להגדיר סודות לשני סוגי האימות. בדוגמאות אפשר לראות שהסוד מוחל על מרחב השמות anthos-identity-service.

זו דוגמה להגדרת סוד לאימות בסיסי:

apiVersion: v1
kind: Secret
metadata:
  name: SERVICE_ACCOUNT_SECRET_NAME
  namespace: "anthos-identity-service"
type: kubernetes.io/basic-auth     # Make sure the type is correct
data:
  username: USERNAME  # Use a base64-encoded username
  password: PASSWORD  # Use a base64-encoded password

כאשר SERVICE_ACCOUNT_SECRET_NAME הוא השם שבחרתם לסוד הזה. מחליפים את ערכי שם המשתמש והסיסמה בשם המשתמש ובסיסמה שקיבלתם בשלב הקודם. ‫USERNAME הוא שם משתמש בקידוד Base64 ‫PASSWORD היא סיסמה בקידוד Base64

זו דוגמה להגדרת סוד של אישור לקוח:

apiVersion: v1
kind: Secret
metadata:
  name: SERVICE_ACCOUNT_SECRET_NAME
  namespace: anthos-identity-service
type: kubernetes.io/tls            # Make sure the type is correct
data:
  # the data is abbreviated in this example
  tls.crt: |
       MIIC2DCCAcCgAwIBAgIBATANBgkqh ...
  tls.key: |
       MIIEpgIBAAKCAQEA7yn3bRHQ5FHMQ ...

מחליפים את SERVICE_ACCOUNT_SECRET_NAME בשם שבחרתם לסוד הזה. מחליפים את ערכי המפתח ואישור ה-TLS בערכי המפתח והאישור המקודדים שקיבלתם בשלב הקודם.

בדוגמאות אפשר לראות שהסוד מוחל על מרחב השמות anthos-identity-service. כברירת מחדל, לרכיבי המערכת יש הרשאה לקרוא סודות במרחב השמות הזה. כדי להשתמש במרחב שמות אחר, צריך לשנות את המטא-נתונים בסוד ואז להוסיף מדיניות RBAC חדשה כדי להעניק את ההרשאה לקרוא סודות במרחב השמות הזה ל-default ServiceAccount במרחב השמות anthos-identity-service, באופן הבא:

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: NAMESPACE
  name: ais-secret-reader-role
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get","list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: ais-secret-reader-role-binding
  namespace: NAMESPACE
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: ais-secret-reader-role
subjects:
- kind: ServiceAccount
  name: default
  namespace: anthos-identity-service
---

הגדרת האוסף

כדי להגדיר אימות לאשכול באמצעות LDAP, מוסיפים את הפרטים הבאים למשאב מותאם אישית של Kubernetes בשם ClientConfig:

  • מידע על ספק הזהויות והפרמטרים שהוא צריך כדי להחזיר מידע על המשתמש.
  • השם ומרחב השמות של הסוד שיצרתם והחלתם בשלב הקודם, שמאפשר לאשכול לבצע אימות לשרת LDAP.

כדי להגדיר את האשכול, עורכים את default ClientConfig במרחב השמות kube-public:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG -n kube-public edit clientconfig default

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

כך נראה הפורמט של הגדרת ClientConfig:

apiVersion: authentication.gke.io/v2alpha1
kind: ClientConfig
metadata:
  name: default
  namespace: kube-public
spec:
  authentication:
  - name: NAME
    ldap:
      certificateAuthorityData: CERTIFICATE_AUTHORITY_DATA
      connectionType: CONNECTION_TYPE
      host: HOST_NAME
      serviceAccountSecret:
        name: SERVICE_ACCOUNT_SECRET_NAME
        namespace: NAMESPACE
        type: SECRET_FORMAT
      user:
        baseDN: BASE_DN
        filter: FILTER
        identifierAttribute: IDENTIFIER_ATTRIBUTE
        loginAttribute: LOGIN_ATTRIBUTE
      group:
        baseDN: BASE_DN
        filter: FILTER
        identifierAttribute: IDENTIFIER_ATTRIBUTE

אפשר להוסיף כמה הגדרות של ספקי זהויות ב-OIDC, ב-LDAP וב-SAML לאותו ClientConfig. האשכול מנסה לבצע אימות עם כל הגדרה לפי הסדר שבו הן מוגדרות, ומפסיק אחרי האימות הראשון שמצליח. בדוגמה הבאה של ClientConfig מוגדרים כמה ספקי זהויות בסדר מסוים:

apiVersion: authentication.gke.io/v2alpha1
kind: ClientConfig
metadata:
  name: default
  namespace: kube-public
spec:
  authentication:
  - aws:
      region: us-west-2
    name: AWS Login
  - ldap:
  # Multiple lines are omitted here.
  - saml:
  # Multiple lines are omitted here.
  - azureAD:
  # Multiple lines are omitted here.
  - oidc:
    name: Okta OIDC
  # Multiple lines are omitted here.
  - oidc:
    name: Google OIDC
  # Multiple lines are omitted here.

שדות ClientConfig LDAP

בטבלה הבאה מתוארים השדות של אובייקט ClientConfig ldap. השדות שצריך להוסיף תלויים בטוקנים של ספק הזהויות ובאופן שבו האדמין של הפלטפורמה הגדיר את הספק.

שדה חובה תיאור פורמט
name כן שם לזיהוי הגדרת ה-LDAP הזו מחרוזת
מארח כן שם המארח או כתובת ה-IP של שרת ה-LDAP. היציאה היא אופציונלית, ואם לא מציינים אותה, ברירת המחדל היא 389. לדוגמה, ldap.server.example.com או 10.10.10.10:389. מחרוזת
certificateAuthorityData נדרש לסוגים מסוימים של חיבורי LDAP מכיל אישור של רשות אישורים לשרת LDAP בקידוד Base64 ובפורמט PEM. צריך לספק את הנתון הזה רק לחיבורים של ldaps ושל startTLS. מחרוזת
connectionType כן סוג החיבור ל-LDAP שבו יש להשתמש כשמתחברים לשרת ה-LDAP. ברירת המחדל היא startTLS. אסור להשתמש במצב insecure אלא לצורך פיתוח, כי כל התקשורת עם השרת תהיה בטקסט רגיל. מחרוזת
serviceAccountSecret
name כן השם של סוד Kubernetes שבו מאוחסנים פרטי הכניסה לחשבון השירות של LDAP. מחרוזת
מרחב שמות כן מרחב השמות של סוד Kubernetes שבו מאוחסנים פרטי הכניסה לחשבון השירות של LDAP. מחרוזת
סוג כן מגדיר את הפורמט של הסוד של חשבון השירות כדי לתמוך בסוגים שונים של סודות. אם ציינתם basic-auth בהגדרת הסוד, הערך צריך להיות basic, אחרת הוא צריך להיות tls. אם לא מציינים ערך, ברירת המחדל היא basic. מחרוזת
משתמש
baseDN כן המיקום של עץ המשנה בספריית ה-LDAP שבו יתבצע חיפוש של רשומות משתמשים. מחרוזת
מסנ לא מסנן אופציונלי להחלה כשמחפשים את המשתמש. אפשר להשתמש בהגדרה הזו כדי להגביל עוד יותר את חשבונות המשתמשים שמורשים להתחבר. אם לא מציינים ערך, ברירת המחדל היא (objectClass=User). מחרוזת
identifierAttribute לא קובעת באיזה מאפיין להשתמש כזהות המשתמש אחרי שהוא מאומת. השדה הזה שונה מהשדה loginAttribute כדי לאפשר למשתמשים להתחבר באמצעות שם משתמש, אבל שהמזהה בפועל שלהם יהיה כתובת אימייל או שם ייחודי (DN) מלא. לדוגמה, אם מגדירים את loginAttribute ל-sAMAccountName ואת identifierAttribute ל-userPrincipalName המשתמש יוכל להיכנס כ-bsmith, אבל מדיניות בקרת הגישה מבוססת-התפקידים (RBAC) בפועל עבור המשתמש תיכתב כ-bsmith@example.com. מומלץ להשתמש ב-userPrincipalName כי הוא ייחודי לכל משתמש. אם לא מציינים ערך, ברירת המחדל היא userPrincipalName. מחרוזת
loginAttribute לא השם של המאפיין שתואם לשם המשתמש שהוזן. השדה הזה משמש למציאת המשתמש במסד הנתונים של LDAP, לדוגמה (<LoginAttribute>=<username>) והוא משולב עם שדה המסנן האופציונלי. ברירת המחדל היא userPrincipalName. מחרוזת
קבוצה (שדה אופציונלי)
baseDN כן המיקום של עץ המשנה בספריית ה-LDAP שבו יתבצע חיפוש של רשומות קבוצה. מחרוזת
מסנ לא מסנן אופציונלי לשימוש כשמחפשים קבוצות שהמשתמש שייך אליהן. אפשר להשתמש בזה כדי להתאים במפורש רק קבוצות מסוימות, וכך לצמצם את מספר הקבוצות שמוחזרות לכל משתמש. ברירת המחדל היא (objectClass=Group). מחרוזת
identifierAttribute לא השם המזהה של כל קבוצה שהמשתמש שייך אליה. לדוגמה, אם הערך מוגדר כ-distinguishedName, צריך לכתוב את ה-DN המלא של RBAC ושל ציפיות אחרות לגבי קבוצות. אם לא מציינים ערך, ברירת המחדל היא distinguishedName. מחרוזת

מה השלב הבא?

אחרי שההגדרה מוחלת, ממשיכים אל הגדרת גישת משתמשים מספקי זהויות חיצוניים לאשכולות.