הרשאות IAM גרנולריות לקבוצות של רשומות ב-Cloud DNS


ב-Codelab הזה נסביר איך להטמיע בקרת גישה מפורטת לקבוצות של רשומות DNS ב-Cloud DNS באמצעות תנאים ותפקידים בהתאמה אישית ב-IAM.

מבוא

בדרך כלל, Cloud DNS תומך בהגדרת הרשאות IAM ברמת הפרויקט וברמת האזור המנוהל. כך ניתנת גישה רחבה לכל הרשומות בתחום (zone). עם זאת, בארגונים גדולים, הגישה הזו לא עומדת בעקרון של הרשאות מינימליות.

בשיעור Codelab הזה נסביר איך להגדיר הרשאות IAM לכל קבוצת רשומות ב-Cloud DNS. התכונה הזו מאפשרת להעביר את הניהול של תת-דומיינים ספציפיים או סוגים ספציפיים של רשומות לצוותים שונים באזור מנוהל משותף יחיד.

מה תלמדו

  • איך משתמשים בתנאי IAM כדי להגביל את הניהול של רשומות DNS.
  • למה ואיך יוצרים תפקידים בהתאמה אישית.
  • איך להקצות תת-דומיינים וסוגים ספציפיים של רשומות (לדוגמה: A, ‏ MX).
  • איך מטפלים בעסקאות DNS עם הרשאות מותנות באמצעות הדגל --skip-soa-update.

דרישות מוקדמות

  • חשבון Google
  • פרויקט ב-Google Cloud שהחיוב בו מופעל
  • הגרסה האחרונה של Google Cloud CLI מותקנת ומוגדרת
  • הבנה בסיסית של מושגי DNS ו-IAM

תהליך ההגדרה

משך: 03:00

הפעלת Cloud DNS API

מתחברים ל-CLI של gcloud ומפעילים את ה-API.

gcloud auth login
gcloud services enable dns.googleapis.com

יצירת פרויקט בדיקה

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

gcloud projects create my-dns-per-rrset-lab
gcloud config set project my-dns-per-rrset-lab

הסבר על הגישה של תפקידים בהתאמה אישית

משך: 02:00

אי אפשר לקשר תנאי IAM ישירות לתפקיד roles/dns.admin הרגיל. במקום זאת, צריך להפריד את הניהול של קבוצת הרשומות ממשימות ניהול אחרות באמצעות שני תפקידים בהתאמה אישית:

  1. DnsRecordSetAdmin: מכילה הרשאות ליצירה, למחיקה, לקבלת מידע ולעדכון של קבוצות רשומות משאבים. התפקיד הזה יינתן באופן מותנה.
  2. DnsNonRecordSetAdmin: מכיל את כל הרשאות הניהול האחרות של DNS (כמו ניהול אזורים, הצגת רשימת רשומות וצפייה בפרטי הפרויקט). התפקיד הזה יינתן ללא תנאים.

הפרדת התפקידים מבטיחה שהבדיקות המוקדמות שמבוצעות על ידי Cloud DNS (כמו dns.changes.create) יתבצעו ללא תנאי, בעוד שהשינויים בפועל ברשומה יהיו תלויים בתנאים שהגדרתם.

יצירת תפקידים בהתאמה אישית

משך: 05:00

מריצים את הפקודות הבאות כדי ליצור את התפקידים הנדרשים בהתאמה אישית בפרויקט.

הגדרת קבוצות ההרשאות

# Record set management permissions
rs_perms="dns.resourceRecordSets.create,dns.resourceRecordSets.delete,dns.resourceRecordSets.get,dns.resourceRecordSets.update"

# Complementary administrative permissions
comp_perms="compute.networks.get,compute.networks.list,dns.changes.create,dns.changes.get,dns.changes.list,dns.dnsKeys.get,dns.dnsKeys.list,dns.gkeClusters.bindDNSResponsePolicy,dns.gkeClusters.bindPrivateDNSZone,dns.managedZoneOperations.get,dns.managedZoneOperations.list,dns.managedZones.create,dns.managedZones.delete,dns.managedZones.get,dns.managedZones.getIamPolicy,dns.managedZones.list,dns.managedZones.update,dns.networks.bindDNSResponsePolicy,dns.networks.bindPrivateDNSPolicy,dns.networks.bindPrivateDNSZone,dns.networks.targetWithPeeringZone,dns.networks.useHealthSignals,dns.policies.create,dns.policies.createTagBinding,dns.policies.delete,dns.policies.deleteTagBinding,dns.policies.get,dns.policies.list,dns.policies.listEffectiveTags,dns.policies.listTagBindings,dns.policies.update,dns.projects.get,dns.resourceRecordSets.list,dns.responsePolicies.create,dns.responsePolicies.delete,dns.responsePolicies.get,dns.responsePolicies.list,dns.responsePolicies.update,dns.responsePolicyRules.create,dns.responsePolicyRules.delete,dns.responsePolicyRules.get,dns.responsePolicyRules.list,dns.responsePolicyRules.update,resourcemanager.projects.get"

יצירת התפקידים ב-Gcloud

gcloud iam roles create DnsRecordSetAdmin --project=$(gcloud config get-value project) \
    --title="DNS Record Set Admin (Conditional)" --permissions="${rs_perms}"

gcloud iam roles create DnsNonRecordSetAdmin --project=$(gcloud config get-value project) \
    --title="DNS Complimentary Admin" --permissions="${comp_perms}"

תרחיש 1: התאמה מדויקת של רשומה

משך: 05:00

בתרחיש הזה, אתם רוצים להעניק לצוות הרשאה לנהל רק את רשומת A עבור api.example.com..

יצירת אזור מנוהל

gcloud dns managed-zones create example-zone \
    --description="Lab zone for per-RRSet permissions" \
    --dns-name=example.com. --visibility=private \
    --networks=default

יצירה של חשבון שירות לבדיקה

תשתמשו בחשבון השירות הזה כדי לאמת את ההרשאות המוגבלות.

gcloud iam service-accounts create dns-restricted-sa \
    --display-name="Restricted DNS SA"

SA_EMAIL="dns-restricted-sa@$(gcloud config get-value project).iam.gserviceaccount.com"

החלת מדיניות IAM מותנית

מעניקים את DnsNonRecordSetAdmin ללא תנאי ואת DnsRecordSetAdmin עם תנאי.

cat << EOF > policy.json
{
  "bindings": [
    {
      "role": "projects/$(gcloud config get-value project)/roles/DnsRecordSetAdmin",
      "members": ["serviceAccount:${SA_EMAIL}"],
      "condition": {
        "expression": "resource.type == 'dns.googleapis.com/ResourceRecordSet' && resource.name.endsWith('/rrsets/api.example.com./A')",
        "title": "Exact Record Match"
      }
    },
    {
      "role": "projects/$(gcloud config get-value project)/roles/DnsNonRecordSetAdmin",
      "members": ["serviceAccount:${SA_EMAIL}"]
    }
  ],
  "version": 3
}
EOF

gcloud dns managed-zones set-iam-policy example-zone --policy-file=policy.json

אימות ההגבלה

נסו ליצור את הרשומה המותרת, ואז נסו ליצור רשומה לא מורשית.

# ALLOWED: Create the specific A record
gcloud dns record-sets create api.example.com. --zone=example-zone --type=A --rrdatas="1.2.3.4" --ttl=300 --impersonate-service-account=${SA_EMAIL}

# DENIED: Create an unauthorized name
gcloud dns record-sets create www.example.com. --zone=example-zone --type=A --rrdatas="5.6.7.8" --ttl=300 --impersonate-service-account=${SA_EMAIL}

תרחיש 2: האצלת סמכויות בתת-דומיין

משך: 05:00

עכשיו נותנים הרשאה לניהול כל רשומה בתת-הדומיין p.example.com..

עדכון מדיניות ה-IAM

משנים את התנאי כך שישתמש ב-resource.name.extract() כדי להתאים לסיומת של תת-הדומיין.

cat << EOF > policy_subdomain.json
{
  "bindings": [
    {
      "role": "projects/$(gcloud config get-value project)/roles/DnsRecordSetAdmin",
      "members": ["serviceAccount:${SA_EMAIL}"],
      "condition": {
        "expression": "resource.type == 'dns.googleapis.com/ResourceRecordSet' && resource.name.extract('/rrsets/{name}/').endsWith('.p.example.com.')",
        "title": "Subdomain Delegation"
      }
    },
    {
      "role": "projects/$(gcloud config get-value project)/roles/DnsNonRecordSetAdmin",
      "members": ["serviceAccount:${SA_EMAIL}"]
    }
  ],
  "version": 3
}
EOF

gcloud dns managed-zones set-iam-policy example-zone --policy-file=policy_subdomain.json

אימות ההרשאה

# ALLOWED: Create any record in the subdomain
gcloud dns record-sets create test.p.example.com. --zone=example-zone --type=A --rrdatas="192.168.1.1" --ttl=300 --impersonate-service-account=${SA_EMAIL}

# DENIED: Create a record outside the subdomain
gcloud dns record-sets create news.example.com. --zone=example-zone --type=A --rrdatas="192.168.1.2" --ttl=300 --impersonate-service-account=${SA_EMAIL}

תרחיש 3: שינויים ועסקאות בקבוצות

משך: 03:00

כשמשתמשים בהרשאות מותנות, יש פרט חשוב לגבי טרנזקציות. כברירת מחדל, העסקאות ב-DNS מנסות לעדכן את רשומת SOA. אם התנאי של IAM מאפשר למשתמשים לנהל רק רשומות ספציפיות (כמו api.example.com.), העסקה תיכשל כי למשתמש אין הרשאה לשנות את הרשומה SOA.

הסימון ‎--skip-soa-update

כדי לשנות רשומות מותרות בתוך טרנזקציה, צריך לאפשר עדכוני SOA על ידי שינוי התנאי בהתאם (resource.name.endsWith('/SOA')) או להשתמש בדגל --skip-soa-update.

gcloud dns record-sets transaction start --zone=example-zone --skip-soa-update
gcloud dns record-sets transaction add --zone=example-zone --name="api.example.com." --type=A --ttl=300 "10.0.0.1"
gcloud dns record-sets transaction execute --zone=example-zone --impersonate-service-account=${SA_EMAIL}

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

הסרת המשאבים

משך: 01:00

כדי להימנע מחיובים, מוחקים את המשאבים שנוצרו בשיעור ה-Lab הזה.

# Delete record sets
gcloud dns record-sets delete api.example.com. --zone=example-zone --type=A
gcloud dns record-sets delete test.p.example.com. --zone=example-zone --type=A

# Delete managed zone
gcloud dns managed-zones delete example-zone

# Delete custom roles
gcloud iam roles delete DnsRecordSetAdmin --project=$(gcloud config get-value project)
gcloud iam roles delete DnsNonRecordSetAdmin --project=$(gcloud config get-value project)

# Delete service account
gcloud iam service-accounts delete ${SA_EMAIL}

מזל טוב

מעולה! למדתם איך להטמיע הרשאות IAM גרנולריות לכל קבוצת רשומות ב-Cloud DNS.

סיכום של הנושאים שדיברנו עליהם

  • יצרנו תפקידים בהתאמה אישית כדי להפריד בין הרשאות של קבוצות רשומות לבין משימות אדמיניסטרטיביות ברמת האזור.
  • הטמענו תנאי התאמה מדויקת לשמות ולסוגים ספציפיים של רשומות.
  • הטמענו הענקת הרשאות לדומיין משנה באמצעות חילוץ מחרוזות בתנאי IAM.
  • השתמשתם בדגל --skip-soa-update כדי לאפשר למשתמשים מותנים לבצע שינויים באצווה.

קריאה נוספת