From 800dd6b96a497bf8a560e8cbfa3778c2d62887b1 Mon Sep 17 00:00:00 2001 From: ibizaman Date: Mon, 24 Nov 2025 22:29:53 +0100 Subject: [PATCH] docs: add recip for dns server --- CHANGELOG.md | 4 + docs/recipes.md | 4 + docs/recipes/dnsServer.md | 186 ++++++++++++++++++++++++++++++++++++++ docs/redirects.json | 12 +++ 4 files changed, 206 insertions(+) create mode 100644 docs/recipes/dnsServer.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 198e76e..d22f318 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,10 @@ Template: - Allow to upload big files in Immich. +## Other Changes + +- Add recipe to setup DNS server with DNSSEC. + # v0.6.1 ## New Features diff --git a/docs/recipes.md b/docs/recipes.md index b85503a..457f335 100644 --- a/docs/recipes.md +++ b/docs/recipes.md @@ -3,6 +3,10 @@ This section of the manual gives you easy to follow recipes for common use cases. +```{=include=} chapters html:into-file=//recipes-dnsServer.html +recipes/dnsServer.md +``` + ```{=include=} chapters html:into-file=//recipes-exposeService.html recipes/exposeService.md ``` diff --git a/docs/recipes/dnsServer.md b/docs/recipes/dnsServer.md new file mode 100644 index 0000000..277afe2 --- /dev/null +++ b/docs/recipes/dnsServer.md @@ -0,0 +1,186 @@ + +# Self-Host a DNS server making {#recipes-dnsServer} + +This recipe will show how to setup [dnsmasq][] as a local DNS server +that forwards all queries to your own domain `example.com` to a local IP - your server running SelfHostBlocks for example. + +[dnsmasq]: https://dnsmasq.org/doc.html + +Other DNS queries will be forwarded to an external DNS server +using [DNSSEC][] to encrypt your queries. + +[DNSSEC]: https://en.wikipedia.org/wiki/Domain_Name_System_Security_Extensions + +For this to work, you must configure the DHCP server of your network +to set the DNS server to the IP of the host where the DNS server is running. +Usually, your ISP's router can do this but probably easier is to disable completely that DHCP server +and also self-host the DHCP server. +This recipe shows how to do that too. + +## Why {#recipes-dnsServer-why} + +_You want to hide your DNS queries from your ISP or other prying eyes._ + +Even if you use HTTPS to access an URL, +DNS queries are by default made in plain text. +Crazy, right? +So, even if the actual communication is encrypted, +everyone can see which site you're trying to access. +Using DNSSEC means encrypting the traffic to your preferred external DNS server. +Of course, that server will see what domain names you're trying to resolve, +but at least intermediary hops will not be able to anymore. + +_You want more control on which DNS queries can be made._ + +Self-hosting your own DNS server means you can block some domains or subdomains. +This is done in practice by instructing your DNS server +to fail resolving some domains or subdomains. +Want to block Facebook for every host in the house? +That's the way to go. + +Some routers allow this level of fine-tuning but if not, +self-hosting your own DNS server is the way to go. + +## Drawbacks {#recipes-dnsServer-drawbacks} + +Although it has some nice advantages, +self-hosting your own DNS server has one major drawback: +if it goes down, the whole household will be impacted. +By experience, it takes up to 5 minutes for others to notice something is wrong with internet. + +So be wary when you deploy a new config. + +## Recipe {#recipes-dnsServer-recipe} + +The following snippet: + +- Opens UDP port 53 in the firewall which is the ubiquitous (and hardcoded, crazy I know) port for DNS queries. +- Disables the default DNS resolver. +- Sets up dnsmasq as the DNS server. +- Optionally sets up dnsmasq as the DHCP server. +- Answers all DNS requests to your domain with the internal IP of the server. +- Forwards all other DNS requests to an external DNS server using DNSSEC. + This is done using [stubby][]. + +[stubby]: https://dnsprivacy.org/dns_privacy_daemon_-_stubby/ + +For more information about options, read the dnsmasq [manual][]. + +[manual]: https://dnsmasq.org/docs/dnsmasq-man.html + +```nix +let + # Replace these values with what matches your network. + domain = "example.com"; + serverIP = "192.168.1.30"; + + # This port is used internally for dnsmasq to talk to stubby on the loopback interface. + # Only change this if that port is already taken. + stubbyPort = 53000; +in +{ + networking.firewall.allowedUDPPorts = [ 53 ]; + + services.resolved.enable = false; + services.dnsmasq = { + enable = true; + settings = { + inherit domain; + + # Redirect queries to the stubby instance. + server = [ + "127.0.0.1#${stubbyPort}" + "::1#${stubbyPort}" + ]; + # We do trust our own instance of stubby + # so we can proxy DNSSEC stuff. + # I'm not sure how useful this is. + proxy-dnssec = true; + + # Log all queries. + # This produces a lot of log lines + # and looking at those can be scary! + log-queries = true; + + # Do not look at /etc/resolv.conf + no-resolv = true; + + # Do not forward externally reverse DNS lookups for internal IPs. + bogus-priv = true; + + address = [ + "/.${domain}/${serverIP}" + # You can redirect anything anywhere too. + "/pikvm.${domain}/192.168.1.31" + ]; + }; + }; + + services.stubby = { + enable = true; + # It's a bit weird but default values comes from the examples settings hosted at + # https://github.com/getdnsapi/stubby/blob/develop/stubby.yml.example + settings = pkgs.stubby.passthru.settingsExample // { + listen_addresses = [ + "127.0.0.1@${stubbyPort}" + "0::1@${stubbyPort}" + ]; + + # For more example of good DNS resolvers, + # head to https://dnsprivacy.org/public_resolvers/ + # + # The digest comes from https://nixos.wiki/wiki/Encrypted_DNS#Stubby + upstream_recursive_servers = [ + { + address_data = "9.9.9.9"; + tls_auth_name = "dns.quad9.net"; + tls_pubkey_pinset = [ + { + digest = "sha256"; + value = "i2kObfz0qIKCGNWt7MjBUeSrh0Dyjb0/zWINImZES+I="; + } + ]; + } + { + address_data = "149.112.112.112"; + tls_auth_name = "dns.quad9.net"; + tls_pubkey_pinset = [ + { + digest = "sha256"; + value = "i2kObfz0qIKCGNWt7MjBUeSrh0Dyjb0/zWINImZES+I="; + } + ]; + } + ]; + }; + }; +} +``` + +Optionally, to use dnsmasq as the DHCP server too, +use the following snippet: + +```nix +services.dnsmasq = { + settings = { + # When switching DNS server, accept old leases from previous server. + dhcp-authoritative = true; + + # Adapt to your needs + # ,,, + dhcp-range = "192.168.1.101,192.168.1.150,255.255.255.0,6h"; + + # Static DNS leases if needed. + # Choose an IP outside of the DHCP range + # ,,, + dhcp-host = [ + "12:34:56:78:9a:bc,server,192.168.1.50,infinite" + ]; + + # Set default route to the router that can acccess the internet. + dhcp-option = [ + "3,192.168.1.1" + ]; + }; +}; +``` diff --git a/docs/redirects.json b/docs/redirects.json index c1401c8..21bb1e4 100644 --- a/docs/redirects.json +++ b/docs/redirects.json @@ -1985,6 +1985,18 @@ "recipes": [ "recipes.html#recipes" ], + "recipes-dnsServer": [ + "recipes-dnsServer.html#recipes-dnsServer" + ], + "recipes-dnsServer-drawbacks": [ + "recipes-dnsServer.html#recipes-dnsServer-drawbacks" + ], + "recipes-dnsServer-recipe": [ + "recipes-dnsServer.html#recipes-dnsServer-recipe" + ], + "recipes-dnsServer-why": [ + "recipes-dnsServer.html#recipes-dnsServer-why" + ], "recipes-exposeService": [ "recipes-exposeService.html#recipes-exposeService" ],