cluster/services/dns: improve resiliency
This commit is contained in:
parent
694bd7d712
commit
7985d891a0
3 changed files with 84 additions and 16 deletions
|
@ -3,9 +3,16 @@
|
||||||
let
|
let
|
||||||
inherit (depot.reflection) interfaces;
|
inherit (depot.reflection) interfaces;
|
||||||
inherit (tools.meta) domain;
|
inherit (tools.meta) domain;
|
||||||
|
inherit (config.networking) hostName;
|
||||||
|
|
||||||
|
link = cluster.config.hostLinks.${hostName}.dnsAuthoritative;
|
||||||
patroni = cluster.config.links.patroni-pg-access;
|
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
|
translateConfig = cfg: let
|
||||||
configList = lib.mapAttrsToList (n: v: "${n}=${v}") cfg;
|
configList = lib.mapAttrsToList (n: v: "${n}=${v}") cfg;
|
||||||
in lib.concatStringsSep "\n" configList;
|
in lib.concatStringsSep "\n" configList;
|
||||||
|
@ -46,7 +53,7 @@ in {
|
||||||
services.coredns = {
|
services.coredns = {
|
||||||
enable = true;
|
enable = true;
|
||||||
config = ''
|
config = ''
|
||||||
. {
|
.:${link.portStr} {
|
||||||
bind ${interfaces.primary.addr}
|
bind ${interfaces.primary.addr}
|
||||||
chaos "Private Void DNS" info@privatevoid.net
|
chaos "Private Void DNS" info@privatevoid.net
|
||||||
cache {
|
cache {
|
||||||
|
@ -57,7 +64,9 @@ in {
|
||||||
}
|
}
|
||||||
forward service.eu-central.sd-magic.${domain} 127.0.0.1:8600
|
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 addr.eu-central.sd-magic.${domain} 127.0.0.1:8600
|
||||||
forward . ${config.links.localAuthoritativeDNS.tuple}
|
forward . ${config.links.localAuthoritativeDNS.tuple} ${otherDnsServers} {
|
||||||
|
policy sequential
|
||||||
|
}
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,24 @@
|
||||||
{ config, depot, lib, pkgs, tools, ... }:
|
{ cluster, config, depot, lib, pkgs, tools, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (depot.reflection) interfaces;
|
inherit (depot.reflection) interfaces hyprspace;
|
||||||
inherit (tools.meta) domain;
|
inherit (tools.meta) domain;
|
||||||
inherit (config.links) localRecursor;
|
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;
|
inherit (depot.packages) stevenblack-hosts;
|
||||||
dot = config.security.acme.certs."securedns.${domain}";
|
dot = config.security.acme.certs."securedns.${domain}";
|
||||||
in
|
in
|
||||||
|
@ -17,7 +32,11 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.coredns = {
|
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 = [
|
serviceConfig.LoadCredential = [
|
||||||
"dot-cert.pem:${dot.directory}/fullchain.pem"
|
"dot-cert.pem:${dot.directory}/fullchain.pem"
|
||||||
"dot-key.pem:${dot.directory}/key.pem"
|
"dot-key.pem:${dot.directory}/key.pem"
|
||||||
|
@ -25,8 +44,7 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
security.acme.certs."securedns.${domain}" = {
|
security.acme.certs."securedns.${domain}" = {
|
||||||
group = "nginx";
|
dnsProvider = "pdns";
|
||||||
webroot = "/var/lib/acme/acme-challenge";
|
|
||||||
# using a different ACME provider because Android Private DNS is fucky
|
# using a different ACME provider because Android Private DNS is fucky
|
||||||
server = "https://api.buypass.com/acme/directory";
|
server = "https://api.buypass.com/acme/directory";
|
||||||
reloadServices = [
|
reloadServices = [
|
||||||
|
@ -37,14 +55,18 @@ in
|
||||||
services.coredns = {
|
services.coredns = {
|
||||||
enable = true;
|
enable = true;
|
||||||
config = ''
|
config = ''
|
||||||
. {
|
.:${link.portStr} {
|
||||||
${lib.optionalString (interfaces ? vstub) "bind ${interfaces.vstub.addr}"}
|
${lib.optionalString (interfaces ? vstub) "bind ${interfaces.vstub.addr}"}
|
||||||
bind 127.0.0.1
|
bind 127.0.0.1
|
||||||
|
bind ${link.ipv4}
|
||||||
|
${lib.optionalString hyprspace.enable "bind ${hyprspace.addr}"}
|
||||||
hosts ${stevenblack-hosts} {
|
hosts ${stevenblack-hosts} {
|
||||||
fallthrough
|
fallthrough
|
||||||
}
|
}
|
||||||
chaos "Private Void DNS" info@privatevoid.net
|
chaos "Private Void DNS" info@privatevoid.net
|
||||||
forward . ${localRecursor.tuple}
|
forward . ${backend.tuple} ${otherRecursors} {
|
||||||
|
policy sequential
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tls://.:853 {
|
tls://.:853 {
|
||||||
bind ${interfaces.primary.addr}
|
bind ${interfaces.primary.addr}
|
||||||
|
@ -53,7 +75,9 @@ in
|
||||||
fallthrough
|
fallthrough
|
||||||
}
|
}
|
||||||
chaos "Private Void DNS" info@privatevoid.net
|
chaos "Private Void DNS" info@privatevoid.net
|
||||||
forward . ${localRecursor.tuple}
|
forward . ${backend.tuple} ${otherRecursors} {
|
||||||
|
policy sequential
|
||||||
|
}
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
@ -63,12 +87,27 @@ in
|
||||||
dnssecValidation = "process";
|
dnssecValidation = "process";
|
||||||
forwardZones = {
|
forwardZones = {
|
||||||
# optimize queries against our own domain
|
# optimize queries against our own domain
|
||||||
"${domain}" = interfaces.primary.addr;
|
"${domain}" = authoritativeServers;
|
||||||
};
|
};
|
||||||
dns = {
|
dns = {
|
||||||
inherit (localRecursor) port;
|
inherit (backend) port;
|
||||||
address = localRecursor.ipv4;
|
address = backend.ipv4;
|
||||||
allowFrom = [ "127.0.0.1" ];
|
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";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
{ config, depot, ... }:
|
{ config, depot, lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (depot.config) hours;
|
inherit (depot.config) hours;
|
||||||
|
cfg = config.services.dns;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
vars.pdns-api-key-secret = {
|
vars.pdns-api-key-secret = {
|
||||||
|
@ -18,11 +19,30 @@ in
|
||||||
protocol = "http";
|
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 = {
|
services.dns = {
|
||||||
nodes = {
|
nodes = {
|
||||||
master = [ "VEGAS" ];
|
master = [ "VEGAS" ];
|
||||||
slave = [ "checkmate" "prophet" ];
|
slave = [ "checkmate" "prophet" ];
|
||||||
coredns = [ "VEGAS" ];
|
coredns = [ "checkmate" "VEGAS" ];
|
||||||
client = [ "VEGAS" "prophet" ];
|
client = [ "VEGAS" "prophet" ];
|
||||||
};
|
};
|
||||||
nixos = {
|
nixos = {
|
||||||
|
|
Loading…
Reference in a new issue