{# LE SERVEUR DE NOMS EST CELUI DU SITE, SOUS LE NOM QUE LE SITE DECLARE (2026-09-16). La premiere version ecrivait `ns1.` dans chaque zone. Or `ns1.chezlepro.ca` existe en production, vers une autre adresse : basculer l'aurait deplace en silence. Toutes les zones du site designent desormais un seul nom, `dns_public_nom`, et seule la zone qui le contient porte son A. #} {% set _ns = serveur_powerdns_dns_public_nom | trim | regex_replace('\\.$', '') %} $ORIGIN {{ zone_publique }}. $TTL {{ serveur_powerdns_ttl }} @ IN SOA {{ _ns }}. hostmaster.{{ zone_publique }}. ( {{ serveur_powerdns_serial_public }} {{ serveur_powerdns_soa_refresh }} {{ serveur_powerdns_soa_retry }} {{ serveur_powerdns_soa_expire }} {{ serveur_powerdns_soa_minimum }} ) {# L'ETAT DNSSEC FAIT PARTIE DU CORPS. Signer, changer de cle ou retirer la signature ne change aucun enregistrement : sans cette ligne, le serial ne bougerait pas, et le site garderait la version non signee (eprouve le 2026-09-16). L'empreinte d'une cle aleatoire de 256 bits ne revele rien d'elle. #} {% set _cle = lookup('vars', 'vault_dnssec_' ~ (zone_publique | lower | regex_replace('[^a-z0-9]', '_')), default='') %} ; DNSSEC : {{ ('signee, cle ' ~ (_cle | hash('sha256'))[:12]) if ((domaines_publics[zone_publique].dnssec | default(false) | bool) and _cle) else 'non signee' }} @ IN NS {{ _ns }}. {% if _ns.endswith('.' ~ zone_publique) %} {{ _ns[:-(zone_publique | length + 1)] }} IN A {{ serveur_powerdns_ip_publique }} {% endif %} {# UNE ZONE PUBLIQUE NE PORTE QUE DES ADRESSES PUBLIQUES. Un nom expose sous ce domaine resout vers l'adresse publique du site — la frontiere le relaie ensuite a l'edge. Jamais vers l'adresse interne de l'edge : elle ne resoudrait pour personne dehors, et renseignerait sur le reseau dedans. #} {% for expo in serveur_powerdns_expositions | default([]) if expo.domaine == zone_publique %} {{ expo.fqdn[:-(zone_publique | length + 1)] if expo.fqdn != zone_publique else '@' }} IN A {{ serveur_powerdns_ip_publique }} {% endfor %} {# LES ENREGISTREMENTS DECLARES AU PLAN : courriel, verifications, noms historiques. `valider_domaines` les a deja passes au crible (adresses publiques, cibles completes, CNAME seul a son nom, texte sans guillemet). Le gabarit ne fait que les ecrire. Un TXT plus long que 255 octets — une cle DKIM — est coupe en tranches : un resolveur les recolle, et une seule chaine trop longue rendrait la zone illisible. #} {% for enr in (domaines_publics | default({}))[zone_publique].enregistrements | default([]) %} {% set _t = enr.type | upper %} {% set _v = enr.valeur | string | trim %} {{ enr.nom }} {{ enr.ttl | default('') }} IN {{ _t }} {% if _t in ['A', 'AAAA'] %}{{ _v }}{% elif _t == 'CNAME' %}{{ _v.rstrip('.') }}.{% elif _t == 'MX' %}{{ enr.priorite }} {{ _v.rstrip('.') }}.{% elif _t == 'CAA' %}0 {{ enr.etiquette }} "{{ _v }}"{% elif _t == 'TXT' %}{% for i in range(0, _v | length, 255) %}"{{ _v[i:i + 255] }}"{{ ' ' if not loop.last }}{% endfor %}{% endif %} {% endfor %}