Permissões detalhadas do IAM do Cloud DNS para conjuntos de registros


Este codelab demonstra como implementar o controle de acesso refinado para conjuntos de registros DNS individuais no Cloud DNS usando condições do IAM e papéis personalizados.

Introdução

O Cloud DNS oferece suporte tradicionalmente à definição de permissões do IAM nos níveis de projeto e zona gerenciada. Isso fornece acesso amplo a todos os registros em uma zona. No entanto, para grandes empresas, isso não atende ao "princípio do privilégio mínimo".

Este codelab orienta você na configuração de permissões do IAM por conjunto de registros no Cloud DNS. Esse recurso permite delegar o gerenciamento de subdomínios ou tipos de registro específicos a diferentes equipes em uma única zona gerenciada compartilhada.

O que você vai aprender

  • Como usar as condições do IAM para restringir o gerenciamento de registros DNS.
  • Por que e como criar papéis personalizados.
  • Como delegar subdomínios e tipos de registro específicos (por exemplo, A, MX).
  • Como processar transações de DNS com permissões condicionais usando a flag --skip-soa-update.

Pré-requisitos

  • Uma Conta do Google
  • Tenha um projeto na nuvem do Google Cloud com o faturamento ativado.
  • A versão mais recente da CLI do Google Cloud instalada e configurada
  • Um conhecimento básico dos conceitos de DNS e IAM

Etapas da configuração

Duração: 03:00

Ativar a API Cloud DNS

Faça login na CLI gcloud e ative a API.

gcloud auth login
gcloud services enable dns.googleapis.com

Criar um projeto de teste

Se você não tiver um projeto pronto, crie um agora e defina a configuração da gcloud para o projeto. Assim, todos os comandos serão direcionados a ele.

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

Entender a abordagem de função personalizada

Duração: 02:00

Não é possível vincular condições do IAM diretamente ao papel padrão roles/dns.admin. Em vez disso, é necessário separar o gerenciamento de conjuntos de registros de outras tarefas administrativas usando duas funções personalizadas:

  1. DnsRecordSetAdmin: contém permissões para criar, excluir, receber e atualizar conjuntos de registros de recursos. Esse papel será concedido condicionalmente.
  2. DnsNonRecordSetAdmin: contém todas as outras permissões administrativas de DNS (como gerenciar zonas, listar registros e visualizar detalhes do projeto). Esse papel será concedido incondicionalmente.

Ao dividir esses papéis, você garante que as verificações de pré-requisitos realizadas pelo Cloud DNS (como dns.changes.create) sejam atendidas incondicionalmente, enquanto as modificações reais de registro são estritamente controladas pelas suas condições.

Como criar as funções personalizadas

Duração: 05:00

Execute os comandos a seguir para criar as funções personalizadas necessárias no seu projeto.

Definir os conjuntos de permissões

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

Criar as funções na 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}"

Cenário 1: correspondência exata de registro

Duração: 05:00

Nesse cenário, você quer conceder a uma equipe permissão para gerenciar apenas o registro A de api.example.com..

Criar uma zona gerenciada

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

Criar uma conta de serviço de teste

Você vai usar essa conta de serviço para verificar as permissões restritas.

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"

Aplicar a política condicional do IAM

Conceda DnsNonRecordSetAdmin incondicionalmente e DnsRecordSetAdmin com uma condição.

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

Verificar a restrição

Tente criar o registro permitido e, em seguida, um não autorizado.

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

Cenário 2: delegação de subdomínio

Duração: 05:00

Agora, vamos conceder permissão para gerenciar qualquer registro no subdomínio p.example.com..

Atualizar a política do IAM

Modifique a condição para usar resource.name.extract() para corresponder ao sufixo do subdomínio.

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

Verificar a delegação

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

Cenário 3: mudanças e transações em lote

Duração: 03:00

Ao usar permissões condicionais, há um detalhe importante para transações. Por padrão, as transações de DNS tentam atualizar o registro SOA. Se a condição do IAM permitir que os usuários gerenciem apenas registros específicos (como api.example.com.), a transação vai falhar porque o usuário não está autorizado a modificar o registro SOA.

A flag --skip-soa-update

Para modificar registros permitidos em uma transação, permita atualizações de SOA modificando sua condição de acordo (resource.name.endsWith('/SOA')) ou use a flag --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}

Observação: se uma transação contiver até mesmo uma modificação de registro não autorizada, toda a transação será rejeitada.

Limpar

Duração: 01:00

Exclua os recursos criados neste laboratório para evitar cobranças.

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

Parabéns

Parabéns! Você aprendeu a implementar permissões do IAM granulares por conjunto de registros no Cloud DNS.

Resumo do que abordamos

  • Criamos funções personalizadas para separar as permissões do conjunto de registros das tarefas administrativas no nível da zona.
  • Implementamos uma condição de correspondência exata para nomes e tipos de registros específicos.
  • Implementamos a delegação de subdomínio usando a extração de strings em condições do IAM.
  • Usamos a flag --skip-soa-update para permitir que usuários condicionais façam mudanças em lote.

Leia mais