Autorisations IAM précises pour les ensembles d'enregistrements Cloud DNS


Cet atelier pratique explique comment implémenter un contrôle des accès précis pour des ensembles d'enregistrements DNS individuels dans Cloud DNS à l'aide de conditions IAM et de rôles personnalisés.

Introduction

Cloud DNS est traditionnellement compatible avec la définition d'autorisations IAM au niveau du projet et de la zone gérée. Cela permet d'accéder à tous les enregistrements d'une zone. Cependant, pour les grandes entreprises, cela ne respecte pas le principe du moindre privilège.

Cet atelier pratique vous explique comment configurer des autorisations IAM par ensemble d'enregistrements dans Cloud DNS. Cette fonctionnalité vous permet de déléguer la gestion de sous-domaines ou de types d'enregistrements spécifiques à différentes équipes au sein d'une même zone gérée partagée.

Points abordés

  • Utiliser des conditions IAM pour restreindre la gestion des enregistrements DNS.
  • Créer des rôles personnalisés (pourquoi et comment).
  • Déléguer des sous-domaines et des types d'enregistrements spécifiques (par exemple, A, MX).
  • Gérer les transactions DNS avec des autorisations conditionnelles à l'aide de l'option --skip-soa-update.

Prérequis

  • Un compte Google
  • Un projet Google Cloud avec facturation activée
  • La dernière version de Google Cloud CLI installée et configurée
  • Une compréhension de base des concepts DNS et IAM

Configuration

Durée : 03:00

Activer l'API Cloud DNS

Connectez-vous à gcloud CLI et activez l'API.

gcloud auth login
gcloud services enable dns.googleapis.com

Créer un projet de test

Si vous n'avez pas de projet prêt, créez-en un maintenant et définissez votre configuration gcloud sur le projet afin que toutes les commandes ciblent ce projet.

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

Comprendre les approches

Durée : 02:00

Pour modifier correctement les enregistrements DNS, le compte principal doit être autorisé à effectuer à la fois la modification de l'enregistrement et les opérations associées sur les ressources de modification Change.

Vous pouvez configurer cela de deux manières :

Vous pouvez lier la condition IAM directement au rôle standard roles/dns.admin. Pour prendre en charge à la fois les modifications d'enregistrement et les opérations sur les ressources de modification, vous utilisez une condition CEL plus complète qui accorde l'accès aux ressources d'ensemble d'enregistrements requises.

  • Autorisation : autorise toutes les autres actions d'administration DNS. Cela équivaut à l'option 2 si le rôle complémentaire contient toutes les autres autorisations d'administration standard. cel (resource.type == 'dns.googleapis.com/ResourceRecordSet' && <RRSET_CONDITION>) || (resource.type != 'dns.googleapis.com/ResourceRecordSet')
  • Restriction : n'autorise que les modifications d'ensemble d'enregistrements et les opérations sur les ressources de modification. Les autres actions d'administration, y compris la liste des ensembles d'enregistrements (dns.resourceRecordSets.list) et la description de la zone gérée, sont bloquées. cel (resource.type == 'dns.googleapis.com/ResourceRecordSet' && <RRSET_CONDITION>) || (resource.type == 'dns.googleapis.com/Change')

Cette approche est recommandée, car elle ne nécessite pas de créer ni de gérer des rôles personnalisés.

Option 2 : Approche avec rôle personnalisé

Si vous préférez des conditions plus simples, vous pouvez séparer la gestion des ensembles d'enregistrements des autres tâches d'administration à l'aide de deux rôles personnalisés :

  1. DnsRecordSetAdmin : contient les autorisations permettant de créer, supprimer, obtenir et mettre à jour des ensembles d'enregistrements de ressources. Ce rôle sera attribué de manière conditionnelle.
  2. DnsNonRecordSetAdmin : contient toutes les autres autorisations d'administration DNS (comme la gestion des zones, la liste des enregistrements et l'affichage des détails du projet). Ce rôle sera attribué de manière inconditionnelle.

Créer les rôles personnalisés

Durée : 05:00

[!NOTE] Cette étape n'est requise que si vous utilisez l'option 2 : Approche avec rôle personnalisé. Si vous utilisez l'option 1 : Approche avec rôle standard, vous pouvez ignorer cette étape.

Exécutez les commandes suivantes pour créer les rôles personnalisés requis dans votre projet.

Définir les ensembles d'autorisations

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

Créer les rôles dans 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}"

Scénario 1 : Correspondance exacte des enregistrements

Durée : 05:00

Dans ce scénario, vous souhaitez accorder à une équipe l'autorisation de gérer uniquement l'enregistrement A pour api.example.com..

Créer une zone gérée

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

Créer un compte de service de test

Vous utiliserez ce compte de service pour vérifier les autorisations restreintes.

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"

Appliquer la stratégie IAM conditionnelle

Choisissez l'une des options suivantes pour appliquer la stratégie.

Cette option utilise le rôle standard dns.admin avec une condition permissive.

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

Option 2 : Approche avec rôle personnalisé

Cette option utilise les rôles personnalisés que vous avez créés à l'étape précédente.

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

Vérifier la restriction

Essayez de créer l'enregistrement autorisé, puis essayez-en un non autorisé.

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

Scénario 2 : Délégation de sous-domaine

Durée : 05:00

Accordons maintenant l'autorisation de gérer n'importe quel enregistrement dans le sous-domaine p.example.com..

Mettre à jour la stratégie IAM

Choisissez l'une des options suivantes pour mettre à jour la stratégie.

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

Option 2 : Approche avec rôle personnalisé

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

Vérifier la délégation

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

Scénario 3 : Modifications et transactions par lot

Durée : 03:00

Lorsque vous utilisez des autorisations conditionnelles, il existe un détail important pour les transactions. Par défaut, les transactions DNS tentent de mettre à jour l'enregistrement SOA. Si votre condition IAM n'autorise les utilisateurs à gérer que des enregistrements spécifiques (comme api.example.com.), la transaction échouera, car l'utilisateur n'est pas autorisé à modifier l'enregistrement SOA.

L'option --skip-soa-update

Pour modifier les enregistrements autorisés dans une transaction, vous devez autoriser les mises à jour SOA en modifiant votre condition en conséquence (resource.name.endsWith('/SOA')) ou utiliser l'option --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}

Remarque : Si une transaction contient au moins une modification d'enregistrement non autorisée, l'ensemble de la transaction sera rejeté.

Libérer de l'espace

Durée : 01:00

Supprimez les ressources créées dans cet atelier pour éviter les frais.

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

Félicitations

Félicitations ! Vous avez appris à implémenter des autorisations IAM précises par ensemble d'enregistrements dans Cloud DNS.

Résumé des points abordés

  • Création de rôles personnalisés pour séparer les autorisations d'ensemble d'enregistrements des tâches d'administration au niveau de la zone.
  • Implémentation d'une condition de correspondance exacte pour des noms et des types d'enregistrements spécifiques.
  • Implémentation de la délégation de sous-domaine à l'aide de l'extraction de chaînes dans les conditions IAM.
  • Utilisation de l'option --skip-soa-update pour permettre aux utilisateurs conditionnels d'effectuer des modifications par lot.

Complément d'informations