hosts/plover: change DNS server to Bind9

CoreDNS doesn't have dynamic updates available yet (though there are PRs
and discussions for it) so we'll have to go with something that has it.
Also, it provides an opportunity for me to use the de-facto software for
this.
This commit is contained in:
Gabriel Arazas 2023-06-22 17:56:47 +08:00
parent 1760a6cfc9
commit eb1003f7e6
No known key found for this signature in database
GPG Key ID: ADE0C41DAB221FCC
9 changed files with 184 additions and 10 deletions

View File

@ -1,9 +1,10 @@
; This is trying to be discrete with certain information. This should be copied ; This is trying to be discrete with certain information. This should be copied
; and replaced with more confidential information somewhere. ; and replaced with more confidential information somewhere.
$TTL 12h $TTL 12h
$ORIGIN foodogsquared.one.
@ 3600 IN SOA ns1.first-ns.de. hostmaster.foodogsquared.one. ( @ 3600 IN SOA ns1.first-ns.de. hostmaster.foodogsquared.one. (
2023061201 ; serial number 2023062201 ; serial number
1h ; refresh 1h ; refresh
15m ; update retry 15m ; update retry
3w ; expiry 3w ; expiry
@ -48,14 +49,16 @@ wiki IN CNAME foodogsquared-wiki.netlify.app.
; Public-facing services from this server. Just remember to increment the ; Public-facing services from this server. Just remember to increment the
; serial number once the public IPs changes. PLEEEEEEEEEEEAAAAAAAAASE! ; serial number once the public IPs changes. PLEEEEEEEEEEEAAAAAAAAASE!
plover IN A @ploverPublicIPv4@ plover IN A @ploverWANIPv4@
plover IN AAAA @ploverPublicIPv6@ plover IN AAAA @ploverWANIPv6@
auth IN CNAME plover auth IN CNAME plover
pass IN CNAME plover pass IN CNAME plover
code IN CNAME plover code IN CNAME plover
vpn IN CNAME plover vpn IN CNAME plover
postgres IN CNAME plover
; Other things. ; Other things.
_github-pages-challenge-foo-dogsquared IN TXT 673febae1ea0095e76d1e02a7a1709 _github-pages-challenge-foo-dogsquared IN TXT 673febae1ea0095e76d1e02a7a1709

View File

@ -0,0 +1,19 @@
$TTL 12h
$ORIGIN plover.foodogsquared.one.
@ 3600 IN SOA ns hostmaster.foodogsquared.one. (
2023062201 ; serial number
1h ; refresh
15m ; update retry
3w ; expiry
2h ; nx = nxdomain ttl
)
3600 IN NS ns
ns 3600 IN A @ploverLANIPv4@
3600 IN AAAA @ploverLANIPv6@
* 3600 IN A @ploverLANIPv4@
3600 IN AAAA @ploverLANIPv6@
; vim: expandtab! tabstop=8 shiftwidth=8 filetype=dns

View File

@ -23,7 +23,7 @@ in
"${modulesPath}/profiles/hardened.nix" "${modulesPath}/profiles/hardened.nix"
# The primary DNS server that is completely hidden. # The primary DNS server that is completely hidden.
./modules/services/coredns.nix ./modules/services/bind.nix
# The reverse proxy of choice. # The reverse proxy of choice.
./modules/services/nginx.nix ./modules/services/nginx.nix
@ -145,11 +145,12 @@ in
}; };
# DNS-related settings. We're settling by configuring the ACME setup with a # DNS-related settings. We're settling by configuring the ACME setup with a
# DNS provider. # self-hosted DNS server.
security.acme.defaults = { security.acme.defaults = {
email = "admin@foodogsquared.one"; email = "admin@foodogsquared.one";
dnsProvider = "porkbun"; dnsProvider = "rfc2136";
credentialsFile = config.sops.secrets."plover/lego/env".path; credentialsFile = config.sops.secrets."plover/lego/env".path;
dnsPropagationCheck = false;
}; };
services.openssh.hostKeys = [{ services.openssh.hostKeys = [{

View File

@ -0,0 +1,148 @@
{ config, lib, pkgs, ... }:
let
inherit (config.networking) domain fqdn;
inherit (import ../hardware/networks.nix) privateIPv6Prefix interfaces clientNetworks serverNetworks secondaryNameServers wireguardPeers;
secondaryNameserverDomains = lib.attrNames secondaryNameServers;
secondaryNameServersIPv4 = lib.foldl'
(total: addresses: total ++ addresses.IPv4)
[ ]
(lib.attrValues secondaryNameServers);
secondaryNameServersIPv6 = lib.foldl'
(total: addresses: total ++ addresses.IPv6)
[ ]
(lib.attrValues secondaryNameServers);
secondaryNameServersIPs = secondaryNameServersIPv4 ++ secondaryNameServersIPv6;
domainZone = pkgs.substituteAll {
src = ../../config/dns/${domain}.zone;
ploverWANIPv4 = interfaces.wan.IPv4.address;
ploverWANIPv6 = interfaces.wan.IPv6.address;
};
fqdnZone = pkgs.substituteAll {
src = ../../config/dns/${fqdn}.zone;
ploverLANIPv4 = interfaces.lan.IPv4.address;
ploverLANIPv6 = interfaces.lan.IPv6.address;
};
zonesDir = "/var/db/dns";
zoneFile = domain: "${zonesDir}/${domain}.zone";
localhostIP = [
"127.0.0.1"
"::1"
];
allowedLANIPs = [
# Loopback address
"127.0.0.0/8"
# Private uses
"10.48.0.0/12"
"172.27.0.0/16" # The private subnet for our internal network.
"172.28.0.0/16" # The Wireguard subnet.
];
allowedLANIPv6s = [
"::1" # Loopback
"${privateIPv6Prefix}::/48" # Private uses
];
in
{
sops.secrets =
let
getKey = key: {
inherit key;
sopsFile = ../../secrets/secrets.yaml;
};
getSecrets = secrets:
lib.mapAttrs'
(secret: config:
lib.nameValuePair
"plover/${secret}"
((getKey secret) // config))
secrets;
in
getSecrets {
"dns/${domain}/mailbox-security-key" = { };
"dns/${domain}/mailbox-security-key-record" = { };
};
networking.nameservers = localhostIP;
environment.etc."bind/named.conf".source = config.services.bind.configFile;
services.bind = {
enable = true;
forward = "first";
forwarders = [ "127.0.0.53 port 53" ];
listenOn = [
"127.0.0.1"
interfaces.lan.IPv4.address
interfaces.wan.IPv4.address
];
listenOnIpv6 = [
"::1"
interfaces.lan.IPv6.address
interfaces.wan.IPv6.address
];
extraConfig = ''
acl internals { ${lib.concatStringsSep "; " (clientNetworks ++ serverNetworks ++ [ "127.0.0.0/8" "::1" ])}; };
'';
extraOptions = ''
allow-recursion { internals; };
empty-zones-enable yes;
'';
zones = {
"${config.networking.domain}" = {
file = zoneFile domain;
allowQuery = allowedLANIPs ++ allowedLANIPv6s;
master = true;
slaves = secondaryNameServersIPs;
extraConfig = ''
forwarders { };
update-policy local;
'';
};
"${config.networking.fqdn}" = {
file = zoneFile fqdn;
master = true;
allowQuery = allowedLANIPs ++ allowedLANIPv6s;
slaves = [ "none" ];
};
};
};
networking.firewall.extraInputRules =
let
allowedIPs = secondaryNameServersIPv4 ++ allowedLANIPs;
allowedIPv6s = secondaryNameServersIPv6 ++ allowedLANIPv6s;
in
''
meta l4proto {tcp, udp} th dport domain ip saddr { ${lib.concatStringsSep ", " allowedIPs} } accept comment "Accept DNS queries from secondary nameservers and private networks"
meta l4proto {tcp, udp} th dport domain ip6 saddr { ${lib.concatStringsSep ", " allowedIPv6s} } accept comment "Accept DNS queries from secondary nameservers and private networks"
meta l4proto {tcp, udp} th dport domain-s ip saddr { ${lib.concatStringsSep ", " allowedIPs} } accept comment "Accept DNS queries from secondary nameservers and private networks"
meta l4proto {tcp, udp} th dport domain-s ip6 saddr { ${lib.concatStringsSep ", " allowedIPv6s} } accept comment "Accept DNS queries from secondary nameservers and private networks"
'';
systemd.services.bind = {
preStart = let
secretsPath = path: config.sops.secrets."plover/${path}".path;
replaceSecretBin = "${lib.getBin pkgs.replace-secret}/bin/replace-secret";
in
lib.mkBefore ''
install -Dm0644 ${domainZone} ${zoneFile domain}
install -Dm0644 ${fqdnZone} ${zoneFile fqdn}
${replaceSecretBin} '#mailboxSecurityKey#' '${secretsPath "dns/${domain}/mailbox-security-key"}' '${zoneFile domain}'
${replaceSecretBin} '#mailboxSecurityKeyRecord#' '${secretsPath "dns/${domain}/mailbox-security-key-record"}' '${zoneFile domain}'
'';
};
}

View File

@ -9,9 +9,9 @@ let
inherit (import ../hardware/networks.nix) privateIPv6Prefix interfaces clientNetworks serverNetworks secondaryNameServers wireguardPeers; inherit (import ../hardware/networks.nix) privateIPv6Prefix interfaces clientNetworks serverNetworks secondaryNameServers wireguardPeers;
domainZoneFile = pkgs.substituteAll { domainZoneFile = pkgs.substituteAll {
src = ../../config/coredns/${domain}.zone;
ploverPublicIPv4 = interfaces.main'.IPv4.address; ploverPublicIPv4 = interfaces.main'.IPv4.address;
ploverPublicIPv6 = interfaces.main'.IPv6.address; ploverPublicIPv6 = interfaces.main'.IPv6.address;
src = ../../config/dns/${domain}.zone;
}; };
# The final location of the thing. # The final location of the thing.

View File

@ -163,6 +163,7 @@ in
services.nginx.virtualHosts."${codeForgeDomain}" = { services.nginx.virtualHosts."${codeForgeDomain}" = {
forceSSL = true; forceSSL = true;
enableACME = true; enableACME = true;
acmeRoot = null;
locations."/" = { locations."/" = {
proxyPass = "http://localhost:${toString config.services.gitea.settings.server.HTTP_PORT}"; proxyPass = "http://localhost:${toString config.services.gitea.settings.server.HTTP_PORT}";
}; };

View File

@ -78,6 +78,7 @@ in
"${authDomain}" = { "${authDomain}" = {
forceSSL = true; forceSSL = true;
enableACME = true; enableACME = true;
acmeRoot = null;
# This is based from the reverse proxy guide from the official # This is based from the reverse proxy guide from the official
# documentation at https://www.keycloak.org/server/reverseproxy. # documentation at https://www.keycloak.org/server/reverseproxy.

View File

@ -81,6 +81,7 @@ in
services.nginx.virtualHosts."${passwordManagerDomain}" = { services.nginx.virtualHosts."${passwordManagerDomain}" = {
forceSSL = true; forceSSL = true;
enableACME = true; enableACME = true;
acmeRoot = null;
locations = locations =
let let
address = config.services.vaultwarden.config.ROCKET_ADDRESS; address = config.services.vaultwarden.config.ROCKET_ADDRESS;

View File

@ -1,6 +1,6 @@
ssh-key: ENC[AES256_GCM,data:UgJB9WiLs1nt8e95sYeBr9XJRw16CldxBFYazppwHD0Tx0rkv9YDsqJMdrMFQJJ15UgOx61yQ2rg56KoaR4cJIqQM/7foKY3+LgdI4ePtfnbGRebIMyeqCiEVWq+a5ppwsG6B9w9liRqaOG7LpD90JpXcLKVG6Lo/YwTmwDbOBGJHhyJk2DindJ7qWly1gcys5Mm9GTZmtuz8lKG7hNVQar5lmuq1fhyOolnxlFKCLG3zfumttVnT3U1ELd3TzZIaWnNIL7SuhfZDBko3ZO4bbDj/JdX1uNKlEh2FeS7Mp/DvylFlVleoQOMI9FTes/tQHmztVaA7DllYP6gKHzvLsKX577fXeoZihrGvQiNj11qDXxcj3qhUx/8iXdyVzvy/UTGWW5/QeDGNDsrT7wlwuVmqVHb7s+9Ep6Oq9tFbDQHkRMRv/Nl3C/xxtH23RuShJ1IjxXTPu9t+AiD/qPvecXyD0iZ9OX1YJn5AM9WyPLisEFasaFbgfhF6uDS2l61oCS3LPwjdbXA8UyB7vUi,iv:1OGfGUojkL0/DS+HMbyAK0GeVKa6AuQkyRwO5txiD54=,tag:TmD3ljgWGv0SNPq8GxI/kw==,type:str] ssh-key: ENC[AES256_GCM,data:UgJB9WiLs1nt8e95sYeBr9XJRw16CldxBFYazppwHD0Tx0rkv9YDsqJMdrMFQJJ15UgOx61yQ2rg56KoaR4cJIqQM/7foKY3+LgdI4ePtfnbGRebIMyeqCiEVWq+a5ppwsG6B9w9liRqaOG7LpD90JpXcLKVG6Lo/YwTmwDbOBGJHhyJk2DindJ7qWly1gcys5Mm9GTZmtuz8lKG7hNVQar5lmuq1fhyOolnxlFKCLG3zfumttVnT3U1ELd3TzZIaWnNIL7SuhfZDBko3ZO4bbDj/JdX1uNKlEh2FeS7Mp/DvylFlVleoQOMI9FTes/tQHmztVaA7DllYP6gKHzvLsKX577fXeoZihrGvQiNj11qDXxcj3qhUx/8iXdyVzvy/UTGWW5/QeDGNDsrT7wlwuVmqVHb7s+9Ep6Oq9tFbDQHkRMRv/Nl3C/xxtH23RuShJ1IjxXTPu9t+AiD/qPvecXyD0iZ9OX1YJn5AM9WyPLisEFasaFbgfhF6uDS2l61oCS3LPwjdbXA8UyB7vUi,iv:1OGfGUojkL0/DS+HMbyAK0GeVKa6AuQkyRwO5txiD54=,tag:TmD3ljgWGv0SNPq8GxI/kw==,type:str]
lego: lego:
env: ENC[AES256_GCM,data:CAklP0yjTBABPZq/0SANoi+6tNTXrbX7dgY34V+l5w65osPFJkC3GwDk037NzQKr9LgizhuzXqd6FP1YcHv8GZa5c7hrXU32brqNlGsW/xBL2e2DjvILgmwcndi3Bk7opzoXASyRuv3J/bTkPMdEEie+G041ushO+bPcR6Vw2xL8TJKujZrBJJ+Pd8KJHOqck3/x2pFynYHTflwOb3SgHhIBY+/H72G0I8pKYK4A1vR7,iv:KIHu2dWaOY8crEC+2LQu5WNTcgFhSV1+mwhGe3ViblY=,tag:EHz9LV9iiGCdtHa/vXbCWA==,type:str] env: ENC[AES256_GCM,data:pJPaYAuFEj8f0Rm+Quhf4T2FKmvJ5cxGPAW7TCZkl++0yMaYx7e94WKYjLmWp+OWfUQss6byZ4WiARHY0XuF7w/S41isJdObSGgeUXnoLAu9oqt9JLsVOlQABtrY45ZF,iv:J6vBXY1gi12Zy6wXM1NyGZNxuVApKWy7eJUs8WapDoE=,tag:nEoAiY7Uy92/JjJDaSJZzw==,type:str]
sourcehut: sourcehut:
network-key: ENC[AES256_GCM,data:e28WJt1POxWnCgjYG+6HdSOwhHiIArGPrGb/3pQ5o2P2R4gIuxm8YxRPg4E=,iv:44VlT5ID8KXDquDOZMIEPBWl7r+JwbamRdqhBsFO4Rw=,tag:JRTs4FRT8bBpPyetDbt6zg==,type:str] network-key: ENC[AES256_GCM,data:e28WJt1POxWnCgjYG+6HdSOwhHiIArGPrGb/3pQ5o2P2R4gIuxm8YxRPg4E=,iv:44VlT5ID8KXDquDOZMIEPBWl7r+JwbamRdqhBsFO4Rw=,tag:JRTs4FRT8bBpPyetDbt6zg==,type:str]
service-key: ENC[AES256_GCM,data:glZuT+e9c2UOXieP313ny6Dl15HRXpeHtGr4XPWjhNSAvFgcwp/1AgFYrHDWZBf771MkN0pgVE/d/fx0oBOgSg==,iv:S4BzMYPZtVFhXV0g5qBxjItqCyEQ25Ct6swBut7FefQ=,tag:w3t59DqroYuAmgHlu/BhEQ==,type:str] service-key: ENC[AES256_GCM,data:glZuT+e9c2UOXieP313ny6Dl15HRXpeHtGr4XPWjhNSAvFgcwp/1AgFYrHDWZBf771MkN0pgVE/d/fx0oBOgSg==,iv:S4BzMYPZtVFhXV0g5qBxjItqCyEQ25Ct6swBut7FefQ=,tag:w3t59DqroYuAmgHlu/BhEQ==,type:str]
@ -55,8 +55,8 @@ sops:
ZCtNbnFqdzNkVlBtNjVCdE4yNHMrRjQKfFV4GaReO0UO81xsTB0EuN5ibVsafXJY ZCtNbnFqdzNkVlBtNjVCdE4yNHMrRjQKfFV4GaReO0UO81xsTB0EuN5ibVsafXJY
miBgZAZWbJjSBcM4X+Fym/DlxHRoB1a6iFEFN9yg+Z9WI8PfjKnbsA== miBgZAZWbJjSBcM4X+Fym/DlxHRoB1a6iFEFN9yg+Z9WI8PfjKnbsA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2023-04-29T14:57:00Z" lastmodified: "2023-06-22T08:57:24Z"
mac: ENC[AES256_GCM,data:Fkf+0g4FweOxhHgJbAvq4GBqYSr2K7U4uDN/9A5t/LN80oJGX2G/Xj0/Al2+rr0TOOgWJpDkQqVhoZNG27Hl0xzo95n/vc+jcp7y3oeCk+P02+dn3tiEPOnKmCGnAYC5xiuDpPKTIPStKQAX/p89MvL/rliQ4FhPV4P+BfkNgp8=,iv:xyWKf0PIk0BiGJj9w+1rurOZAJMOukMBQzgTSX5YGys=,tag:cej29myo5y69TRbrBIb/4Q==,type:str] mac: ENC[AES256_GCM,data:Ltx4nr5Llq3txLTcK1mO1/BoOKm6O0FaQd60FMPpFtpIUhFQhPaPrDmnAB7/j1rMMCc4fg9hv2AYAx/rCCoaMy2aQmgRnjsuX8S7UfwqOYqvCVl6CJz3HeCfficDe5P2Un0BeblK1SeSJ689VXO0kAa2z8/uB5tis5cULfAIkBs=,iv:HKEN2YLM83mu4JjNWdBQGI+RX03nssZPwIdaP9iMW1I=,tag:VMHrarG2H/NPuymojxntUQ==,type:str]
pgp: [] pgp: []
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.7.3 version: 3.7.3