bertvv.bind

Rôle Ansible BIND

Statut des Actions

Un rôle Ansible pour configurer ISC BIND comme serveur DNS autoritaire uniquement pour plusieurs domaines. Les responsabilités de ce rôle sont de :

  • installer BIND
  • mettre en place le fichier de configuration principal (serveur primaire/secondaire/forwarder)
  • créer des fichiers de zone pour la recherche directe et inverse

Ce rôle supporte plusieurs zones directes et inverses, y compris pour IPv6. Bien que l’activation de la récursivité soit supportée (mais fortement déconseillée), envisagez d'utiliser un autre rôle si vous souhaitez configurer un serveur de noms avec mise en cache ou redirection.

Si vous aimez/utilisez ce rôle, merci de lui attribuer une étoile et de le noter sur la page Ansible Galaxy du rôle. Merci !

Consultez le journal des modifications pour les changements notables entre les versions.

AVERTISSEMENT : Si vous utilisez ce rôle depuis avant v5.0.0, veuillez vérifier le journal des modifications pour des informations importantes sur les changements incompatibles. Les anciens playbooks échoueront si vous mettez à jour vers v5.0.0.

Plateformes supportées

Ce rôle peut être utilisé sur plusieurs plateformes. Consultez meta/main.yml pour une liste à jour. Nous essayons de mettre en place des tests automatisés pour chaque plateforme supportée (voir .ci.yml), mais cela n'est pas toujours possible.

Voici quelques remarques sur les rôles supportés qui ne sont pas inclus dans les tests automatisés :

  • Arch Linux et FreeBSD devraient fonctionner, mais pour l’instant, il n’est pas possible de tester le rôle sur ces distributions, car aucune image Docker adéquate n'est disponible.
  • CentOS 6 devrait fonctionner, mais les tests d'idempotence échouent même si BIND est installé avec succès et que les tests d'acceptation réussissent.

Exigences

Les paquets python-netaddr (nécessaire pour le filtre ipaddr) et dnspython doivent être installés sur le nœud de gestion.

Variables du rôle

Variable Par défaut Commentaires (type)
bind_acls [] Une liste de définitions d'ACL, qui sont des mappages avec les clés name: et match_list:. Voir ci-dessous pour un exemple.
bind_allow_query ['localhost'] Une liste des hôtes autorisés à interroger ce serveur DNS. Définit à ['any'] pour autoriser tous les hôtes
bind_allow_recursion ['any'] Semblable à bind_allow_query, cette option s'applique aux requêtes récursives.
bind_check_names [] Vérifie la conformité des noms d'hôtes avec RFC 952 et RFC 1123 et prend l'action définie (ex. warn, ignore, fail).
bind_dns_keys [] Une liste de clés de liaison, qui sont des mappages avec les clés name:, algorithm: et secret:. Voir ci-dessous pour un exemple.
bind_dns64 false Si true, support pour DNS64 est activé
bind_dns64_clients ['any'] Une liste de clients auxquels la fonction DNS64 s'applique (peut être n'importe quel ACL)
bind_dnssec_enable true Si true, DNSSEC est activé
bind_dnssec_validation true Si true, la validation DNSSEC est activée
bind_extra_include_files [] Une liste de fichiers de configuration personnalisés à inclure depuis le fichier de configuration principal
bind_forward_only false Si true, BIND est configuré comme serveur de noms avec mise en cache
bind_forwarders [] Une liste de serveurs de noms vers lesquels des requêtes DNS doivent être redirigées.
bind_listen_ipv4 ['127.0.0.1'] Une liste des adresses IPv4 de l'interface réseau à écouter. Définit à ['any'] pour écouter sur toutes les interfaces.
bind_listen_ipv4_port [53] Une liste des numéros de port à écouter pour les adresses IPv4.
bind_listen_ipv6 ['::1'] Une liste des adresses IPv6 de l'interface réseau à écouter
bind_listen_ipv6_port [53] Une liste des numéros de port à écouter pour les adresses IPv6.
bind_log data/named.run Chemin vers le fichier journal
bind_other_logs - Une liste des canaux de journalisation à configurer, avec un mappage séparé pour chaque zone, avec des détails pertinents
bind_query_log - Un mappage avec les clés file: (ex. data/query.log), versions:, size:. Lorsqu'il est défini, cela activera le journal de requêtes
bind_recursion false Détermine si les demandes pour lesquelles le serveur DNS n'est pas autoritaire doivent être redirigées†.
bind_rrset_order random Définit l'ordre pour la rotation DNS (soit random, soit cyclic)
bind_statistics_channels false Si true, BIND est configuré avec une clause statistics-channels (actuellement ne supporte que l'écoute sur une seule interface)
bind_statistics_allow ['127.0.0.1'] Une liste des hôtes qui peuvent accéder aux statistiques du serveur
bind_statistics_host 127.0.0.1 Adresse IP de l'interface réseau sur laquelle le service de statistiques doit écouter
bind_statistics_port 8053 Port réseau sur lequel le service de statistiques doit écouter
bind_zone_dir - Lorsqu'il est défini, définit un chemin absolu personnalisé vers le répertoire du serveur (pour les fichiers de zone, etc.) au lieu de la valeur par défaut.
bind_key_mapping [] Primary: Keyname - mappage des clés TSIG à utiliser pour un primaire spécifique
bind_zones n/a Une liste de mappages avec des définitions de zone. Voir ci-dessous cette table pour des exemples
- allow_update ['none'] Une liste d'hôtes autorisés à mettre à jour dynamiquement cette zone DNS.
- also_notify - Une liste de serveurs qui recevront une notification lorsque le fichier de zone principal sera rechargé.
- create_forward_zones - Lorsqu'initialisé et défini sur false, la création de zones directes sera ignorée (ce qui entraîne une zone uniquement inverse)
- create_reverse_zones - Lorsqu'initialisé et défini sur false, la création de zones inverses sera ignorée (ce qui entraîne une zone uniquement directe)
- delegate [] Délégation de zone.
- forwarders - Liste des redirections pour la zone de type forward
- hostmaster_email hostmaster L'adresse e-mail de l'administrateur système pour la zone
- hosts [] Définitions des hôtes.
- ipv6_networks [] Une liste des réseaux IPv6 qui font partie du domaine, en notation CIDR (ex. 2001:db8::/48)
- mail_servers [] Une liste de mappages (avec les clés name: et preference:) spécifiant les serveurs de messagerie pour ce domaine.
- name_servers [ansible_hostname] Une liste des serveurs DNS pour ce domaine.
- name example.com Le nom de domaine
- naptr [] Une liste de mappages avec les clés name:, order:, pref:, flags:, service:, regex: et replacement: spécifiant les enregistrements NAPTR.
- networks ['10.0.2'] Une liste des réseaux qui font partie du domaine
- other_name_servers [] Une liste des serveurs DNS en dehors de ce domaine.
- primaries - Une liste des serveurs DNS primaires pour cette zone.
- services [] Une liste de services à annoncer par les enregistrements SRV
- text [] Une liste de mappages avec les clés name: et text:, spécifiant les enregistrements TXT. text: peut être une liste ou une chaîne.
- caa [] Une liste de mappages avec les clés name: et text:, spécifiant les enregistrements CAA. text: peut être une liste ou une chaîne.
- type - Type de zone optionnel. Si non spécifié, l'auto-détection sera utilisée. Les valeurs possibles incluent primary, secondary ou forward
bind_zone_file_mode 0640 Les permissions de fichier pour le fichier de configuration principal (named.conf)
bind_zone_minimum_ttl 1D Champ TTL minimum dans l'enregistrement SOA.
bind_zone_time_to_expire 1W Champ temps d'expiration dans l'enregistrement SOA.
bind_zone_time_to_refresh 1D Champ temps de rafraîchissement dans l'enregistrement SOA.
bind_zone_time_to_retry 1H Champ temps de réessai dans l'enregistrement SOA.
bind_zone_ttl 1W Champ Time to Live dans l'enregistrement SOA.
bind_python_version - La version de Python qui doit être utilisée pour Ansible. Dépend de la distribution, soit 2 ou 3. Par défaut, c'est la version standard de l'OS.

† La meilleure pratique pour un serveur de noms autoritaire est de laisser la récursivité désactivée. Cependant, dans certains cas il peut être nécessaire de l'activer.

Variables minimales pour une zone fonctionnelle

Pour configurer un serveur de noms autoritaire accessible aux clients, vous devez au moins définir les variables suivantes :

Variable Primaire Secondaire Forward
bind_allow_query V V V
bind_listen_ipv4 V V V
bind_zones V V V
- hosts V -- --
- name_servers V -- --
- name V V --
- networks V V V
- primaries V V --
- forwarders -- -- V

Définitions de domaines

bind_zones:
  # Exemple d'une zone primaire (hosts: et name_servers: sont définis)
  - name: mydomain.com           # Nom de domaine
    create_reverse_zones: false  # Ignorer la création de zones inverses
    primaries:
      - 192.0.2.1                # Serveur(s) primaire(s) pour cette zone
    name_servers:
      - pub01.mydomain.com.
      - pub02.mydomain.com.
    hosts:
      - name: pub01
        ip: 192.0.2.1
        ipv6: 2001:db8::1
        aliases:
          - ns1
      - name: pub02
        ip: 192.0.2.2
        ipv6: 2001:db8::2
        aliases:
          - ns2
      - name: '@'                # Permet "http://mydomain.com/"
        ip:
          - 192.0.2.3            # Plusieurs adresses IP pour un seul hôte
          - 192.0.2.4            #   entraîne la rotation DNS
        sshfp:                   # Empreinte de sécurité
          - "3 1 1262006f9a45bb36b1aa14f45f354b694b77d7c3"
          - "3 2 e5921564252fe10d2dbafeb243733ed8b1d165b8fa6d5a0e29198e5793f0623b"
        ipv6:
          - 2001:db8::2
          - 2001:db8::3
        aliases:
          - www
      - name: priv01             # Cette IP est dans un autre sous-réseau, ce qui entraîne
        ip: 10.0.0.1             #   plusieurs zones inverses
      - name: mydomain.net.
        aliases:
          - name: sub01
            type: DNAME          # Exemple d'enregistrement d'alias DNAME
    networks:
      - '192.0.2'
      - '10'
      - '172.16'
    delegate:
      - zone: foo
        dns: 192.0.2.1
    services:
      - name: _ldap._tcp
        weight: 100
        port: 88
        target: dc001
    naptr:                       # Enregistrement NAPTR, utilisé pour IP
      - name: "sip"              #   téléphonie
        order: 100
        pref: 10
        flags: "S"
        service: "SIP+D2T"
        regex: "!^.*$!sip:[email protected]!"
        replacement: "_sip._tcp.example.com."
  # Exemple minimal d'une zone secondaire
  - name: acme.com
    primaries:
      - 172.17.0.2
    networks:
      - "172.17"
  # Exemple minimal d'une zone de redirection
  - name: acme.com
    forwarders:
      - 172.17.0.2
    networks:
      - "172.17"

Hôtes

Les noms des hôtes que ce serveur DNS doit résoudre peuvent être spécifiés dans bind_zones.hosts sous forme de liste de mappages avec les clés name:, ip:, aliases: et sshfp:. Les alias peuvent être des enregistrements CNAME (par défaut) ou DNAME.

Pour permettre d'accéder à http://example.com/, définissez le nom de votre serveur web sur '@' (doit être cité !). En syntaxe BIND, @ indique le nom de domaine lui-même.

Si vous souhaitez spécifier plusieurs adresses IP pour un hôte, ajoutez des entrées à bind_zones.hosts avec le même nom (par exemple, priv01 dans l'extrait de code). Cela entraîne plusieurs enregistrements A/AAAA pour cet hôte et permet la rotation DNS, une technique simple d'équilibrage de charge. L'ordre dans lequel les adresses IP sont retournées peut être configuré avec la variable du rôle bind_rrset_order.

Réseaux

Comme vous pouvez le constater, tous les hôtes ne sont pas dans le même sous-réseau. Ce rôle générera des zones de recherche inversées appropriées pour chaque sous-réseau. Tous les sous-réseaux doivent être spécifiés dans bind_zones.networks, sinon l'hôte ne recevra pas d'enregistrement PTR pour la recherche inversée.

Notez que seule la partie réseau doit être spécifiée ici ! Lors de la spécification d'une adresse IP de classe B (par exemple "172.16") dans un fichier de variable, elle doit être citée. Sinon, le parser Yaml l'interprétera comme un nombre à virgule flottante.

Sur la base de l'idée et des exemples détaillés sur https://linuxmonk.ch/wordpress/index.php/2016/managing-dns-zones-with-ansible/ pour le package gdnsd, les fichiers de zone sont entièrement idempotents, et donc ne sont mis à jour que si le contenu "réel" change.

Types de zone et auto-détection des types de zone

Le type de zone est un paramètre optionnel qui définit si le type de zone doit être de type primary, secondary ou forward. Lorsque le paramètre type est omis, le type de zone sera autodétecté en fonction de l'intersection des adresses IP des hôtes et de l'enregistrement primaries lors de la configuration d'une zone primaire ou secondaire. Lorsque primaries n'est pas défini et que forwarders est défini, le type de zone sera défini sur forward.

La fonctionnalité d'auto-détection de zone est particulièrement utile lors du déploiement d'une infrastructure DNS multi-sites. Il est pratique d'avoir des définitions de bind_zones "partagées" dans un seul fichier d'inventaire de groupe pour tous les serveurs DNS (ex. group_vars\dns.yml). Une telle approche permet de changer de rôles entre serveurs primaire et secondaire en mettant à jour uniquement l'enregistrement primaries et en relançant le playbook. L'auto-détection de type de zone peut être testée avec le scénario de molécule "shared_inventory" en exécutant : molecule test --scenario-name shared_inventory


REMARQUE

  • BIND ne prend pas en charge la configuration multi-maîtres automatisée et la liste primaries ne doit contenir qu'une seule entrée.
  • Lorsque l'enregistrement primaries est mis à jour pour changer un primaire en rôle secondaire, les zones seront supprimées et recréées à partir du modèle car nous ne prenons pas encore en charge les mises à jour dynamiques pour les zones existantes.

Les types de zone peuvent également être définis explicitement dans l'inventaire par hôte pour éviter l'auto-détection :

# Serveur primaire
bind_zones:
  - name: mydomain.com
    type: primary
    primaries:
      - 192.0.2.1
...
# Serveur secondaire
bind_zones:
  - name: mydomain.com
      type: secondary
      primaries:
        - 192.0.2.1
...
# Serveur de redirection
bind_zones:
  - name: anotherdomain.com
      type: forward
      forwarders:
        - 192.0.3.1

Délégation de zone

Pour déléguer une zone à un serveur DNS, il suffit de créer un enregistrement NS (sous delegation) qui équivaut à :

foo IN NS 192.0.2.1

Enregistrements de service

Les enregistrements de service (SRV) peuvent être ajoutés avec les services. Cela doit être une liste de mappages avec les clés obligatoires name: (nom du service), target: (hôte fournissant le service), port: (port TCP/UDP du service) et les clés optionnelles priority: (par défaut = 0) et weight: (par défaut = 0).

ACLs

Les ACLs peuvent être définies ainsi :

bind_acls:
  - name: acl1
    match_list:
      - 192.0.2.0/24
      - 10.0.0.0/8

Les noms des ACL seront ajoutés à la clause allow-transfer dans les options globales.

Clés de liaison

Les clés de liaison peuvent être définies comme suit :

bind_dns_keys:
  - name: primary_key
    algorithm: hmac-sha256
    secret: "azertyAZERTY123456"
bind_extra_include_files:
  - "{{ bind_auth_file }}"

astuce : Le fichier d'inclusion supplémentaire doit être défini en tant que variable ansible car le fichier dépend de l'OS

Ceci sera défini dans un fichier "{{ bind_auth_file }}" (ex. /etc/bind/auth_transfer.conf pour Debian) qui doit être ajouté à la liste des variables bind_extra_include_files.

Utilisation de TSIG pour l'autorisation de transfert de zone (XFR)

Pour autoriser le transfert de zone entre serveurs primaire et secondaire basé sur une clé TSIG, définissez le mappage dans la variable bind_key_mapping :

bind_key_mapping:
  primary_ip: TSIG-keyname

Chaque primaire peut avoir une seule clé (par vue).

Une vérification sera effectuée pour s'assurer que la clé est bien présente dans le mappage bind_dns_keys. Cela ajoutera une déclaration de serveur pour l’a dans le bind_auth_file sur un serveur secondaire contenant la clé spécifiée.

Dépendances

Pas de dépendances.

Exemples de Playbooks

Consultez les playbooks de test et l'inventaire pour un exemple élaboré qui met en valeur la plupart des fonctionnalités.

Inventaire standard

❯ tree --dirsfirst molecule/default
molecule/default
├── group_vars
│   └── all.yml
├── host_vars
│   ├── ns1.yml    # Primaire
│   ├── ns2.yml    # Secondaire
│   └── ns3.yml    # De redirection
├── converge.yml
...

Inventaire partagé

Variables communes entre les serveurs primaire et secondaire définies dans all.yml

❯ tree --dirsfirst molecule/shared_inventory
molecule/shared_inventory
├── group_vars
│   └── all.yml
├── converge.yml
...

Tests

Ce rôle est testé à l'aide de Ansible Molecule. Les tests sont lancés automatiquement sur Github Actions après chaque commit et PR.

Cette configuration de molécule effectuera :

  • Exécute Yamllint et Ansible Lint
  • Crée trois conteneurs Docker, un primaire (ns1), un secondaire (ns2) et un de redirection(ns3) - scénario de molécule par défaut
  • Effectue une vérification de syntaxe
  • Applique le rôle avec un playbook de test et vérifie l'idempotence
  • Exécute les tests d'acceptation avec le playbook de vérification
  • Crée deux conteneurs Docker supplémentaires, un primaire(ns4) et un secondaire (ns5) et exécute le scénario shared_inventory

Ce processus est répété pour toutes les distributions Linux prises en charge.

Environnement de test local

Pour exécuter les tests d'acceptation sur ce rôle localement, vous pouvez installer les outils nécessaires sur votre machine, ou utiliser cette configuration reproductible dans une VM VirtualBox (mise en place avec Vagrant): https://github.com/bertvv/ansible-testenv.

Étapes pour installer manuellement les outils :

  1. Docker doit être installé sur votre machine
  2. Comme recommandé par Molecule, créez un environnement virtuel python
  3. Installez les outils logiciels python3 -m pip install molecule molecule-docker docker netaddr dnspython yamllint ansible-lint
  4. Allez à la racine du répertoire du rôle et exécutez molecule test

Molecule supprime automatiquement les conteneurs après un test. Si vous souhaitez vérifier les conteneurs vous-même, exécutez molecule converge suivi de molecule login --host HOSTNAME.

Les conteneurs Docker sont basés sur des images créées par Jeff Geerling, spécifiquement pour les tests d'Ansible (cherchez des images nommées geerlingguy/docker-DISTRO-ansible). Vous pouvez utiliser n'importe laquelle de ses images, mais seules les distributions mentionnées dans meta/main.yml sont supportées.

La configuration par défaut démarrera trois conteneurs Centos 8 (la plateforme principale prise en charge à ce jour). Choisissez une autre distribution en définissant la variable MOLECULE_DISTRO avec la commande, par exemple :

MOLECULE_DISTRO=debian9 molecule test

ou

MOLECULE_DISTRO=debian9 molecule converge

Vous pouvez exécuter les tests d'acceptation sur tous les serveurs avec molecule verify.

Les tests de vérification sont effectués à l'aide du module "dig" en interrogeant les enregistrements DNS et en validant les réponses. Cela nécessite une communication réseau directe entre le nœud contrôleur Ansible (votre machine exécutant Ansible) et le conteneur Docker cible.


REMARQUE

Les tests de vérification de Molecule échoueront si Docker fonctionne sur macOS, car macOS ne peut pas accéder directement à l'IP des conteneurs. C'est un problème connu. Voir #2670.

Solution de contournement :

  1. Exécutez le linter de molécule : molecule lint
  2. Provisionnez les conteneurs : molecule converge
  3. Connectez-vous au conteneur : molecule login --host ns1
  4. Allez dans le répertoire du rôle : cd /etc/ansible/roles/bertvv.bind
  5. Exécutez le playbook de vérification :
ansible-playbook -c local -i "`hostname`," -i molecule/default/inventory.ini molecule/default/verify.yml
  1. Répétez les étapes 2-4 pour ns2 et ns3

Licence

BSD

Contributeurs

Ce rôle n'aurait pu être réalisé grâce qu'aux contributions de nombreux. Si vous avez une idée pour l'améliorer encore, n'hésitez pas à partager !

Les problèmes, demandes de fonctionnalités, idées, suggestions, etc. peuvent être publiés dans la section Issues.

Les demandes de tirage sont également les bienvenues. Merci de créer une branche de sujet pour vos modifications proposées. Si vous ne le faites pas, cela créera des conflits dans votre fork après la fusion. N'hésitez pas à vous ajouter à la liste des contributeurs ci-dessous dans votre PR !

Mainteneurs :

Contributeurs :

À propos du projet

Sets up ISC BIND as an authoritative DNS server for one or more domains (primary and/or secondary).

Installer
ansible-galaxy install bertvv.bind
Licence
other
Téléchargements
406.9k
Propriétaire
Hi! My contribs are often related to my job (teaching Linux), but are mostly done in my free time. I can't always respond quickly to PRs and Issues. Sorry!