infra/nix/modules/coredns.nix

289 lines
8.0 KiB
Nix

{
lib,
config,
pkgs,
sops-nix,
...
}: let
serial = toString 15;
svc = "coredns.service";
usr = "${toString config.users.users.coredns.name}";
domain = p.domainName;
p = config.sops.placeholder;
in {
networking.firewall = {
allowedTCPPorts = [53];
allowedUDPPorts = [53];
};
sops = {
secrets = {
"domainName".restartUnits = [svc];
"coredns/cidrHomenet".restartUnits = [svc];
"coredns/cidrTailnet".restartUnits = [svc];
"coredns/localDNSCryptResolver".restartUnits = [svc];
"eth/loki".restartUnits = [svc];
"eth/caelum".restartUnits = [svc];
"eth/carina".restartUnits = [svc];
"eth/nixpi".restartUnits = [svc];
"eth/surtur".restartUnits = [svc];
"wlan/loki".restartUnits = [svc];
"wlan/carina".restartUnits = [svc];
"domainName".owner = usr;
"coredns/cidrHomenet".owner = usr;
"coredns/cidrTailnet".owner = usr;
"coredns/localDNSCryptResolver".owner = usr;
"eth/loki".owner = usr;
"eth/caelum".owner = usr;
"eth/carina".owner = usr;
"eth/nixpi".owner = usr;
"eth/surtur".owner = usr;
"wlan/loki".owner = usr;
"wlan/carina".owner = usr;
"domainName".sopsFile = ../secrets/coredns.yaml;
"coredns/cidrHomenet".sopsFile = ../secrets/coredns.yaml;
"coredns/cidrTailnet".sopsFile = ../secrets/coredns.yaml;
"coredns/localDNSCryptResolver".sopsFile = ../secrets/coredns.yaml;
"eth/loki".sopsFile = ../secrets/net.yaml;
"eth/caelum".sopsFile = ../secrets/net.yaml;
"eth/carina".sopsFile = ../secrets/net.yaml;
"eth/nixpi".sopsFile = ../secrets/net.yaml;
"eth/surtur".sopsFile = ../secrets/net.yaml;
"wlan/loki".sopsFile = ../secrets/net.yaml;
"wlan/carina".sopsFile = ../secrets/net.yaml;
};
};
sops.templates = {
corednsZoneInternal = {
owner = usr;
content = ''
$ORIGIN ${domain}.
@ 1D IN SOA ${domain}. root.${domain}. (
${serial} ; serial (yyyymmdd##)
1m ; refresh
1m ; retry
1m ; expiry
1m ) ; minimum ttl
5m IN NS ns0.${domain}.
5m IN NS ns1.${domain}.
5m IN NS ns2.${domain}.
5m IN NS ns3.${domain}.
5m IN NS ns4.${domain}.
ns0 5m IN A ${p."eth/nixpi"}
ns1 5m IN A ${p."eth/carina"}
ns2 5m IN A ${p."eth/loki"}
ns3 5m IN A ${p."wlan/loki"}
ns4 5m IN A ${p."wlan/carina"}
grocy 5m IN A ${p."eth/loki"}
gonic 5m IN A ${p."eth/loki"}
cloud 5m IN A ${p."eth/loki"}
media 5m IN A ${p."eth/caelum"}
llama 5m IN A ${p."eth/caelum"}
llama2 5m IN A ${p."eth/caelum"}
auth 5m IN A ${p."eth/loki"}
whoami 5m IN A ${p."eth/loki"}
ffsync 5m IN A ${p."eth/loki"}
cache 5m IN A ${p."eth/loki"}
nixcache 5m IN CNAME cache.${domain}
uptime 5m IN A ${p."eth/loki"}
carina 5m IN A ${p."eth/carina"}
loki 5m IN A ${p."eth/loki"}
caelum 5m IN A ${p."eth/caelum"}
nixpi 5m IN A ${p."eth/nixpi"}
surtur 5m IN A ${p."eth/surtur"}
'';
};
corednsCorefile = {
owner = usr;
content = ''
. {
# TODO: listen on 853 and 443 and 1443 for DoT and DoH,
# certs will be courtesy of caddy (or acme).
# TODO: ad blocking?
# hosts /etc/coredns/blocklist.hosts {
# fallthrough
# }
reload
bufsize 1232
# TODO: add wlan and tailscale IPs
# bind {$IP} {$IPWLAN} {$IPTailscale}
bind ${p."coredns/ifaces"}
acl {
allow net 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8 192.0.0.0/24 100.64.0.0/10
block
}
hosts {
reload 0
fallthrough
}
# loadbalance
# local dnscrypt-proxy.
forward . ${p."coredns/localDNSCryptResolver"} {
health_check 5s
expire 600s
policy sequential
}
#cache {
# success 4096
# success 10000
# denial 2048
# prefetch 512
#}
whoami
health
prometheus :9153
errors
log
local
any
}
# ${domain} {
# bind {$IPTailscale}
# view tailscale {
# expr incidr(server_ip(), '{$cidrTailnet}')
# }
# reload 300s
# file /etc/coredns/external-tailnet.zone
# cache {
# #success 1000
# success 4096
# denial 2048
# prefetch 512
# keepttl
# }
# errors
# log
#}
${domain} {
bind ${p."coredns/ifaces"}
view homenet {
expr incidr(server_ip(), '${p."coredns/cidrHomenet"}')
}
reload 300s
file ${config.sops.templates.corednsZoneInternal.path}
cache {
success 4096
denial 2048
prefetch 512
keepttl
}
errors
log
local
any
}
# vim: noexpandtab:ft=Corefile
'';
};
corednsEnv = {
content = ''
cidrHomenet=${p."coredns/cidrHomenet"}
cidrTailnet=${p."coredns/cidrTailnet"}
domainName=${domain}
IPTailscale=${p."coredns/iptailscale"}
localDNSCryptResolver=${p."coredns/localDNSCryptResolver"}
'';
};
};
services.coredns = {
enable = true;
config = "import ${config.sops.templates.corednsCorefile.path}";
};
# systemd.services.coredns.unitConfig = {
# upholds = config.systemd.services.dnscrypt-proxy2;
# wants = config.systemd.services.dnscrypt-proxy2;
# };
# systemd.services.coredns.serviceConfig = {
systemd.services.coredns = {
after = ["sops-nix.service"];
# wants = ["dnscrypt-proxy2.service"];
serviceConfig = {
# StateDirectory = "coredns";
# WorkingDirectory = "/etc/coredns";
WorkingDirectory = "/";
# StartLimitIntervalSec = 5;
StartLimitBurst = 10;
Restart = lib.mkForce "always";
RestartSec = 10;
# PermissionsStartOnly = true;
ProtectSystem = "strict";
LimitNOFILE = 1048576;
LimitNPROC = 512;
User = usr;
DynamicUser = lib.mkForce "no";
EnvironmentFile = config.sops.templates.corednsEnv.path;
# LoadCredential = lib.mapAttrsToList (name: path: "${name}:${path}") cfg.credentials;
DeviceAllow = "";
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateTmp = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
# DynamicUser = true;
ProtectProc = "invisible";
RemoveIPC = true;
# RestrictAddressFamilies = ["AF_INET" "AF_INET6" "AF_UNIX"];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallErrorNumber = "EPERM";
SystemCallFilter = [
"@system-service"
"~@cpu-emulation"
"~@debug"
"~@keyring"
"~@memlock"
"~@obsolete"
# "~@privileged"
"~@setuid"
];
UMask = 0027;
};
};
users.users.coredns = {
group = usr;
home = "/etc/" + usr;
createHome = false;
isSystemUser = true;
extraGroups = ["users"];
};
users.groups.coredns = {};
}