Quyền IAM chi tiết của Cloud DNS cho Nhóm bản ghi


Lớp học lập trình này minh hoạ cách triển khai chế độ kiểm soát quyền truy cập chi tiết cho từng tập hợp bản ghi DNS trong Cloud DNS bằng cách sử dụng Điều kiện IAM và vai trò tuỳ chỉnh.

Giới thiệu

Theo truyền thống, Cloud DNS hỗ trợ việc thiết lập quyền IAM ở cấp dự án và vùng được quản lý. Điều này giúp bạn có quyền truy cập rộng rãi vào tất cả các bản ghi trong một vùng. Tuy nhiên, đối với các doanh nghiệp lớn, điều này không đáp ứng "nguyên tắc cấp ít quyền nhất".

Lớp học lập trình này sẽ hướng dẫn bạn cách định cấu hình quyền IAM cho mỗi tập hợp bản ghi trong Cloud DNS. Tính năng này cho phép bạn uỷ quyền quản lý các miền con hoặc loại bản ghi cụ thể cho các nhóm khác nhau trong một vùng được quản lý dùng chung.

Kiến thức bạn sẽ học được

  • Cách sử dụng Điều kiện IAM để hạn chế việc quản lý bản ghi DNS.
  • Lý do và cách tạo vai trò tuỳ chỉnh.
  • Cách uỷ quyền miền con và các loại bản ghi cụ thể (ví dụ: A, MX).
  • Cách xử lý các giao dịch DNS có quyền có điều kiện bằng cách sử dụng cờ --skip-soa-update.

Điều kiện tiên quyết

  • Tài khoản Google
  • Một dự án trên Google Cloud đã bật tính năng thanh toán
  • Đã cài đặt và định cấu hình phiên bản mới nhất của Google Cloud CLI
  • Hiểu biết cơ bản về các khái niệm DNS và IAM

Thiết lập

Thời lượng: 03:00

Bật Cloud DNS API

Đăng nhập vào gcloud CLI và bật API.

gcloud auth login
gcloud services enable dns.googleapis.com

Tạo một dự án thử nghiệm

Nếu bạn chưa có dự án nào, hãy tạo một dự án ngay bây giờ và đặt cấu hình gcloud cho dự án đó để tất cả các lệnh đều nhắm đến dự án đó.

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

Tìm hiểu về các phương pháp

Thời lượng: 02:00

Để sửa đổi bản ghi DNS thành công, thực thể chính phải có quyền thực hiện cả việc sửa đổi bản ghi và các thao tác liên quan trên tài nguyên Thay đổi.

Bạn có thể định cấu hình việc này theo một trong hai cách sau:

Bạn có thể liên kết trực tiếp điều kiện IAM với vai trò roles/dns.admin tiêu chuẩn. Để hỗ trợ cả việc sửa đổi bản ghi và các thao tác trên tài nguyên Thay đổi, bạn hãy sử dụng điều kiện CEL toàn diện hơn để cấp quyền truy cập vào các tài nguyên không phải tập hợp bản ghi bắt buộc.

  • Cho phép: Cho phép tất cả các thao tác quản trị DNS khác. Điều này tương đương với Cách 2 nếu vai trò bổ sung chứa tất cả các quyền quản trị tiêu chuẩn khác. cel (resource.type == 'dns.googleapis.com/ResourceRecordSet' && <RRSET_CONDITION>) || (resource.type != 'dns.googleapis.com/ResourceRecordSet')
  • Hạn chế: Chỉ cho phép sửa đổi tập hợp bản ghi và các thao tác trên tài nguyên Thay đổi. Các thao tác quản trị khác, bao gồm cả việc liệt kê tập hợp bản ghi (dns.resourceRecordSets.list) và mô tả vùng được quản lý, đều bị chặn. cel (resource.type == 'dns.googleapis.com/ResourceRecordSet' && <RRSET_CONDITION>) || (resource.type == 'dns.googleapis.com/Change')

Bạn nên sử dụng phương pháp này vì không cần tạo và quản lý vai trò tuỳ chỉnh.

Cách 2: Phương pháp vai trò tuỳ chỉnh

Nếu muốn có các điều kiện đơn giản hơn, bạn có thể tách việc quản lý tập hợp bản ghi khỏi các tác vụ quản trị khác bằng cách sử dụng hai vai trò tuỳ chỉnh:

  1. DnsRecordSetAdmin: Chứa các quyền tạo, xoá, nhận và cập nhật tập hợp bản ghi tài nguyên. Vai trò này sẽ được cấp có điều kiện.
  2. DnsNonRecordSetAdmin: Chứa tất cả các quyền quản trị DNS khác (chẳng hạn như quản lý vùng, liệt kê bản ghi và xem thông tin chi tiết về dự án). Vai trò này sẽ được cấp vô điều kiện.

Tạo vai trò tuỳ chỉnh

Thời lượng: 05:00

[!NOTE] Bạn chỉ cần thực hiện bước này nếu đang sử dụng Cách 2: Phương pháp vai trò tuỳ chỉnh. Nếu đang sử dụng Cách 1: Phương pháp vai trò tiêu chuẩn, bạn có thể bỏ qua bước này.

Chạy các lệnh sau để tạo các vai trò tuỳ chỉnh bắt buộc trong dự án của bạn.

Xác định tập hợp quyền

# 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"

Tạo vai trò trong 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}"

Trường hợp 1: Khớp chính xác bản ghi

Thời lượng: 05:00

Trong trường hợp này, bạn muốn cấp cho một nhóm quyền chỉ quản lý bản ghi A cho api.example.com..

Tạo một vùng được quản lý

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

Tạo một tài khoản dịch vụ thử nghiệm

Bạn sẽ sử dụng tài khoản dịch vụ này để xác minh các quyền bị hạn chế.

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"

Áp dụng chính sách IAM có điều kiện

Chọn một trong các cách sau để áp dụng chính sách.

Cách này sử dụng vai trò dns.admin tiêu chuẩn với điều kiện cho phép.

cat << EOF > policy.json
{
  "bindings": [
    {
      "role": "roles/dns.admin",
      "members": ["serviceAccount:${SA_EMAIL}"],
      "condition": {
        "expression": "(resource.type == 'dns.googleapis.com/ResourceRecordSet' && resource.name.endsWith('/rrsets/api.example.com./A')) || (resource.type != 'dns.googleapis.com/ResourceRecordSet')",
        "title": "Exact Record Match (Standard Role)"
      }
    }
  ],
  "version": 3
}
EOF

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

Cách 2: Phương pháp vai trò tuỳ chỉnh

Cách này sử dụng các vai trò tuỳ chỉnh mà bạn đã tạo ở bước trước.

cat << EOF > policy_custom.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 (Custom Roles)"
      }
    },
    {
      "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_custom.json

Xác minh hạn chế

Hãy thử tạo bản ghi được phép, sau đó thử tạo bản ghi không được phép.

# 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}

Trường hợp 2: Uỷ quyền miền con

Thời lượng: 05:00

Bây giờ, hãy cấp quyền quản lý mọi bản ghi trong miền con p.example.com..

Cập nhật chính sách IAM

Chọn một trong các cách sau để cập nhật chính sách.

cat << EOF > policy_subdomain.json
{
  "bindings": [
    {
      "role": "roles/dns.admin",
      "members": ["serviceAccount:${SA_EMAIL}"],
      "condition": {
        "expression": "(resource.type == 'dns.googleapis.com/ResourceRecordSet' && resource.name.extract('/rrsets/{name}/').endsWith('.p.example.com.')) || (resource.type != 'dns.googleapis.com/ResourceRecordSet')",
        "title": "Subdomain Delegation (Standard Role)"
      }
    }
  ],
  "version": 3
}
EOF

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

Cách 2: Phương pháp vai trò tuỳ chỉnh

cat << EOF > policy_subdomain_custom.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 (Custom Roles)"
      }
    },
    {
      "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_custom.json

Xác minh việc uỷ quyền

# 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}

Trường hợp 3: Các giao dịch và thay đổi hàng loạt

Thời lượng: 03:00

Khi sử dụng quyền có điều kiện, bạn cần lưu ý một chi tiết quan trọng đối với các giao dịch. Theo mặc định, các giao dịch DNS sẽ cố gắng cập nhật bản ghi SOA. Nếu điều kiện IAM của bạn chỉ cho phép người dùng quản lý các bản ghi cụ thể (chẳng hạn như api.example.com.), thì giao dịch sẽ không thành công vì người dùng không được phép sửa đổi bản ghi SOA.

Cờ --skip-soa-update

Để sửa đổi các bản ghi được phép trong một giao dịch, bạn nên cho phép cập nhật SOA bằng cách sửa đổi điều kiện cho phù hợp (resource.name.endsWith('/SOA')) hoặc sử dụng cờ --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}

Lưu ý: Nếu một giao dịch chứa dù chỉ một lần sửa đổi bản ghi không được phép, thì toàn bộ giao dịch đó sẽ bị từ chối.

Dọn dẹp

Thời lượng: 01:00

Xoá các tài nguyên đã tạo trong phòng thí nghiệm này để tránh bị tính phí.

# 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 (only if you created them in Option 2)
gcloud iam roles delete DnsRecordSetAdmin --project=$(gcloud config get-value project) || true
gcloud iam roles delete DnsNonRecordSetAdmin --project=$(gcloud config get-value project) || true

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

Xin chúc mừng

Xin chúc mừng! Bạn đã học thành công cách triển khai quyền IAM chi tiết cho mỗi tập hợp bản ghi trong Cloud DNS.

Tóm tắt nội dung chúng ta đã đề cập

  • Đã tạo vai trò tuỳ chỉnh để tách quyền tập hợp bản ghi khỏi các tác vụ quản trị ở cấp vùng.
  • Đã triển khai điều kiện Khớp chính xác cho các tên và loại bản ghi cụ thể.
  • Đã triển khai Uỷ quyền miền con bằng cách trích xuất chuỗi trong các điều kiện IAM.
  • Đã sử dụng cờ --skip-soa-update để cho phép người dùng có điều kiện thực hiện các thay đổi hàng loạt.

Tài liệu đọc thêm