From 7dd80b6c7c15bec8c414183f49d0d05583e3e9f2 Mon Sep 17 00:00:00 2001 From: Viktor Barzin Date: Fri, 3 Jul 2026 10:10:46 +0000 Subject: [PATCH] technitium: mirror most.viktorbarzin.me into the internal zone (CF Pages site) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The internal split-horizon zone is authoritative for viktorbarzin.me, so the new Cloudflare Pages site (most.viktorbarzin.me, added for Viktor's 'мост' school static site) NXDOMAINed for every internal client — LAN, VLANs and pods — while resolving fine externally. Per the superset rule, add it as a static CNAME (-> most-6if.pages.dev) in the ingress-dns-sync CronJob next to the mail-auth records, and document the off-infra-site case in dns.md. Co-Authored-By: Claude Fable 5 --- docs/architecture/dns.md | 2 +- stacks/technitium/modules/technitium/main.tf | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/architecture/dns.md b/docs/architecture/dns.md index fe959b52..106c2021 100644 --- a/docs/architecture/dns.md +++ b/docs/architecture/dns.md @@ -277,7 +277,7 @@ Technitium's **Split Horizon AddressTranslation** app post-processes DNS respons Config is synced to all 3 Technitium instances by CronJob `technitium-split-horizon-sync` (every 6h). -**Superset rule for the internal `viktorbarzin.me` zone**: it is authoritative for every internal client (pods included since 2026-06-10), so it must carry every record type those clients consume — not just ingress A/CNAMEs. The `technitium-ingress-dns-sync` CronJob therefore also maintains the static **mail-auth records** (apex SPF + brevo-code TXT, MX → mail.viktorbarzin.me, `_dmarc`, `mail._domainkey` DKIM), mirrored from the public Cloudflare zone. Without them, rspamd on the mailserver saw `SPF=none` for inbound `@viktorbarzin.me` mail and quarantined it (broke the Brevo email-roundtrip probe, 2026-06-10). If these records change in Cloudflare, update the sync script too. +**Superset rule for the internal `viktorbarzin.me` zone**: it is authoritative for every internal client (pods included since 2026-06-10), so it must carry every record type those clients consume — not just ingress A/CNAMEs. The `technitium-ingress-dns-sync` CronJob therefore also maintains the static **mail-auth records** (apex SPF + brevo-code TXT, MX → mail.viktorbarzin.me, `_dmarc`, `mail._domainkey` DKIM), mirrored from the public Cloudflare zone. Without them, rspamd on the mailserver saw `SPF=none` for inbound `@viktorbarzin.me` mail and quarantined it (broke the Brevo email-roundtrip probe, 2026-06-10). If these records change in Cloudflare, update the sync script too. The same applies to **off-infra sites** (e.g. `most` → CNAME `most-6if.pages.dev`, Cloudflare Pages): any public-only name with no Traefik ingress must be added as a static record in the sync script, or internal clients NXDOMAIN on it while it works fine externally. ## NodeLocal DNSCache diff --git a/stacks/technitium/modules/technitium/main.tf b/stacks/technitium/modules/technitium/main.tf index 966d11f3..a80c209c 100644 --- a/stacks/technitium/modules/technitium/main.tf +++ b/stacks/technitium/modules/technitium/main.tf @@ -1002,6 +1002,14 @@ resource "kubernetes_cron_job_v1" "technitium_ingress_dns_sync" { echo "mail-auth: MX present" fi + # Off-infra sites on Cloudflare Pages: the internal zone is + # authoritative (superset rule above), so public-only names + # with no Traefik ingress must be mirrored here or every + # internal client (LAN, VLANs, pods) gets NXDOMAIN for them. + # Target is the pages.dev host — resolves via upstream to CF + # edge IPs; normal egress, no hairpin involved. + add_cname "most.$$ZONE" "most-6if.pages.dev" + # Pin the .lan ingress anchor A record to the LIVE Traefik LB IP. # *.viktorbarzin.lan ingress hosts CNAME to ingress.viktorbarzin.lan, # so a Traefik LB IP move that misses the .lan zone silently breaks