2026-06-24 20:17:46 -04:00
|
|
|
---
|
|
|
|
|
- name: Installer PowerDNS Authoritative
|
|
|
|
|
ansible.builtin.apt:
|
|
|
|
|
name: "{{ serveur_powerdns_packages }}"
|
|
|
|
|
state: present
|
|
|
|
|
update_cache: true
|
|
|
|
|
cache_valid_time: 3600
|
|
|
|
|
|
|
|
|
|
- name: Créer le répertoire des zones PowerDNS
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
path: "{{ serveur_powerdns_zone_directory }}"
|
|
|
|
|
state: directory
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0755"
|
|
|
|
|
|
|
|
|
|
- name: Déployer la configuration du backend BIND
|
|
|
|
|
ansible.builtin.template:
|
|
|
|
|
src: setops-bind.conf.j2
|
|
|
|
|
dest: /etc/powerdns/pdns.d/setops-bind.conf
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0644"
|
|
|
|
|
notify: Validate and reload PowerDNS
|
|
|
|
|
|
|
|
|
|
- name: Déployer l'index des zones PowerDNS
|
|
|
|
|
ansible.builtin.template:
|
|
|
|
|
src: bindbackend.conf.j2
|
|
|
|
|
dest: "{{ serveur_powerdns_bind_config }}"
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0644"
|
|
|
|
|
notify: Validate and reload PowerDNS
|
|
|
|
|
|
site : le plancher survit au redemarrage, et la zone dit les vraies adresses
Le decoupage du site en quatre zones a deplace cinq machines. Ni le plancher
/etc/hosts ni la zone DNS n'avaient suivi. Quatre defauts, tous dans le moteur.
LE PLANCHER ETAIT EFFACE A CHAQUE DEMARRAGE — ET LE PREMIER CORRECTIF N'EN
ETAIT PAS UN.
`hosts_statiques` posait `99-setops-hosts.cfg` avec `manage_etc_hosts: false`,
pendant que `cloud_init` posait `99_setops.cfg` avec `true`. Dans `cloud.cfg.d`
l'ordre est LEXICAL et le dernier gagne : `-` vaut 0x2D, `_` vaut 0x5F. On a
donc retire la cle de `cloud_init` — le role qui POSSEDE le fichier decide —
puis renomme notre fragment `zz-` pour passer apres le `99_chezlepro.cfg` du
gabarit dore.
Et ca ne suffisait toujours pas. Redemarrage d'epreuve : plancher encore efface.
La cause reelle est ailleurs — Proxmox inscrit `manage_etc_hosts: true` dans la
USER-DATA de son lecteur cloud-init, et la user-data prime sur `cloud.cfg.d`
tout entier. Aucun fragment ne pouvait gagner ; renommer pour parler en dernier
ne servait a rien, le dernier mot n'appartenant pas a ce repertoire.
Ce que cloud-init regenere, il le regenere depuis `hosts.debian.tmpl` — le
gabarit le documente lui-meme. `hosts_statiques` le pose desormais avec le MEME
contenu que /etc/hosts, et une garde compare les deux a chaque passage.
Redemarrage d'epreuve : les neuf entrees sont la.
La garde precedente affirmait « conforme » en mesurant l'ordre lexical — vrai,
et sans rapport avec ce qui se passait. Une garde qui mesure la mauvaise chose
est pire qu'aucune.
LA ZONE DNS NE PUBLIAIT PAS LES NOMS DE SERVICE.
`forge.genese.internal` et `pki.genese.internal` — des noms que les certificats
portent et que les clients appellent — n'avaient aucun enregistrement. Seul le
plancher savait les resoudre. Trois causes empilees :
- le plan du site coupait `serveur_powerdns_publier_expositions`, au motif que
« le site n'a pas d'edge » : ca confondait PUBLIC et EXPOSE ;
- `expositions_des_applications` rendait `domaine: None` faute de
`domaines.yml`, et le modele de zone ecarte les expositions dont le domaine
n'est pas la zone. Repli ajoute, symetrique de celui deja ecrit pour `edge` :
sans domaine public declare, le domaine est celui que porte le FQDN ;
- `serveur_powerdns` exigeait les deux registres et echouait si `domaines.yml`
manquait — le meme tout-ou-rien que `hosts_statiques` a corrige le meme jour.
Puis `named-checkzone` a refuse la zone : `dns.genese.internal` heritait d'un
CNAME par defaut du role ET d'un A par exposition. La garde a bien joue son role
— elle a arrete une zone cassee avant qu'elle soit servie. Le plan l'emporte
desormais sur le defaut du role.
Un service ne doit pas dependre d'un plancher pour etre joignable : le plancher
est un filet, pas le sol.
VERIFICATION. Les huit noms — cinq machines, trois services — resolvent vers les
bonnes adresses depuis les cinq hotes, par le plancher ET par le DNS, et le
plancher survit au redemarrage.
P46 refuse desormais deux choses : plus d'un role ecrivant `manage_etc_hosts`,
et l'absence du gabarit maitre. Controle negatif verifie.
RESTE NOMME, PAS CORRIGE : la zone INVERSE. `serveur_powerdns_zone_inverse`
derive d'un supernet /16 — la forme d'un tenant. Un site declare plusieurs /24
et n'a pas de supernet unique : aucune zone inverse n'est generee.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 20:31:01 -04:00
|
|
|
# CHAQUE REGISTRE EST CHARGE POUR LUI-MEME (2026-08-25).
|
|
|
|
|
#
|
|
|
|
|
# Ce `include_vars` listait les deux fichiers en dur et echouait si l'un manquait.
|
|
|
|
|
# `domaines.yml` declare les domaines PUBLICS, et un ecosysteme peut legitimement n'en
|
|
|
|
|
# avoir aucun — c'est le cas du SITE, dont tous les services sont internes.
|
|
|
|
|
#
|
|
|
|
|
# Le defaut est reste invisible tant que le site gardait `publier_expositions: false` ;
|
|
|
|
|
# il est apparu a la seconde ou on a voulu publier ses noms de service. C'est le MEME
|
|
|
|
|
# defaut que `hosts_statiques` a corrige le meme jour, dans les memes termes : un registre
|
|
|
|
|
# absent n'est pas une faute, il est simplement absent.
|
|
|
|
|
- name: Vérifier la présence des registres du plan (sur le nœud de contrôle)
|
|
|
|
|
ansible.builtin.stat:
|
|
|
|
|
path: "{{ item }}"
|
|
|
|
|
register: serveur_powerdns_plan
|
|
|
|
|
delegate_to: localhost # les registres du plan vivent sur le nœud de contrôle
|
|
|
|
|
become: false # lire un fichier ne nécessite pas de privilèges
|
2026-07-03 13:47:29 -04:00
|
|
|
loop:
|
|
|
|
|
- "{{ setops_plan_dir }}/applications.yml"
|
|
|
|
|
- "{{ setops_plan_dir }}/domaines.yml"
|
site : le plancher survit au redemarrage, et la zone dit les vraies adresses
Le decoupage du site en quatre zones a deplace cinq machines. Ni le plancher
/etc/hosts ni la zone DNS n'avaient suivi. Quatre defauts, tous dans le moteur.
LE PLANCHER ETAIT EFFACE A CHAQUE DEMARRAGE — ET LE PREMIER CORRECTIF N'EN
ETAIT PAS UN.
`hosts_statiques` posait `99-setops-hosts.cfg` avec `manage_etc_hosts: false`,
pendant que `cloud_init` posait `99_setops.cfg` avec `true`. Dans `cloud.cfg.d`
l'ordre est LEXICAL et le dernier gagne : `-` vaut 0x2D, `_` vaut 0x5F. On a
donc retire la cle de `cloud_init` — le role qui POSSEDE le fichier decide —
puis renomme notre fragment `zz-` pour passer apres le `99_chezlepro.cfg` du
gabarit dore.
Et ca ne suffisait toujours pas. Redemarrage d'epreuve : plancher encore efface.
La cause reelle est ailleurs — Proxmox inscrit `manage_etc_hosts: true` dans la
USER-DATA de son lecteur cloud-init, et la user-data prime sur `cloud.cfg.d`
tout entier. Aucun fragment ne pouvait gagner ; renommer pour parler en dernier
ne servait a rien, le dernier mot n'appartenant pas a ce repertoire.
Ce que cloud-init regenere, il le regenere depuis `hosts.debian.tmpl` — le
gabarit le documente lui-meme. `hosts_statiques` le pose desormais avec le MEME
contenu que /etc/hosts, et une garde compare les deux a chaque passage.
Redemarrage d'epreuve : les neuf entrees sont la.
La garde precedente affirmait « conforme » en mesurant l'ordre lexical — vrai,
et sans rapport avec ce qui se passait. Une garde qui mesure la mauvaise chose
est pire qu'aucune.
LA ZONE DNS NE PUBLIAIT PAS LES NOMS DE SERVICE.
`forge.genese.internal` et `pki.genese.internal` — des noms que les certificats
portent et que les clients appellent — n'avaient aucun enregistrement. Seul le
plancher savait les resoudre. Trois causes empilees :
- le plan du site coupait `serveur_powerdns_publier_expositions`, au motif que
« le site n'a pas d'edge » : ca confondait PUBLIC et EXPOSE ;
- `expositions_des_applications` rendait `domaine: None` faute de
`domaines.yml`, et le modele de zone ecarte les expositions dont le domaine
n'est pas la zone. Repli ajoute, symetrique de celui deja ecrit pour `edge` :
sans domaine public declare, le domaine est celui que porte le FQDN ;
- `serveur_powerdns` exigeait les deux registres et echouait si `domaines.yml`
manquait — le meme tout-ou-rien que `hosts_statiques` a corrige le meme jour.
Puis `named-checkzone` a refuse la zone : `dns.genese.internal` heritait d'un
CNAME par defaut du role ET d'un A par exposition. La garde a bien joue son role
— elle a arrete une zone cassee avant qu'elle soit servie. Le plan l'emporte
desormais sur le defaut du role.
Un service ne doit pas dependre d'un plancher pour etre joignable : le plancher
est un filet, pas le sol.
VERIFICATION. Les huit noms — cinq machines, trois services — resolvent vers les
bonnes adresses depuis les cinq hotes, par le plancher ET par le DNS, et le
plancher survit au redemarrage.
P46 refuse desormais deux choses : plus d'un role ecrivant `manage_etc_hosts`,
et l'absence du gabarit maitre. Controle negatif verifie.
RESTE NOMME, PAS CORRIGE : la zone INVERSE. `serveur_powerdns_zone_inverse`
derive d'un supernet /16 — la forme d'un tenant. Un site declare plusieurs /24
et n'a pas de supernet unique : aucune zone inverse n'est generee.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 20:31:01 -04:00
|
|
|
loop_control:
|
|
|
|
|
label: "{{ item | basename }}"
|
2026-07-03 13:47:29 -04:00
|
|
|
when: serveur_powerdns_publier_expositions | bool
|
|
|
|
|
|
site : le plancher survit au redemarrage, et la zone dit les vraies adresses
Le decoupage du site en quatre zones a deplace cinq machines. Ni le plancher
/etc/hosts ni la zone DNS n'avaient suivi. Quatre defauts, tous dans le moteur.
LE PLANCHER ETAIT EFFACE A CHAQUE DEMARRAGE — ET LE PREMIER CORRECTIF N'EN
ETAIT PAS UN.
`hosts_statiques` posait `99-setops-hosts.cfg` avec `manage_etc_hosts: false`,
pendant que `cloud_init` posait `99_setops.cfg` avec `true`. Dans `cloud.cfg.d`
l'ordre est LEXICAL et le dernier gagne : `-` vaut 0x2D, `_` vaut 0x5F. On a
donc retire la cle de `cloud_init` — le role qui POSSEDE le fichier decide —
puis renomme notre fragment `zz-` pour passer apres le `99_chezlepro.cfg` du
gabarit dore.
Et ca ne suffisait toujours pas. Redemarrage d'epreuve : plancher encore efface.
La cause reelle est ailleurs — Proxmox inscrit `manage_etc_hosts: true` dans la
USER-DATA de son lecteur cloud-init, et la user-data prime sur `cloud.cfg.d`
tout entier. Aucun fragment ne pouvait gagner ; renommer pour parler en dernier
ne servait a rien, le dernier mot n'appartenant pas a ce repertoire.
Ce que cloud-init regenere, il le regenere depuis `hosts.debian.tmpl` — le
gabarit le documente lui-meme. `hosts_statiques` le pose desormais avec le MEME
contenu que /etc/hosts, et une garde compare les deux a chaque passage.
Redemarrage d'epreuve : les neuf entrees sont la.
La garde precedente affirmait « conforme » en mesurant l'ordre lexical — vrai,
et sans rapport avec ce qui se passait. Une garde qui mesure la mauvaise chose
est pire qu'aucune.
LA ZONE DNS NE PUBLIAIT PAS LES NOMS DE SERVICE.
`forge.genese.internal` et `pki.genese.internal` — des noms que les certificats
portent et que les clients appellent — n'avaient aucun enregistrement. Seul le
plancher savait les resoudre. Trois causes empilees :
- le plan du site coupait `serveur_powerdns_publier_expositions`, au motif que
« le site n'a pas d'edge » : ca confondait PUBLIC et EXPOSE ;
- `expositions_des_applications` rendait `domaine: None` faute de
`domaines.yml`, et le modele de zone ecarte les expositions dont le domaine
n'est pas la zone. Repli ajoute, symetrique de celui deja ecrit pour `edge` :
sans domaine public declare, le domaine est celui que porte le FQDN ;
- `serveur_powerdns` exigeait les deux registres et echouait si `domaines.yml`
manquait — le meme tout-ou-rien que `hosts_statiques` a corrige le meme jour.
Puis `named-checkzone` a refuse la zone : `dns.genese.internal` heritait d'un
CNAME par defaut du role ET d'un A par exposition. La garde a bien joue son role
— elle a arrete une zone cassee avant qu'elle soit servie. Le plan l'emporte
desormais sur le defaut du role.
Un service ne doit pas dependre d'un plancher pour etre joignable : le plancher
est un filet, pas le sol.
VERIFICATION. Les huit noms — cinq machines, trois services — resolvent vers les
bonnes adresses depuis les cinq hotes, par le plancher ET par le DNS, et le
plancher survit au redemarrage.
P46 refuse desormais deux choses : plus d'un role ecrivant `manage_etc_hosts`,
et l'absence du gabarit maitre. Controle negatif verifie.
RESTE NOMME, PAS CORRIGE : la zone INVERSE. `serveur_powerdns_zone_inverse`
derive d'un supernet /16 — la forme d'un tenant. Un site declare plusieurs /24
et n'a pas de supernet unique : aucune zone inverse n'est generee.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 20:31:01 -04:00
|
|
|
- name: Charger les registres applications et domaines (si présents)
|
|
|
|
|
ansible.builtin.include_vars:
|
|
|
|
|
file: "{{ item.item }}"
|
|
|
|
|
loop: "{{ serveur_powerdns_plan.results | default([]) }}"
|
|
|
|
|
loop_control:
|
|
|
|
|
label: "{{ item.item | basename }}"
|
|
|
|
|
when:
|
|
|
|
|
- serveur_powerdns_publier_expositions | bool
|
|
|
|
|
- item.stat.exists | default(false)
|
|
|
|
|
|
2026-07-03 13:47:29 -04:00
|
|
|
- name: Dériver les A d'exposition (FQDN publics -> edge qui les sert)
|
|
|
|
|
ansible.builtin.set_fact:
|
|
|
|
|
serveur_powerdns_expositions: >-
|
|
|
|
|
{{ {'applications': applications | default({})}
|
|
|
|
|
| expositions_des_applications({'domaines_publics': domaines_publics | default({})}) }}
|
|
|
|
|
when: serveur_powerdns_publier_expositions | bool
|
|
|
|
|
|
2026-06-24 20:17:46 -04:00
|
|
|
- name: Générer la zone DNS interne depuis l'inventaire
|
|
|
|
|
ansible.builtin.template:
|
|
|
|
|
src: zone.db.j2
|
|
|
|
|
dest: "{{ serveur_powerdns_zone_directory }}/{{ serveur_powerdns_zone }}.zone"
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0644"
|
|
|
|
|
notify: Validate and reload PowerDNS
|
|
|
|
|
|
2026-08-08 15:29:57 -04:00
|
|
|
# Meme source que la zone directe : `hotes_actifs` et son `ansible_host`. Deux zones
|
|
|
|
|
# alimentees par une seule verite — l'endroit ou elles divergeraient n'existe pas.
|
dns : quatre zones inverses pour le site, et rien de plus
Le site ne servait aucun PTR. `serveur_powerdns_zone_inverse` derivait d'un
supernet /16 — la forme d'un TENANT, qui tire tout de son index. Un site ne
derive pas : il declare plusieurs /24 et n'a pas de supernet unique, si bien que
la derivation rendait une chaine vide et qu'aucune zone n'etait generee.
Le site revendique desormais exactement ce qu'il occupe :
31.0.10.in-addr.arpa 32.0.10.in-addr.arpa
33.0.10.in-addr.arpa 34.0.10.in-addr.arpa
Revendiquer `0.10.in-addr.arpa` d'un seul geste aurait ete plus simple et faux :
cette zone couvre aussi la frontiere, le transit et les hyperviseurs, qui ne sont
pas a lui. Une autorite qu'on s'attribue sans l'exercer est une panne differee —
le resolveur repondrait NXDOMAIN pour des adresses qu'un autre sait nommer.
LA DERIVATION VIT DANS UN FILTRE (`zones_inverses`) parce qu'elle a DEUX
appelants : `serveur_powerdns` ecrit ces zones, `serveur_resolveur` les delegue a
l'autoritatif. Deux calculs separes finiraient par diverger, et la divergence ne
se verrait qu'au premier PTR interroge. Le nom d'une zone dit sa profondeur —
trois etiquettes numeriques valent un /24, deux valent un /16 — et le modele en
deduit seul la forme du PTR.
DEUX CHEMINS MORTS TROUVES EN ROUTE.
Les zones etaient servies, et personne ne les demandait. `serveur_resolveur`
deleguait la zone directe par une `stub-zone` mais pas les inverses : `dig -x`
rendait vide depuis les cinq machines alors que la meme requete posee directement
a l'autoritatif repondait juste. Un service correct derriere un chemin que rien
n'emprunte.
Puis, les stubs poses, Unbound repondait toujours NXDOMAIN avec le drapeau `aa` —
une reponse AUTORITAIRE, sans jamais consulter le stub. Il embarque des
`local-zone` pour tout l'espace RFC1918 inverse. `nodefault` n'y change rien : ce
mode n'agit que si le nom correspond EXACTEMENT a une zone par defaut, et la
sienne est `10.in-addr.arpa`, le /8 entier. C'est `transparent` qui laisse la
requete suivre son cours — pour nos quatre zones seulement, la ou
`unblock-lan-zones` aurait ouvert tout l'espace prive.
Rien ne distinguait ce blocage d'une absence : le meme NXDOMAIN qu'un nom qui
n'existe pas.
AUSSI : les zones inverses sont desormais validees par `named-checkzone` comme la
directe (un fichier mal forme etait refuse en silence par PowerDNS), et une zone
qu'un ecosysteme cesse de revendiquer est retiree du repertoire.
VERIFICATION. Les cinq PTR resolvent depuis les cinq hotes par le resolveur, les
huit noms directs par le plancher ET par le DNS, et les deux roles sont
idempotents (changed=0).
P47 evalue la derivation sur cinq cas — un site a quatre zones, un tenant a une,
deux machines d'un meme /24 qui n'en font qu'une, aucune adresse, une adresse
illisible. Controle negatif verifie.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 20:58:50 -04:00
|
|
|
- name: Générer les zones DNS inverses depuis l'inventaire
|
2026-08-08 15:29:57 -04:00
|
|
|
ansible.builtin.template:
|
|
|
|
|
src: zone-inverse.db.j2
|
dns : quatre zones inverses pour le site, et rien de plus
Le site ne servait aucun PTR. `serveur_powerdns_zone_inverse` derivait d'un
supernet /16 — la forme d'un TENANT, qui tire tout de son index. Un site ne
derive pas : il declare plusieurs /24 et n'a pas de supernet unique, si bien que
la derivation rendait une chaine vide et qu'aucune zone n'etait generee.
Le site revendique desormais exactement ce qu'il occupe :
31.0.10.in-addr.arpa 32.0.10.in-addr.arpa
33.0.10.in-addr.arpa 34.0.10.in-addr.arpa
Revendiquer `0.10.in-addr.arpa` d'un seul geste aurait ete plus simple et faux :
cette zone couvre aussi la frontiere, le transit et les hyperviseurs, qui ne sont
pas a lui. Une autorite qu'on s'attribue sans l'exercer est une panne differee —
le resolveur repondrait NXDOMAIN pour des adresses qu'un autre sait nommer.
LA DERIVATION VIT DANS UN FILTRE (`zones_inverses`) parce qu'elle a DEUX
appelants : `serveur_powerdns` ecrit ces zones, `serveur_resolveur` les delegue a
l'autoritatif. Deux calculs separes finiraient par diverger, et la divergence ne
se verrait qu'au premier PTR interroge. Le nom d'une zone dit sa profondeur —
trois etiquettes numeriques valent un /24, deux valent un /16 — et le modele en
deduit seul la forme du PTR.
DEUX CHEMINS MORTS TROUVES EN ROUTE.
Les zones etaient servies, et personne ne les demandait. `serveur_resolveur`
deleguait la zone directe par une `stub-zone` mais pas les inverses : `dig -x`
rendait vide depuis les cinq machines alors que la meme requete posee directement
a l'autoritatif repondait juste. Un service correct derriere un chemin que rien
n'emprunte.
Puis, les stubs poses, Unbound repondait toujours NXDOMAIN avec le drapeau `aa` —
une reponse AUTORITAIRE, sans jamais consulter le stub. Il embarque des
`local-zone` pour tout l'espace RFC1918 inverse. `nodefault` n'y change rien : ce
mode n'agit que si le nom correspond EXACTEMENT a une zone par defaut, et la
sienne est `10.in-addr.arpa`, le /8 entier. C'est `transparent` qui laisse la
requete suivre son cours — pour nos quatre zones seulement, la ou
`unblock-lan-zones` aurait ouvert tout l'espace prive.
Rien ne distinguait ce blocage d'une absence : le meme NXDOMAIN qu'un nom qui
n'existe pas.
AUSSI : les zones inverses sont desormais validees par `named-checkzone` comme la
directe (un fichier mal forme etait refuse en silence par PowerDNS), et une zone
qu'un ecosysteme cesse de revendiquer est retiree du repertoire.
VERIFICATION. Les cinq PTR resolvent depuis les cinq hotes par le resolveur, les
huit noms directs par le plancher ET par le DNS, et les deux roles sont
idempotents (changed=0).
P47 evalue la derivation sur cinq cas — un site a quatre zones, un tenant a une,
deux machines d'un meme /24 qui n'en font qu'une, aucune adresse, une adresse
illisible. Controle negatif verifie.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 20:58:50 -04:00
|
|
|
dest: "{{ serveur_powerdns_zone_directory }}/{{ zone_inverse }}.zone"
|
2026-08-08 15:29:57 -04:00
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0644"
|
dns : quatre zones inverses pour le site, et rien de plus
Le site ne servait aucun PTR. `serveur_powerdns_zone_inverse` derivait d'un
supernet /16 — la forme d'un TENANT, qui tire tout de son index. Un site ne
derive pas : il declare plusieurs /24 et n'a pas de supernet unique, si bien que
la derivation rendait une chaine vide et qu'aucune zone n'etait generee.
Le site revendique desormais exactement ce qu'il occupe :
31.0.10.in-addr.arpa 32.0.10.in-addr.arpa
33.0.10.in-addr.arpa 34.0.10.in-addr.arpa
Revendiquer `0.10.in-addr.arpa` d'un seul geste aurait ete plus simple et faux :
cette zone couvre aussi la frontiere, le transit et les hyperviseurs, qui ne sont
pas a lui. Une autorite qu'on s'attribue sans l'exercer est une panne differee —
le resolveur repondrait NXDOMAIN pour des adresses qu'un autre sait nommer.
LA DERIVATION VIT DANS UN FILTRE (`zones_inverses`) parce qu'elle a DEUX
appelants : `serveur_powerdns` ecrit ces zones, `serveur_resolveur` les delegue a
l'autoritatif. Deux calculs separes finiraient par diverger, et la divergence ne
se verrait qu'au premier PTR interroge. Le nom d'une zone dit sa profondeur —
trois etiquettes numeriques valent un /24, deux valent un /16 — et le modele en
deduit seul la forme du PTR.
DEUX CHEMINS MORTS TROUVES EN ROUTE.
Les zones etaient servies, et personne ne les demandait. `serveur_resolveur`
deleguait la zone directe par une `stub-zone` mais pas les inverses : `dig -x`
rendait vide depuis les cinq machines alors que la meme requete posee directement
a l'autoritatif repondait juste. Un service correct derriere un chemin que rien
n'emprunte.
Puis, les stubs poses, Unbound repondait toujours NXDOMAIN avec le drapeau `aa` —
une reponse AUTORITAIRE, sans jamais consulter le stub. Il embarque des
`local-zone` pour tout l'espace RFC1918 inverse. `nodefault` n'y change rien : ce
mode n'agit que si le nom correspond EXACTEMENT a une zone par defaut, et la
sienne est `10.in-addr.arpa`, le /8 entier. C'est `transparent` qui laisse la
requete suivre son cours — pour nos quatre zones seulement, la ou
`unblock-lan-zones` aurait ouvert tout l'espace prive.
Rien ne distinguait ce blocage d'une absence : le meme NXDOMAIN qu'un nom qui
n'existe pas.
AUSSI : les zones inverses sont desormais validees par `named-checkzone` comme la
directe (un fichier mal forme etait refuse en silence par PowerDNS), et une zone
qu'un ecosysteme cesse de revendiquer est retiree du repertoire.
VERIFICATION. Les cinq PTR resolvent depuis les cinq hotes par le resolveur, les
huit noms directs par le plancher ET par le DNS, et les deux roles sont
idempotents (changed=0).
P47 evalue la derivation sur cinq cas — un site a quatre zones, un tenant a une,
deux machines d'un meme /24 qui n'en font qu'une, aucune adresse, une adresse
illisible. Controle negatif verifie.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 20:58:50 -04:00
|
|
|
loop: "{{ serveur_powerdns_zones_inverses | default([]) }}"
|
|
|
|
|
loop_control:
|
|
|
|
|
loop_var: zone_inverse
|
|
|
|
|
notify: Validate and reload PowerDNS
|
|
|
|
|
|
|
|
|
|
# UNE ZONE INVERSE QUI N'EST PLUS REVENDIQUEE DOIT DISPARAITRE. Sans ce retrait, un
|
|
|
|
|
# ecosysteme qui abandonne un reseau laisserait derriere lui un fichier que le backend ne
|
|
|
|
|
# declare plus mais que le repertoire garde — et le prochain lecteur croirait la zone
|
|
|
|
|
# servie.
|
|
|
|
|
- name: Relever les zones inverses présentes sur la machine
|
|
|
|
|
ansible.builtin.find:
|
|
|
|
|
paths: "{{ serveur_powerdns_zone_directory }}"
|
|
|
|
|
patterns: "*.in-addr.arpa.zone"
|
|
|
|
|
register: serveur_powerdns_inverses_presentes
|
|
|
|
|
|
|
|
|
|
- name: Retirer les zones inverses que l'écosystème ne revendique plus
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
path: "{{ item.path }}"
|
|
|
|
|
state: absent
|
|
|
|
|
loop: "{{ serveur_powerdns_inverses_presentes.files | default([]) }}"
|
|
|
|
|
loop_control:
|
|
|
|
|
label: "{{ item.path | basename }}"
|
|
|
|
|
when: >-
|
|
|
|
|
(item.path | basename | regex_replace('\.zone$', ''))
|
|
|
|
|
not in (serveur_powerdns_zones_inverses | default([]))
|
2026-08-08 15:29:57 -04:00
|
|
|
notify: Validate and reload PowerDNS
|
|
|
|
|
|
2026-06-24 20:17:46 -04:00
|
|
|
- name: Activer et démarrer PowerDNS
|
|
|
|
|
ansible.builtin.systemd:
|
|
|
|
|
name: "{{ serveur_powerdns_service_name }}"
|
|
|
|
|
enabled: true
|
|
|
|
|
state: started
|
2026-07-01 21:01:53 -04:00
|
|
|
# Dry-run (--check) : le paquet n'est pas reellement installe, donc le service
|
|
|
|
|
# n'existe pas encore et systemd echouerait. On saute en mode check seulement ;
|
|
|
|
|
# en vrai deploiement, la tache s'execute normalement.
|
|
|
|
|
when: not ansible_check_mode
|