From 7985d891a0c4465e84ce61a15797cfc0ae62dd5d Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 22 Mar 2023 23:00:29 +0100 Subject: [PATCH] cluster/services/dns: improve resiliency --- cluster/services/dns/authoritative.nix | 13 +++++- cluster/services/dns/coredns.nix | 63 +++++++++++++++++++++----- cluster/services/dns/default.nix | 24 +++++++++- 3 files changed, 84 insertions(+), 16 deletions(-) diff --git a/cluster/services/dns/authoritative.nix b/cluster/services/dns/authoritative.nix index 30326f4..499be79 100644 --- a/cluster/services/dns/authoritative.nix +++ b/cluster/services/dns/authoritative.nix @@ -3,9 +3,16 @@ let inherit (depot.reflection) interfaces; inherit (tools.meta) domain; + inherit (config.networking) hostName; + link = cluster.config.hostLinks.${hostName}.dnsAuthoritative; patroni = cluster.config.links.patroni-pg-access; + otherDnsServers = lib.pipe (with cluster.config.services.dns.otherNodes; master ++ slave) [ + (map (node: cluster.config.hostLinks.${node}.dnsAuthoritative.tuple)) + (lib.concatStringsSep " ") + ]; + translateConfig = cfg: let configList = lib.mapAttrsToList (n: v: "${n}=${v}") cfg; in lib.concatStringsSep "\n" configList; @@ -46,7 +53,7 @@ in { services.coredns = { enable = true; config = '' - . { + .:${link.portStr} { bind ${interfaces.primary.addr} chaos "Private Void DNS" info@privatevoid.net cache { @@ -57,7 +64,9 @@ in { } forward service.eu-central.sd-magic.${domain} 127.0.0.1:8600 forward addr.eu-central.sd-magic.${domain} 127.0.0.1:8600 - forward . ${config.links.localAuthoritativeDNS.tuple} + forward . ${config.links.localAuthoritativeDNS.tuple} ${otherDnsServers} { + policy sequential + } } ''; }; diff --git a/cluster/services/dns/coredns.nix b/cluster/services/dns/coredns.nix index a991914..310d2ce 100644 --- a/cluster/services/dns/coredns.nix +++ b/cluster/services/dns/coredns.nix @@ -1,9 +1,24 @@ -{ config, depot, lib, pkgs, tools, ... }: +{ cluster, config, depot, lib, pkgs, tools, ... }: let - inherit (depot.reflection) interfaces; + inherit (depot.reflection) interfaces hyprspace; inherit (tools.meta) domain; inherit (config.links) localRecursor; + inherit (config.networking) hostName; + + link = cluster.config.hostLinks.${hostName}.dnsResolver; + backend = cluster.config.hostLinks.${hostName}.dnsResolverBackend; + + otherRecursors = lib.pipe (cluster.config.services.dns.otherNodes.coredns) [ + (map (node: cluster.config.hostLinks.${node}.dnsResolverBackend.tuple)) + (lib.concatStringsSep " ") + ]; + + authoritativeServers = lib.pipe (with cluster.config.services.dns.nodes; master ++ slave) [ + (map (node: cluster.config.hostLinks.${node}.dnsAuthoritative.tuple)) + (lib.concatStringsSep ";") + ]; + inherit (depot.packages) stevenblack-hosts; dot = config.security.acme.certs."securedns.${domain}"; in @@ -17,7 +32,11 @@ in }; systemd.services.coredns = { - after = lib.optional (interfaces ? vstub) "network-addresses-vstub.service"; + after = (lib.optional (interfaces ? vstub) "network-addresses-vstub.service") ++ [ + "acme-selfsigned-securedns.${domain}.service" + ]; + before = [ "acme-securedns.${domain}.service" ]; + wants = [ "acme-finished-securedns.${domain}.target" ]; serviceConfig.LoadCredential = [ "dot-cert.pem:${dot.directory}/fullchain.pem" "dot-key.pem:${dot.directory}/key.pem" @@ -25,8 +44,7 @@ in }; security.acme.certs."securedns.${domain}" = { - group = "nginx"; - webroot = "/var/lib/acme/acme-challenge"; + dnsProvider = "pdns"; # using a different ACME provider because Android Private DNS is fucky server = "https://api.buypass.com/acme/directory"; reloadServices = [ @@ -37,14 +55,18 @@ in services.coredns = { enable = true; config = '' - . { + .:${link.portStr} { ${lib.optionalString (interfaces ? vstub) "bind ${interfaces.vstub.addr}"} bind 127.0.0.1 + bind ${link.ipv4} + ${lib.optionalString hyprspace.enable "bind ${hyprspace.addr}"} hosts ${stevenblack-hosts} { fallthrough } chaos "Private Void DNS" info@privatevoid.net - forward . ${localRecursor.tuple} + forward . ${backend.tuple} ${otherRecursors} { + policy sequential + } } tls://.:853 { bind ${interfaces.primary.addr} @@ -53,7 +75,9 @@ in fallthrough } chaos "Private Void DNS" info@privatevoid.net - forward . ${localRecursor.tuple} + forward . ${backend.tuple} ${otherRecursors} { + policy sequential + } } ''; }; @@ -63,12 +87,27 @@ in dnssecValidation = "process"; forwardZones = { # optimize queries against our own domain - "${domain}" = interfaces.primary.addr; + "${domain}" = authoritativeServers; }; dns = { - inherit (localRecursor) port; - address = localRecursor.ipv4; - allowFrom = [ "127.0.0.1" ]; + inherit (backend) port; + address = backend.ipv4; + allowFrom = [ "127.0.0.1" cluster.config.vars.meshNet.cidr "10.100.3.0/24" ]; + }; + }; + + consul.services.securedns = { + unit = "coredns"; + mode = "external"; + definition = rec { + name = "securedns"; + address = interfaces.primary.addrPublic; + port = 853; + checks = lib.singleton { + name = "SecureDNS"; + tcp = "${address}:${toString port}"; + interval = "30s"; + }; }; }; } diff --git a/cluster/services/dns/default.nix b/cluster/services/dns/default.nix index 18edb9f..7edad4c 100644 --- a/cluster/services/dns/default.nix +++ b/cluster/services/dns/default.nix @@ -1,7 +1,8 @@ -{ config, depot, ... }: +{ config, depot, lib, ... }: let inherit (depot.config) hours; + cfg = config.services.dns; in { vars.pdns-api-key-secret = { @@ -18,11 +19,30 @@ in protocol = "http"; }; }; + hostLinks = lib.mkMerge [ + (lib.genAttrs (with cfg.nodes; master ++ slave) (node: { + dnsAuthoritative = { + ipv4 = hours.${node}.interfaces.primary.addrPublic; + port = 53; + }; + })) + (lib.genAttrs cfg.nodes.coredns (node: { + dnsResolver = { + ipv4 = config.vars.mesh.${node}.meshIp; + port = 53; + }; + })) + (lib.genAttrs cfg.nodes.coredns (node: { + dnsResolverBackend = { + ipv4 = config.vars.mesh.${node}.meshIp; + }; + })) + ]; services.dns = { nodes = { master = [ "VEGAS" ]; slave = [ "checkmate" "prophet" ]; - coredns = [ "VEGAS" ]; + coredns = [ "checkmate" "VEGAS" ]; client = [ "VEGAS" "prophet" ]; }; nixos = {