สิทธิ์ IAM แบบละเอียดของ Cloud DNS สำหรับชุดระเบียน


Codelab นี้แสดงวิธีใช้ IAM Conditions และบทบาทที่กำหนดเองเพื่อใช้การควบคุมการเข้าถึงแบบละเอียดสำหรับชุดระเบียน DNS แต่ละชุดภายใน Cloud DNS

บทนำ

โดยปกติแล้ว Cloud DNS จะรองรับการตั้งค่าสิทธิ์ IAM ที่ระดับโปรเจ็กต์และโซนที่มีการจัดการ ซึ่งจะให้สิทธิ์เข้าถึงระเบียนทั้งหมดภายในโซนอย่างกว้างขวาง อย่างไรก็ตาม สำหรับองค์กรขนาดใหญ่ วิธีนี้ไม่เป็นไปตาม "หลักการให้สิทธิ์ขั้นต่ำที่สุด"

Codelab นี้จะแนะนำวิธีกำหนดค่าสิทธิ์ IAM ต่อชุดระเบียนใน Cloud DNS ฟีเจอร์นี้ช่วยให้คุณมอบสิทธิ์การจัดการโดเมนย่อยหรือประเภทระเบียนที่เฉพาะเจาะจงให้กับทีมต่างๆ ภายในโซนที่มีการจัดการที่แชร์ร่วมกันได้

สิ่งที่คุณจะได้เรียนรู้

  • วิธีใช้ IAM Conditions เพื่อจำกัดการจัดการระเบียน DNS
  • เหตุผลและวิธีสร้างบทบาทที่กำหนดเอง
  • วิธีมอบสิทธิ์โดเมนย่อยและประเภทระเบียนที่เฉพาะเจาะจง (เช่น A, MX)
  • วิธีจัดการธุรกรรม DNS ด้วยสิทธิ์แบบมีเงื่อนไขโดยใช้แฟล็ก --skip-soa-update

ข้อกำหนดเบื้องต้น

  • บัญชี Google
  • โปรเจ็กต์ Google Cloud ที่เปิดใช้การเรียกเก็บเงิน
  • ติดตั้งและกำหนดค่า Google Cloud CLI เวอร์ชันล่าสุด
  • ความเข้าใจพื้นฐานเกี่ยวกับแนวคิด DNS และ IAM

การตั้งค่า

ระยะเวลา: 03:00

เปิดใช้ Cloud DNS API

เข้าสู่ระบบ gcloud CLI และเปิดใช้ 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 Conditions กับบทบาท roles/dns.admin มาตรฐานได้โดยตรง แต่คุณต้องแยกการจัดการชุดระเบียนออกจากงานดูแลระบบอื่นๆ โดยใช้บทบาทที่กำหนดเอง 2 บทบาท ดังนี้

  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 Condition อนุญาตให้ผู้ใช้จัดการระเบียนที่เฉพาะเจาะจงเท่านั้น (เช่น 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

ลบทรัพยากรที่สร้างขึ้นในแล็บนี้เพื่อหลีกเลี่ยงค่าใช้จ่าย

# 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 Conditions
  • ใช้แฟล็ก --skip-soa-update เพื่ออนุญาตให้ผู้ใช้แบบมีเงื่อนไขทำการเปลี่ยนแปลงแบบเป็นชุด

อ่านเพิ่มเติม