summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/dns.nix134
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}";
};
}