این آزمایشگاه کد، نحوه پیادهسازی کنترل دسترسی دقیق برای مجموعه رکوردهای DNS منفرد در Cloud DNS با استفاده از شرایط IAM و نقشهای سفارشی را نشان میدهد.
مقدمه
Cloud DNS به طور سنتی از تنظیم مجوزهای IAM در سطوح پروژه و منطقه مدیریت شده پشتیبانی میکند. این امر دسترسی گستردهای به تمام رکوردهای درون یک منطقه را فراهم میکند. با این حال، برای شرکتهای بزرگ، این امر "اصل حداقل امتیاز" را برآورده نمیکند.
این آزمایشگاه کد شما را در پیکربندی مجوزهای IAM به ازای هر رکورد در Cloud DNS راهنمایی میکند. این ویژگی به شما امکان میدهد مدیریت زیردامنهها یا انواع رکوردهای خاص را به تیمهای مختلف در یک منطقه مدیریتشده مشترک واگذار کنید.
آنچه یاد خواهید گرفت
- نحوه استفاده از شرایط IAM برای محدود کردن مدیریت رکورد DNS.
- چرا و چگونه نقشهای سفارشی ایجاد کنیم؟
- نحوه واگذاری زیر دامنهها و انواع رکوردهای خاص (به عنوان مثال: A، MX).
- نحوه مدیریت تراکنشهای DNS با مجوزهای مشروط با استفاده از پرچم
--skip-soa-update.
پیشنیازها
- یک حساب گوگل
- یک پروژه گوگل کلود با قابلیت پرداخت صورتحساب
- آخرین نسخه Google Cloud CLI نصب و پیکربندی شده است
- درک اولیه از مفاهیم DNS و IAM
راهاندازی
مدت زمان: ۰۳:۰۰
فعال کردن API Cloud DNS
وارد رابط خط فرمان 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
درک رویکردها
مدت زمان: ۰۲:۰۰
برای تغییر موفقیتآمیز رکوردهای DNS، مدیر اصلی باید مجوز انجام اصلاح رکورد و عملیات مرتبط با آن را روی منابع تغییر (Change resources) داشته باشد.
شما میتوانید این را به یکی از دو روش زیر پیکربندی کنید:
گزینه ۱: رویکرد نقش استاندارد (توصیه میشود)
شما میتوانید شرط IAM را مستقیماً به نقش استاندارد roles/dns.admin متصل کنید. برای پشتیبانی از تغییرات رکورد و عملیات روی منابع Change، از یک شرط CEL جامعتر استفاده میکنید که دسترسی به منابع مورد نیاز غیر از مجموعه رکوردها را اعطا میکند.
- مجاز: به تمام اقدامات مدیریتی DNS دیگر اجازه میدهد. اگر نقش مکمل شامل تمام مجوزهای مدیریتی استاندارد دیگر باشد، این معادل گزینه ۲ است.
cel (resource.type == 'dns.googleapis.com/ResourceRecordSet' && <RRSET_CONDITION>) || (resource.type != 'dns.googleapis.com/ResourceRecordSet') - محدودکننده: فقط اجازه تغییرات و عملیات روی مجموعه رکوردها روی منابع Change داده میشود. سایر اقدامات مدیریتی، از جمله فهرست کردن مجموعه رکوردها (
dns.resourceRecordSets.list) و توصیف منطقه مدیریتشده، مسدود شدهاند.cel (resource.type == 'dns.googleapis.com/ResourceRecordSet' && <RRSET_CONDITION>) || (resource.type == 'dns.googleapis.com/Change')
این رویکرد توصیه میشود زیرا نیازی به ایجاد و مدیریت نقشهای سفارشی ندارد.
گزینه ۲: رویکرد نقش سفارشی
اگر شرایط سادهتری را ترجیح میدهید، میتوانید مدیریت مجموعه رکوردها را با استفاده از دو نقش سفارشی از سایر وظایف مدیریتی جدا کنید:
- DnsRecordSetAdmin : شامل مجوزهایی برای ایجاد، حذف، دریافت و بهروزرسانی مجموعه رکوردهای منابع است. این نقش به صورت مشروط اعطا میشود.
- DnsNonRecordSetAdmin : شامل تمام مجوزهای مدیریتی DNS دیگر (مانند مدیریت مناطق، فهرست کردن رکوردها و مشاهده جزئیات پروژه) است. این نقش بدون قید و شرط اعطا میشود.
ایجاد نقشهای سفارشی
مدت زمان: ۰۵:۰۰
[!نکته] این مرحله فقط در صورتی لازم است که از گزینه ۲: رویکرد نقش سفارشی استفاده میکنید . اگر از گزینه ۱: رویکرد نقش استاندارد استفاده میکنید، میتوانید از این مرحله صرف نظر کنید.
برای ایجاد نقشهای سفارشی مورد نیاز در پروژه خود، دستورات زیر را اجرا کنید.
تعریف مجموعه مجوزها
# 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}"
سناریوی ۱: تطبیق دقیق رکورد
مدت زمان: ۰۵:۰۰
در این سناریو، شما میخواهید به یک تیم اجازه دهید فقط رکورد 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 مشروط
برای اعمال پالیسی، یکی از گزینههای زیر را انتخاب کنید.
گزینه ۱: رویکرد نقش استاندارد (توصیه میشود)
این گزینه از نقش استاندارد dns.admin با یک شرط مجاز استفاده میکند.
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
گزینه ۲: رویکرد نقش سفارشی
این گزینه از نقشهای سفارشی که در مرحله قبل ایجاد کردهاید استفاده میکند.
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
محدودیت را تأیید کنید
سعی کنید رکورد مجاز را ایجاد کنید، سپس یک رکورد غیرمجاز را امتحان کنید.
# 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}
سناریو ۲: واگذاری زیردامنه
مدت زمان: ۰۵:۰۰
حالا، بیایید اجازه مدیریت هر رکوردی را در زیردامنه p.example.com. اعطا کنیم.
بهروزرسانی سیاست IAM
برای بهروزرسانی خطمشی، یکی از گزینههای زیر را انتخاب کنید.
گزینه ۱: رویکرد نقش استاندارد (توصیه میشود)
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
گزینه ۲: رویکرد نقش سفارشی
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
تأیید نمایندگی
# 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}
سناریو ۳: تغییرات و تراکنشهای دستهای
مدت زمان: ۰۳:۰۰
هنگام استفاده از مجوزهای مشروط، یک نکته مهم برای تراکنشها وجود دارد. به طور پیشفرض، تراکنشهای DNS تلاش میکنند رکورد SOA را بهروزرسانی کنند. اگر شرط IAM شما فقط به کاربران اجازه میدهد رکوردهای خاصی را مدیریت کنند (مانند api.example.com. )، تراکنش با شکست مواجه خواهد شد زیرا کاربر مجاز به تغییر رکورد SOA نیست.
پرچم --skip-soa-update
برای تغییر رکوردهای مجاز در یک تراکنش، باید یا با تغییر شرط خود (resource.name.endsWith('/SOA')) اجازه بهروزرسانی 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}
توجه: اگر یک تراکنش حاوی حتی یک تغییر رکورد غیرمجاز باشد، کل تراکنش رد خواهد شد.
تمیز کردن
مدت زمان: ۰۱:۰۰
منابع ایجاد شده در این آزمایشگاه را حذف کنید تا از اتهامات جلوگیری شود.
# 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}
تبریک میگویم
تبریک! شما با موفقیت یاد گرفتید که چگونه مجوزهای IAM را به صورت جزئی و بر اساس هر رکورد در Cloud DNS پیادهسازی کنید.
خلاصهای از آنچه پوشش دادیم
- نقشهای سفارشی ایجاد شد تا مجوزهای مجموعه رکوردها از وظایف مدیریتی سطح منطقه جدا شوند.
- شرط تطابق دقیق (Exact Match) برای نامها و انواع رکوردهای خاص پیادهسازی شد.
- پیادهسازی Subdomain Delegation با استفاده از استخراج رشته در شرایط IAM.
- از پرچم
--skip-soa-updateبرای اجازه دادن به کاربران مشروط برای انجام تغییرات دستهای استفاده شد.