{ config, lib, ... }: with lib; let generateCoreDNSConfig = domains: let generateForDomain = domain: conf: concatMapStrings (iface: let architectIP = config.architect.networks.${iface}.devices.architect.address; interfaceNet = config.architect.networks.${iface}.net; in '' ${domain} { view ${iface} { expr incidr(client_ip(), '${interfaceNet}') } template IN A ${domain} { answer "${domain}. 60 IN A ${architectIP}" } template IN HTTPS ${domain} { answer "${domain}. 60 IN HTTPS 1 . ipv4hint=\"${architectIP}\"" } cache log } '' ) conf.dnsInterfaces; in concatStrings (mapAttrsToList generateForDomain domains); # Combine vhosts and the single domain allDomains = config.architect.vhost // { "architect.devs.giugl.io" = { dnsInterfaces = [ "lan" "tailscale" ]; }; }; domain = "adguard.giugl.io"; in { architect.vhost.${domain} = with config.architect.networks; { dnsInterfaces = [ "tailscale" "lan" ]; locations."/" = { port = config.services.adguardhome.port; allowLan = true; allow = [ tailscale.net ]; }; }; services = { coredns = { enable = true; config = '' ${generateCoreDNSConfig allDomains} . { cache forward . 127.0.0.1:${toString config.services.adguardhome.settings.dns.port} } ''; }; adguardhome = { enable = true; settings = { port = 5354; dns = { port = 5300; }; upstream_dns = [ "tls://architect.d65174.dns.nextdns.io" "https://dns.nextdns.io/d65174/architect" ]; }; }; dnscrypt-proxy2 = { enable = true; settings = { listen_addresses = [ "127.0.0.1:5354" ]; ipv4_servers = true; ipv6_servers = false; block_ipv6 = true; dnscrypt_servers = true; doh_servers = true; require_nolog = true; require_nofilter = true; timeout = 350; lb_strategy = "p4"; lb_estimator = true; ignore_system_dns = true; fallback_resolvers = [ "1.1.1.1:53" "9.9.9.9:53" ]; cache_min_ttl = 60; cache_max_ttl = 360; }; }; }; }