diff options
Diffstat (limited to 'hosts/ahmed/local-dns/dns-resolver.nix')
-rw-r--r-- | hosts/ahmed/local-dns/dns-resolver.nix | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/hosts/ahmed/local-dns/dns-resolver.nix b/hosts/ahmed/local-dns/dns-resolver.nix new file mode 100644 index 0000000..1954a52 --- /dev/null +++ b/hosts/ahmed/local-dns/dns-resolver.nix @@ -0,0 +1,57 @@ +# This module creates a local DNS server which provides "split horizon DNS". +# +# It only serves devices on the LAN (see `services.dnscache.clientIps`) and for +# those, it claims to have authority over the domain set in `config.linus.local-dns.domain`. +# +# See: https://www.fefe.de/djbdns/split-horizon +{ + config, + metadata, + lib, + ... +}: { + services.dnscache = { + enable = true; + clientIps = [ + "192.168" # LAN + "127.0.0.1" # Local connections + ]; + + domainServers = { + # Forward any requests to the split domain to our local, authoritative name server. + ${config.linus.local-dns.domain} = ["127.0.0.1"]; + }; + }; + + # Authoritative name server which claims ownership of the split domain. + services.tinydns = { + enable = true; + + # We will only listen for internal queries from the DNS cache. + ip = "127.0.0.1"; + + # Here we publish all the services we want. + data = let + subdomainToARecord = subdomain: "=${subdomain}.${config.linus.local-dns.domain}:${metadata.hosts.ahmed.ipAddress}"; + ARecords = lib.concatMapStringsSep "\n" subdomainToARecord config.linus.local-dns.subdomains; + in '' + # We are authoritative over ${config.linus.local-dns.domain}. + # Here we simply identify as localhost, as only the local dnscache instance will ever see this (I think). + .${config.linus.local-dns.domain}:127.0.0.1:a + # Next, we link all the subdomains to our LAN IP. + ${ARecords} + ''; + }; + + # Allow other devices on LAN to interact with us. In the router's DHCP + # settings, I have set ahmed's IP as the primary DNS server. This will make + # all clients (which respect DNS from DHCP) use ahmed if he's online. + # + # Notably, the NAT on the router does not route external trafic here; we are + # a non-authoritative DNS resolver, so we don't want to service the global + # internet. + networking.firewall = { + allowedTCPPorts = [53]; + allowedUDPPorts = [53]; + }; +} |