# DNS interne > **Pour qui :** le **mainteneur** du DNS interne. Le service DNS interne est la premiere capacite de plateforme. > **Plancher de resolution independant du DNS.** Le socle (`hosts_statiques`, dans > `serveur_debian`) genere `/etc/hosts` sur **chaque** VM depuis l'inventaire : tout > l'ecosysteme se resout par nom **meme serveur DNS eteint** (et au bootstrap, avant > que PowerDNS ne soit la). PowerDNS devient une **commodite** (zone, externe, > dynamique), plus un point de defaillance. ## Trois couches, et une seule est optionnelle > **Ce paragraphe decrivait le modele d'avant le 2026-08-24** — un Unbound *sur chaque VM*, > en opt-in. Ce n'est plus le cas : `client_resolveur` **n'installe plus rien**, et son > integration est **universelle**, pas elective. ```text 1. hosts_statiques le PLANCHER : /etc/hosts genere sur chaque VM depuis l'inventaire -> l'ecosysteme se resout DNS eteint. Jamais optionnel. 2. serveur_powerdns l'AUTORITATIF de la zone souveraine (un par ecosysteme) 3. serveur_resolveur le RECURSIF : UN seul Unbound pour tout le tenant, qui recurse depuis la racine et delegue la zone souveraine a PowerDNS client_resolveur l'integration : ecrit /etc/resolv.conf pour designer ce resolveur ``` **`client_resolveur` n'installe plus de demon** (2026-08-24). Il en posait un par VM — N demons identiques de ~21 Mo pour quelques centaines de requetes. Il ne fait plus qu'une chose : **ecrire `/etc/resolv.conf`**. Son integration est marquee `universelle: true`, et elle n'a **aucune exemption, pas meme l'hote qui porte le resolveur** : il se sert lui-meme. L'ancien nom (`client_unbound`) mentait des lors qu'il n'installait plus Unbound. **L'integration suit l'existence du service, elle ne se declare pas.** Aucun `serveur_resolveur` au plan rend `client_resolveur_actif` faux et le role ne touche a rien : l'ecosysteme garde la resolution d'amorcage de cloud-init. C'est un choix valide, pas une panne. ## Groupes ```text serveur_powerdns -> autoritatif interne (PowerDNS Authoritative) serveur_resolveur -> LE recursif du tenant (Unbound), un seul client_resolveur -> integration universelle : designe ce resolveur dans /etc/resolv.conf ``` ## Zone initiale La zone initiale est : ```text exemple.internal ``` Elle est definie dans : ```text instance/inventories//group_vars/serveur_powerdns.yml ``` ## Enregistrement automatique Le role `serveur_powerdns` genere la zone a partir de l'inventaire. Les hotes qui remplissent ces conditions sont ajoutes automatiquement : ```text hote dans hotes_actifs ansible_host defini ``` Exemple : ```text web-frontal-01 ansible_host=10.0.2.31 -> web-frontal-01.exemple.internal A 10.0.2.31 ``` Les enregistrements additionnels explicites sont dans `serveur_powerdns_records`. ## Backend PowerDNS Le premier jalon utilise le backend BIND de PowerDNS. Raison : - pas de dependance prematuree a PostgreSQL ; - zone lisible et generee par Ansible ; - idempotence simple ; - bon point de depart pour la supervision. Quand `serveur_postgresql` sera stable, il sera possible de migrer vers un backend SQL si le besoin operationnel le justifie. ## La bascule de `/etc/resolv.conf` est protegee Le role `client_resolveur` ne bascule `/etc/resolv.conf` qu'apres avoir verifie que le resolveur repond **deja** — pour l'interne *et* pour l'Internet : ```yaml client_resolveur_apply: true client_resolveur_confirm: true ``` Sans ces deux variables, le role prépare Unbound mais ne modifie pas `/etc/resolv.conf`. Cette protection est volontaire : une mauvaise configuration DNS peut couper la resolution de noms. C'est la dependance la plus dangereuse du lot — basculer un hote sur un resolveur qui n'est pas encore pret le rend **muet**, et le runner qui devrait reparer tombe avec les autres. Le playbook de groupe applique donc l'hote qui *porte* le resolveur avant ceux qui s'y adressent, et la preuve **P44** refuse tout ecart entre cette declaration et lui. ## Le piege qui a coute deux jours : la racine signee nie notre TLD `internal.` n'est **pas delegue dans la racine**, qui est signee : elle rend donc une preuve NXDOMAIN *validee* pour ce TLD. Or `harden-below-nxdomain` — **actif par defaut** dans Unbound — tient ce « non » pour prouve et repond NXDOMAIN pour **tout** nom sous `internal.` depuis son cache, **sans jamais interroger la `stub-zone`** declaree plus bas. La delegation etait correcte. L'autoritatif repondait juste. Pas une requete ne lui parvenait. Ce qui declenche l'empoisonnement : n'importe quelle question sur un nom inexistant sous `internal.` — y compris la zone d'**un autre ecosysteme**, que ce resolveur ne sert pas et va donc chercher a la racine. Sur un resolveur partage, ca arrive en permanence. Et la panne parait **intermittente** : au redemarrage le cache est vide, tout fonctionne, on conclut que c'est regle. Le remede mesure (2026-09-02) est `harden-below-nxdomain: no` dans `roles/serveur_resolveur/templates/setops.conf.j2` — **pas** `aggressive-nsec`, qui traite un autre symptome. ## Surveillance a prevoir Les premiers checks utiles : - service `pdns` actif ; - port UDP/TCP 53 disponible ; - SOA de `exemple.internal` resoluble ; - enregistrement `ns1.exemple.internal` resoluble ; - enregistrements des hotes actifs presents ; - serial de zone attendu ; - latence de resolution.