summaryrefslogtreecommitdiff
path: root/hosts/ahmed/local-dns/dns-resolver.nix
diff options
context:
space:
mode:
Diffstat (limited to 'hosts/ahmed/local-dns/dns-resolver.nix')
-rw-r--r--hosts/ahmed/local-dns/dns-resolver.nix57
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];
+ };
+}