diff options
| author | Mel <mel@rnrd.eu> | 2025-02-21 00:04:39 +0100 |
|---|---|---|
| committer | Mel <mel@rnrd.eu> | 2025-02-21 00:04:39 +0100 |
| commit | 5a8161e086232c5d2262fc53a005464d16006eb5 (patch) | |
| tree | dfbf36285f54b81a9c29f6e663edc48f179ff25d /modules/dns.nix | |
| parent | 5db8f66792fd9a0d73eda57b188dd0e0074281b9 (diff) | |
| download | network-5a8161e086232c5d2262fc53a005464d16006eb5.tar.zst network-5a8161e086232c5d2262fc53a005464d16006eb5.zip | |
Expose DNS server with additional DoH/DoT capabilities
Signed-off-by: Mel <mel@rnrd.eu>
Diffstat (limited to 'modules/dns.nix')
| -rw-r--r-- | modules/dns.nix | 134 |
1 files changed, 115 insertions, 19 deletions
diff --git a/modules/dns.nix b/modules/dns.nix index 235411d..0e17259 100644 --- a/modules/dns.nix +++ b/modules/dns.nix @@ -1,42 +1,138 @@ -{ oisd, ... }: +{ config, oisd, ... }: let + inherit (config.age) secrets; + tailscaleDns = [ "/serval-moth.ts.net/100.100.100.100" ]; cloudflareServers = [ - "1.1.1.1" "1.0.0.1" - "2606:4700:4700::1111" "2606:4700:4700::1001" + "1.1.1.1" + "1.0.0.1" + "2606:4700:4700::1111" + "2606:4700:4700::1001" ]; quad9Servers = [ - "9.9.9.9" "149.112.112.112" - "2620:fe::fe" "2620:fe::9" + "9.9.9.9" + "149.112.112.112" + "2620:fe::fe" + "2620:fe::9" ]; upstreamServers = cloudflareServers ++ quad9Servers ++ tailscaleDns; + + dnsProxyPort = 4157; + dohInternalPort = 4158; + dotInternalPort = 4159; + + # well-known + dnsPort = 53; + dotPort = 853; in { + networking.firewall = { + allowedTCPPorts = [ + dnsPort + dotPort + ]; + allowedUDPPorts = [ dnsPort ]; + }; services.resolved.enable = false; - services.dnsmasq = { - enable = true; + age.secrets.internal-tls = { + file = ../secrets/internal-tls.age; + }; + + services = { + dnsmasq = { + enable = true; + + # Ref: https://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html + settings = { + interface = [ + "enp1s0" + "tailscale0" + ]; + bind-dynamic = true; + + server = upstreamServers; + cache-size = 4096; + + no-resolv = true; + bogus-priv = true; + domain-needed = true; + localise-queries = true; - # Ref: https://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html - settings = { - interface = [ "enp1s0" "tailscale0" ]; - bind-dynamic = true; + conf-file = "${oisd}/dnsmasq2_big.txt"; - server = upstreamServers; - cache-size = 4096; + log-queries = "extra"; + }; + }; - no-resolv = true; - bogus-priv = true; - domain-needed = true; - localise-queries = true; + dnsproxy = { + enable = true; + settings = { + listen-addrs = [ "127.0.0.1" ]; + listen-ports = [ dnsProxyPort ]; # just so that it doesn't bind to 53 + upstream = [ "127.0.0.1:53" ]; + cache = false; - conf-file = "${oisd}/dnsmasq2_big.txt"; + # NOTE: DoH only supports DNS Wireformat so far. + # JSON support has been requested. + # see issue: https://github.com/AdguardTeam/dnsproxy/issues/422 + # NOTE(2): also, there's an open PR to avoid dealing with these + # certificates and expose dnsproxy through HTTP, to later + # reverse proxy Nginx to it, like I'm doing here. + # see: https://github.com/AdguardTeam/dnsproxy/pull/302 + https-port = [ dohInternalPort ]; + tls-port = [ dotInternalPort ]; - log-queries = "extra"; + tls-crt = ../assets/internal-tls.crt; + }; + flags = [ "--tls-key=\${CREDENTIALS_DIRECTORY}/internal-tls" ]; }; + + nginx = { + # DNS-over-HTTPS + virtualHosts."dns.rnrd.eu" = { + useACMEHost = "rnrd.eu"; + forceSSL = true; + + locations."/" = { + proxyPass = "https://127.0.0.1:${toString dohInternalPort}"; + extraConfig = '' + proxy_ssl_trusted_certificate ${../assets/internal-tls.crt}; + proxy_ssl_verify off; + ''; + }; + + extraConfig = '' + access_log /var/log/nginx/dns.access.log json_combined; + ''; + }; + + # DNS-over-TLS + streamConfig = + let + rnrdCertPath = config.security.acme.certs."rnrd.eu".directory; + in + '' + server { + listen [::]:${toString dotPort} ssl ipv6only=off; + ssl_certificate ${rnrdCertPath}/fullchain.pem; + ssl_certificate_key ${rnrdCertPath}/key.pem; + ssl_trusted_certificate ${rnrdCertPath}/chain.pem; + + proxy_pass 127.0.0.1:${toString dotInternalPort}; + proxy_ssl on; + proxy_ssl_trusted_certificate ${../assets/internal-tls.crt}; + proxy_ssl_verify off; + } + ''; + }; + }; + + systemd.services.dnsproxy.serviceConfig = { + LoadCredential = "internal-tls:${secrets.internal-tls.path}"; }; } |
