{ config, ... }: let # Split-horizon fuer die internen Namen *dieses* Stacks, also unter # config.domain2. Erreichbar im gemeinsamen pinix-Tailnet. # Traefiks websecure-Entrypoint lauscht auch auf der Tailnet-Adresse. # 0ff.space und dessen AdGuard-Rewrites bleiben auf blunix. internalNames = [ "dex" "head" "lldap" ]; in { # Rekursiver Resolver im gemeinsamen pinix-Tailnet auf pinix -- die Rolle, # die AdGuardHome auf blunix fuer 0ff.space haelt und dort auch behaelt. # Zwei bewusste Unterschiede zu jenem Aufbau: # # 1. Dieser rekursiert selbst, statt auf 1.1.1.1 und 8.8.8.8 zu # forwarden. Internes DNS haengt damit nicht an Cloudflare und # Google -- dieselbe Richtung wie der Cloudflare-Ausstieg. # 2. Overrides sind Nix-`local-data`, das kein Enable-Flag pro Eintrag # kennt. Die in CLAUDE.md dokumentierte AdGuard-Falle (jeder Rewrite # braucht explizit `enabled = true`, alle neun hatten es nicht) kann # hier nicht wiederkehren. # # AdGuardHomes `safe_search` wird nicht uebernommen (erzwang gefilterte # Suchmaschinen-Varianten fuer jeden Client dieses Resolvers). Mit # local-data-CNAMEs auf forcesafesearch.google.com o.ae. rekonstruierbar. services.unbound = { enable = true; # Must stay false. The module would otherwise point /etc/resolv.conf at # localhost, and pinix' own resolution depends on Mango's DNS64: reaching # any IPv4-only host (blunix, Forgejo) happens through NAT64, which needs # the resolver to synthesise AAAA from A. A plain recursive resolver # returns the real A record instead and pinix loses that path silently. # Same reasoning as bind.nix, verified across a reboot in # docs/pinix-reboot-probe.md. resolveLocalQueries = false; settings.server = { # Tailnet addresses only. Loopback belongs to the authoritative BIND # (bind.nix), and binding both daemons to it would fail. interface = [ config.tailnetIPs.pinix "fd7a:115c:a1e0:96::4" ]; # tailscale0 appears later in boot than unbound, so without this the # bind fails outright on a cold start. ip-freebind = true; # Open resolvers get abused for reflection. Only the Tailnet may query. access-control = [ "100.96.0.0/24 allow" "fd7a:115c:a1e0:96::/64 allow" "0.0.0.0/0 refuse" "::/0 refuse" ]; # `transparent` haelt den Rest der Zone rekursiv: nur die oben # gelisteten Namen werden lokal beantwortet, alles andere unter # config.domain2 loest normal oeffentlich auf. 0ff.space ist hier # bewusst nicht genannt -- dafuer ist blunix zustaendig. local-zone = [ ''"${config.domain2}." transparent'' ]; local-data = map (name: ''"${name}.${config.domain2}. A ${config.tailnetIPs.pinix}"'') internalNames; hide-identity = true; hide-version = true; prefetch = true; }; }; }