يوضّح هذا الدرس التطبيقي حول الترميز كيفية تنفيذ ميزة "التحكّم الدقيق في الوصول" لمجموعات سجلّات نظام أسماء النطاقات الفردية ضِمن Cloud DNS باستخدام "شروط إدارة الهوية وإمكانية الوصول" والأدوار المخصّصة.
مقدمة
يتيح Cloud DNS عادةً ضبط أذونات IAM على مستوى المشروع والمنطقة المُدارة، ما يوفّر إمكانية وصول واسعة إلى جميع السجلات ضِمن المنطقة. ومع ذلك، لا يستوفي هذا الإجراء "مبدأ الحد الأدنى من الامتيازات" للمؤسسات الكبيرة.
سيرشدك هذا الدرس التطبيقي حول الترميز إلى كيفية ضبط أذونات إدارة الهوية وإمكانية الوصول على مستوى كل مجموعة سجلات في Cloud DNS. تتيح لك هذه الميزة تفويض إدارة نطاقات فرعية أو أنواع سجلات معيّنة إلى فِرق مختلفة ضمن منطقة مُدارة مشتركة واحدة.
ما ستتعلمه
- كيفية استخدام "شروط إدارة الهوية وإمكانية الوصول" (IAM) لتقييد إدارة سجلّات نظام أسماء النطاقات
- أسباب إنشاء أدوار مخصّصة وطريقة إنشائها
- كيفية تفويض النطاقات الفرعية وأنواع السجلات المحددة (على سبيل المثال: A وMX)
- كيفية التعامل مع معاملات نظام أسماء النطاقات باستخدام أذونات شَرطية باستخدام العلامة
--skip-soa-update
المتطلبات الأساسية
- حساب على Google
- مشروع Google Cloud تم تفعيل الفوترة فيه
- تثبيت أحدث إصدار من واجهة سطر الأوامر (CLI) في Google Cloud وإعداده
- فهم أساسي لمفاهيم نظام أسماء النطاقات وإدارة الهوية وإمكانية الوصول
الإعداد
المدة: 03:00
تفعيل Cloud DNS API
سجِّل الدخول إلى gcloud CLI وفعِّل واجهة برمجة التطبيقات.
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
لتعديل سجلّات نظام أسماء النطاقات بنجاح، يجب أن يكون لدى الجهة الرئيسية إذن بتنفيذ كلّ من تعديل السجلّ والعمليات المرتبطة به في تغيير الموارد.
يمكنك ضبط هذا الإعداد بإحدى الطريقتَين التاليتَين:
الخيار 1: طريقة الدور العادي (مقترَحة)
يمكنك ربط شرط IAM مباشرةً بدور roles/dns.admin العادي. ولإتاحة تعديل السجلات وتنفيذ العمليات على موارد Change، يمكنك استخدام شرط CEL أكثر شمولاً يمنح إذن الوصول إلى الموارد المطلوبة غير مجموعة السجلات.
- متساهل: يسمح بجميع الإجراءات الإدارية الأخرى لنظام أسماء النطاقات. ويعادل هذا الخيار الخيار 2 إذا كان الدور التكميلي يتضمّن جميع أذونات المشرف العادية الأخرى.
cel (resource.type == 'dns.googleapis.com/ResourceRecordSet' && <RRSET_CONDITION>) || (resource.type != 'dns.googleapis.com/ResourceRecordSet') - تقييدية: لا تسمح إلا بتعديلات مجموعات السجلات وعملياتها على موارد التغيير. يتم حظر الإجراءات الإدارية الأخرى، بما في ذلك إدراج مجموعات السجلات (
dns.resourceRecordSets.list) ووصف المنطقة المُدارة.cel (resource.type == 'dns.googleapis.com/ResourceRecordSet' && <RRSET_CONDITION>) || (resource.type == 'dns.googleapis.com/Change')
ننصحك باتّباع هذا الأسلوب لأنّه لا يتطلّب إنشاء أدوار مخصّصة وإدارتها.
الخيار 2: استخدام الأدوار المخصّصة
إذا كنت تفضّل شروطًا أبسط، يمكنك فصل إدارة مجموعات السجلات عن المهام الإدارية الأخرى باستخدام دورَين مخصّصَين:
- DnsRecordSetAdmin: يحتوي على أذونات لإنشاء مجموعات سجلات الموارد وحذفها والحصول عليها وتعديلها. سيتم منح هذا الدور بشكل مشروط.
- DnsNonRecordSetAdmin: يحتوي على جميع أذونات إدارة نظام أسماء النطاقات الأخرى (مثل إدارة المناطق وسرد السجلات وعرض تفاصيل المشروع). سيتم منح هذا الدور بدون شروط.
إنشاء الأدوار المخصّصة
المدة: 05:00
[!NOTE] هذه الخطوة مطلوبة فقط في حال استخدام الخيار 2: طريقة الدور المخصّص. إذا كنت تستخدم الخيار 1: نهج الأدوار العادية، يمكنك تخطّي هذه الخطوة.
نفِّذ الأوامر التالية لإنشاء الأدوار المخصّصة المطلوبة في مشروعك.
تحديد مجموعات الأذونات
# 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"
تطبيق سياسة إدارة الهوية وإمكانية الوصول الشرطية
حدِّد أحد الخيارات التالية لتطبيق السياسة.
الخيار 1: نهج الأدوار العادية (مُقترَح)
يستخدم هذا الخيار دور 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
الخيار 2: استخدام أدوار مخصّصة
يستخدم هذا الخيار الأدوار المخصّصة التي أنشأتها في الخطوة السابقة.
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}
السيناريو 2: تفويض النطاق الفرعي
المدة: 05:00
الآن، لنمنح الإذن بإدارة أي سجلّ ضمن النطاق الفرعي p.example.com..
تعديل سياسة "إدارة الهوية وإمكانية الوصول"
حدِّد أحد الخيارات التالية لتعديل السياسة.
الخيار 1: نهج الأدوار العادية (مُقترَح)
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
الخيار 2: استخدام أدوار مخصّصة
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}
السيناريو 3: التغييرات والمعاملات المجمّعة
المدة: 03:00
عند استخدام الأذونات الشرطية، هناك تفصيل مهمّ بشأن المعاملات.
تحاول معاملات نظام أسماء النطاقات تلقائيًا تعديل سجلّ 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
احذف الموارد التي تم إنشاؤها في هذا المختبر لتجنُّب تحمّل رسوم.
# 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}
تهانينا
تهانينا! لقد تعلّمت بنجاح كيفية تنفيذ أذونات "إدارة الهوية وإمكانية الوصول" دقيقة على مستوى كل مجموعة سجلات في Cloud DNS.
ملخّص المواضيع التي تناولناها
- تم إنشاء أدوار مخصّصة لفصل أذونات مجموعات السجلات عن مهام الإدارة على مستوى المنطقة.
- تم تنفيذ شرط المطابقة التامة لأسماء وأنواع سجلات معيّنة.
- تم تنفيذ تفويض النطاق الفرعي باستخدام استخراج السلسلة في شروط "إدارة الهوية وإمكانية الوصول".
- تم استخدام العلامة
--skip-soa-updateللسماح للمستخدمين المشروطين بإجراء تغييرات مجمّعة.