2023-11-03 00:11:13 +02:00
|
|
|
{ cluster, config, depot, lib, pkgs, ... }:
|
2022-08-07 20:58:37 +03:00
|
|
|
|
|
|
|
let
|
2023-03-07 02:26:07 +02:00
|
|
|
inherit (depot.reflection) interfaces;
|
2023-08-31 01:55:45 +03:00
|
|
|
inherit (depot.lib.meta) domain;
|
2023-03-23 00:00:29 +02:00
|
|
|
inherit (config.networking) hostName;
|
2022-08-07 20:58:37 +03:00
|
|
|
|
2023-03-23 00:00:29 +02:00
|
|
|
link = cluster.config.hostLinks.${hostName}.dnsAuthoritative;
|
2022-08-07 20:58:37 +03:00
|
|
|
patroni = cluster.config.links.patroni-pg-access;
|
2023-12-03 17:30:16 +02:00
|
|
|
inherit (cluster.config.hostLinks.${hostName}) acmeDnsApi;
|
2022-08-07 20:58:37 +03:00
|
|
|
|
2023-12-03 17:30:16 +02:00
|
|
|
otherDnsServers = lib.pipe (cluster.config.services.dns.otherNodes.authoritative hostName) [
|
2023-03-23 00:00:29 +02:00
|
|
|
(map (node: cluster.config.hostLinks.${node}.dnsAuthoritative.tuple))
|
|
|
|
(lib.concatStringsSep " ")
|
|
|
|
];
|
|
|
|
|
2023-12-03 17:30:16 +02:00
|
|
|
recordsList = lib.mapAttrsToList (lib.const lib.id) cluster.config.dns.records;
|
|
|
|
recordsPartitioned = lib.partition (record: record.rewrite.target == null) recordsList;
|
2023-11-03 00:11:13 +02:00
|
|
|
|
2023-12-03 17:30:16 +02:00
|
|
|
staticRecords = let
|
|
|
|
escape = type: {
|
|
|
|
TXT = builtins.toJSON;
|
|
|
|
}.${type} or lib.id;
|
2023-11-03 00:11:13 +02:00
|
|
|
|
2023-12-03 17:30:16 +02:00
|
|
|
recordName = record: {
|
|
|
|
"@" = "${record.root}.";
|
|
|
|
}.${record.name} or "${record.name}.${record.root}.";
|
|
|
|
in lib.flatten (
|
|
|
|
map (record: map (target: "${recordName record} ${record.type} ${escape record.type target}") record.target) recordsPartitioned.right
|
|
|
|
);
|
|
|
|
|
|
|
|
rewrites = map (record: let
|
2023-11-03 00:58:49 +02:00
|
|
|
maybeEscapeRegex = str: if record.rewrite.type == "regex" then "${lib.escapeRegex str}$" else str;
|
2023-12-03 17:30:16 +02:00
|
|
|
in "rewrite stop name ${record.rewrite.type} ${record.name}${maybeEscapeRegex ".${record.root}."} ${record.rewrite.target}. answer auto") recordsPartitioned.wrong;
|
2023-11-03 00:11:13 +02:00
|
|
|
|
|
|
|
rewriteConf = pkgs.writeText "coredns-rewrites.conf" (lib.concatStringsSep "\n" rewrites);
|
2022-08-07 20:58:37 +03:00
|
|
|
in {
|
2023-03-05 23:00:18 +02:00
|
|
|
links.localAuthoritativeDNS = {};
|
|
|
|
|
2022-08-07 20:58:37 +03:00
|
|
|
age.secrets = {
|
2023-12-03 17:30:16 +02:00
|
|
|
acmeDnsDbCredentials = {
|
|
|
|
file = ./acme-dns-db-credentials.age;
|
|
|
|
};
|
|
|
|
acmeDnsDirectKey = {
|
|
|
|
file = ./acme-dns-direct-key.age;
|
2022-08-07 20:58:37 +03:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
networking.firewall = {
|
|
|
|
allowedTCPPorts = [ 53 ];
|
|
|
|
allowedUDPPorts = [ 53 ];
|
|
|
|
};
|
|
|
|
|
2023-12-03 17:30:16 +02:00
|
|
|
services.acme-dns = {
|
2022-08-07 20:58:37 +03:00
|
|
|
enable = true;
|
2023-12-03 17:30:16 +02:00
|
|
|
package = depot.packages.acme-dns;
|
|
|
|
settings = {
|
|
|
|
general = {
|
|
|
|
listen = config.links.localAuthoritativeDNS.tuple;
|
|
|
|
inherit domain;
|
|
|
|
nsadmin = "hostmaster.${domain}";
|
|
|
|
nsname = "eu1.ns.${domain}";
|
|
|
|
records = staticRecords;
|
|
|
|
};
|
|
|
|
api = {
|
|
|
|
ip = acmeDnsApi.ipv4;
|
|
|
|
inherit (acmeDnsApi) port;
|
|
|
|
};
|
|
|
|
database = {
|
|
|
|
engine = "postgres";
|
|
|
|
connection = "postgres://acmedns@${patroni.tuple}/acmedns?sslmode=disable";
|
|
|
|
};
|
2022-08-07 20:58:37 +03:00
|
|
|
};
|
|
|
|
};
|
2023-03-05 23:00:18 +02:00
|
|
|
|
2023-12-03 17:30:16 +02:00
|
|
|
systemd.services.acme-dns.serviceConfig.EnvironmentFile = with config.age.secrets; [
|
|
|
|
acmeDnsDbCredentials.path
|
|
|
|
acmeDnsDirectKey.path
|
|
|
|
];
|
|
|
|
|
2023-03-05 23:00:18 +02:00
|
|
|
services.coredns = {
|
|
|
|
enable = true;
|
|
|
|
config = ''
|
2023-03-23 00:00:29 +02:00
|
|
|
.:${link.portStr} {
|
2023-03-05 23:00:18 +02:00
|
|
|
bind ${interfaces.primary.addr}
|
|
|
|
chaos "Private Void DNS" info@privatevoid.net
|
|
|
|
cache {
|
|
|
|
success 4000 86400
|
|
|
|
denial 0
|
|
|
|
prefetch 3
|
|
|
|
serve_stale 86400s
|
|
|
|
}
|
2023-11-04 04:59:27 +02:00
|
|
|
trace zipkin ${cluster.config.links.tempo-zipkin-http.tuple} {
|
|
|
|
every 100
|
|
|
|
client_server
|
|
|
|
}
|
2023-03-05 23:16:06 +02:00
|
|
|
forward service.eu-central.sd-magic.${domain} 127.0.0.1:8600
|
2023-03-06 01:49:44 +02:00
|
|
|
forward addr.eu-central.sd-magic.${domain} 127.0.0.1:8600
|
2023-11-03 00:11:13 +02:00
|
|
|
import ${rewriteConf}
|
2023-03-23 00:00:29 +02:00
|
|
|
forward . ${config.links.localAuthoritativeDNS.tuple} ${otherDnsServers} {
|
|
|
|
policy sequential
|
|
|
|
}
|
2023-03-05 23:00:18 +02:00
|
|
|
}
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
systemd.services.coredns = {
|
2023-12-03 17:30:16 +02:00
|
|
|
after = [ "acme-dns.service" ];
|
2023-03-05 23:00:18 +02:00
|
|
|
};
|
2023-03-06 00:50:50 +02:00
|
|
|
|
2023-12-03 17:30:16 +02:00
|
|
|
consul.services = {
|
|
|
|
authoritative-dns = {
|
|
|
|
unit = "acme-dns";
|
|
|
|
definition = {
|
|
|
|
name = "authoritative-dns-backend";
|
|
|
|
address = config.links.localAuthoritativeDNS.ipv4;
|
|
|
|
port = config.links.localAuthoritativeDNS.port;
|
|
|
|
checks = lib.singleton {
|
|
|
|
interval = "60s";
|
|
|
|
tcp = config.links.localAuthoritativeDNS.tuple;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
acme-dns.definition = {
|
|
|
|
name = "acme-dns";
|
|
|
|
address = acmeDnsApi.ipv4;
|
|
|
|
port = acmeDnsApi.port;
|
2023-03-06 00:50:50 +02:00
|
|
|
checks = lib.singleton {
|
|
|
|
interval = "60s";
|
2023-12-03 17:30:16 +02:00
|
|
|
http = "${acmeDnsApi.url}/health";
|
2023-03-06 00:50:50 +02:00
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
2022-08-07 20:58:37 +03:00
|
|
|
}
|