В этом практическом занятии демонстрируется, как реализовать детальный контроль доступа к отдельным наборам DNS-записей в Cloud DNS с использованием условий IAM и пользовательских ролей.
Введение
Традиционно облачный DNS поддерживает настройку разрешений IAM на уровне проекта и управляемой зоны. Это обеспечивает широкий доступ ко всем записям в зоне. Однако для крупных предприятий это не соответствует «принципу минимальных привилегий».
В этом практическом занятии вы научитесь настраивать разрешения IAM для каждого набора записей в Cloud DNS. Эта функция позволяет делегировать управление определенными поддоменами или типами записей различным командам в рамках одной общей управляемой зоны.
Что вы узнаете
- Как использовать условия IAM для ограничения управления записями DNS.
- Зачем и как создавать пользовательские роли.
- Как делегировать управление поддоменами и конкретными типами записей (например: A, MX).
- Как обрабатывать DNS-транзакции с условными разрешениями с помощью флага
--skip-soa-update.
Предварительные требования
- Аккаунт Google
- Проект Google Cloud с включенной функцией выставления счетов.
- Установлена и настроена последняя версия Google Cloud CLI.
- Базовое понимание концепций DNS и IAM.
Настройка
Продолжительность: 03:00
Включите API облачного 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
Понимание подхода к пользовательским ролям
Продолжительность: 02:00
Нельзя напрямую привязать условия IAM к стандартной roles/dns.admin . Вместо этого необходимо отделить управление наборами записей от других административных задач, используя две пользовательские роли:
- DnsRecordSetAdmin : Предоставляет права на создание, удаление, получение и обновление наборов записей ресурсов. Эта роль будет предоставляться условно .
- 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
Удалите ресурсы, созданные в этой лабораторной работе, чтобы избежать списания средств.
# 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, позволяющий пользователям, действующим в определенных условиях, вносить пакетные изменения.