mirror of
https://github.com/foo-dogsquared/nixos-config.git
synced 2025-01-31 04:58:01 +00:00
hosts/plover: replace dnsmasq with CoreDNS as DNS server
This commit is contained in:
parent
3787bf2e68
commit
f75c04eaa9
58
hosts/plover/config/coredns/foodogsquared.one.zone
Normal file
58
hosts/plover/config/coredns/foodogsquared.one.zone
Normal file
@ -0,0 +1,58 @@
|
||||
; This is trying to be discrete with certain information. This should be copied
|
||||
; and replaced with more confidential information somewhere.
|
||||
|
||||
; Take note we're not making the
|
||||
$TTL 2h
|
||||
$ORIGIN @domain@
|
||||
|
||||
@ IN SOA @dnsSubdomain@.@domain@ @email@ (
|
||||
2023020800 ; serial number
|
||||
3h ; refresh
|
||||
15m ; update retry
|
||||
3w ; expiry
|
||||
3h ; nx = nxdomain ttl
|
||||
)
|
||||
|
||||
; Setting up the mail-related DNS entries.
|
||||
; For future references, please the see the following document at
|
||||
; https://kb.mailbox.org/en/private/e-mail-article/using-e-mail-addresses-of-your-domain
|
||||
@ IN MX 10 mxext1.mailbox.org
|
||||
IN MX 10 mxext2.mailbox.org
|
||||
IN MX 20 mxext3.mailbox.org
|
||||
IN TXT v=spf1 include:mailbox.org ~all
|
||||
_dmarc IN TXT v=DMARC1;p=none;rua=mailto:postmaster@foodogsquared.one
|
||||
mbo0001._domainkey IN CNAME mbo0001._domainkey.mailbox.org.
|
||||
mbo0002._domainkey IN CNAME mbo0002._domainkey.mailbox.org.
|
||||
mbo0003._domainkey IN CNAME mbo0003._domainkey.mailbox.org.
|
||||
mbo0004._domainkey IN CNAME mbo0004._domainkey.mailbox.org.
|
||||
#mailboxSecurityKey# IN TXT #mailboxSecurityKeyRecord#
|
||||
|
||||
; My websites that are deployed by somewhere else.
|
||||
@ IN ALIAS apex-loadbalancer.netlify.com.
|
||||
www IN CNAME foodogsquared.netlify.app.
|
||||
wiki IN CNAME foodogsquared-wiki.netlify.app.
|
||||
|
||||
; Public-facing services from this server.
|
||||
auth IN A @publicIPv4@
|
||||
auth IN AAAA @publicIPv6@
|
||||
|
||||
pass IN A @publicIPv4@
|
||||
pass IN AAAA @publicIPv6@
|
||||
|
||||
code IN A @publicIPv4@
|
||||
code IN AAAA @publicIPv6@
|
||||
|
||||
; Other things.
|
||||
_github-pages-challenge-foo-dogsquared IN TXT 673febae1ea0095e76d1e02a7a1709
|
||||
|
||||
; Setting up SendGrid.
|
||||
; This is for rewriting tracking links to my domain.
|
||||
url2871 IN CNAME sendgrid.net
|
||||
30339354 IN CNAME sendgrid.net
|
||||
|
||||
; This is for SendGrid sender authentication.
|
||||
em1172 IN CNAME u30339354.wl105.sendgrid.net
|
||||
s1._domainkey IN CNAME s1.domainkey.u30339354.wl105.sendgrid.net
|
||||
s2._domainkey IN CNAME s2.domainkey.u30339354.wl105.sendgrid.net
|
||||
|
||||
; vim: expandtab! tabstop=8 shiftwidth=8 filetype=dns
|
@ -22,6 +22,9 @@ in
|
||||
# Hardened profile from nixpkgs.
|
||||
"${modulesPath}/profiles/hardened.nix"
|
||||
|
||||
# The primary DNS server that is completely hidden.
|
||||
./modules/services/coredns.nix
|
||||
|
||||
./modules/services/nginx.nix
|
||||
|
||||
# The database of choice which is used by most self-managed services on
|
||||
|
@ -50,15 +50,6 @@ in
|
||||
dhcpcd.enable = false;
|
||||
};
|
||||
|
||||
# The internal DNS server of choice.
|
||||
services.dnsmasq = {
|
||||
enable = true;
|
||||
settings = {
|
||||
listen-address = with interfaces.internal; [ IPv4.address IPv6.address ];
|
||||
port = 3908;
|
||||
};
|
||||
};
|
||||
|
||||
# The main DNS server (not exactly by choice).
|
||||
services.resolved = {
|
||||
enable = true;
|
||||
@ -103,6 +94,11 @@ in
|
||||
IPv4.gateway
|
||||
IPv6.gateway
|
||||
];
|
||||
|
||||
networkConfig.DNS = [
|
||||
"127.0.0.1"
|
||||
"::1"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -6,6 +6,16 @@ let
|
||||
in
|
||||
rec {
|
||||
privateIPv6Prefix = "fdee:b0de:5685";
|
||||
|
||||
clientNetworks = [
|
||||
"172.24.0.0/13"
|
||||
"10.128.0.0/9"
|
||||
];
|
||||
serverNetworks = [
|
||||
"172.16.0.0/13"
|
||||
"10.0.0.0/9"
|
||||
];
|
||||
|
||||
interfaces = let
|
||||
ploverInternalNetworkGateway = "172.16.0.1";
|
||||
widdeerLan = "10.0.0.1";
|
||||
@ -79,4 +89,19 @@ rec {
|
||||
IPv6 = "${wireguardIPv6Prefix}3";
|
||||
};
|
||||
};
|
||||
|
||||
secondaryNameServers = {
|
||||
"ns1.first-ns.de." = {
|
||||
IPv4 = [ "213.239.242.238" ];
|
||||
IPv6 = [ "2a01:4f8:0:a101::a:1" ];
|
||||
};
|
||||
"robotns2.second-ns.de." = {
|
||||
IPv4 = [ "213.133.105.6" ];
|
||||
IPv6 = [ "2a01:4f8:d0a:2004::2" ];
|
||||
};
|
||||
"robotns3.second-ns.com." = {
|
||||
IPv4 = [ "193.47.99.3" ];
|
||||
IPv6 = [ "2001:67c:192c::add:a3" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -30,9 +30,6 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
# Attaching the domain name to the DNS server.
|
||||
services.dnsmasq.settings.address = [ "/${atuinInternalDomain}/${host}" ];
|
||||
|
||||
# Putting it altogether in the reverse proxy of choice.
|
||||
services.nginx.virtualHosts."${atuinInternalDomain}" = {
|
||||
locations."/" = {
|
||||
|
189
hosts/plover/modules/services/coredns.nix
Normal file
189
hosts/plover/modules/services/coredns.nix
Normal file
@ -0,0 +1,189 @@
|
||||
{ config, options, lib, pkgs, ... }:
|
||||
|
||||
# Take note we're also running with systemd-resolved which shouldn't really
|
||||
# conflict much with established DNS servers default configuration considering
|
||||
# it lives in 127.0.0.53 (not 127.0.0.1). So if you found some errors, that's
|
||||
# on you. Either that or we can easily move the resolver somewhere else.
|
||||
let
|
||||
inherit (config.networking) domain fqdn;
|
||||
inherit (import ../hardware/networks.nix) interfaces clientNetworks serverNetworks secondaryNameServers;
|
||||
|
||||
dnsSubdomain = "ns1";
|
||||
dnsDomainName = "${dnsSubdomain}.${domain}";
|
||||
certs = config.security.acme.certs;
|
||||
dnsEmail = "hostmaster.${domain}";
|
||||
|
||||
# This is the part of the SOA record. You'll have to modify it here instead
|
||||
# of modifying a zone file since it does not play well with a dynamically
|
||||
# configured server it seems.
|
||||
dnsSerialNumber = "2023020800";
|
||||
dnsRefresh = "3h";
|
||||
dnsUpdateRetry = "15m";
|
||||
dnsExpiry = "3w";
|
||||
dnsNxTTL = "3h";
|
||||
|
||||
corednsServiceName = "coredns";
|
||||
|
||||
domainZoneFile = pkgs.substituteAll {
|
||||
src = ../../config/coredns/${domain}.zone;
|
||||
inherit domain dnsSubdomain;
|
||||
email = dnsEmail;
|
||||
publicIPv4 = interfaces.main'.IPv4.address;
|
||||
publicIPv6 = interfaces.main'.IPv6.address;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
# The final location of the thing.
|
||||
domainZoneFile' = "/etc/coredns/zones/${domain}.zone";
|
||||
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/mailbox-security-key" = { };
|
||||
"dns/mailbox-security-key-record" = { };
|
||||
};
|
||||
|
||||
# Generating a certificate for the DNS-over-TLS feature.
|
||||
security.acme.certs."${dnsDomainName}".postRun = ''
|
||||
systemctl restart ${corednsServiceName}.service
|
||||
'';
|
||||
|
||||
# Setting up the firewall to make less things to screw up in case anything is
|
||||
# screwed up.
|
||||
networking.firewall.extraInputRules = ''
|
||||
meta l4proto {tcp, udp} th dport 53 ip saddr { ${lib.concatStringsSep ", " secondaryNameServersIPv4} } accept comment "Accept DNS queries from secondary nameservers"
|
||||
meta l4proto {tcp, udp} th dport 53 ip6 saddr { ${lib.concatStringsSep ", " secondaryNameServersIPv6} } accept comment "Accept DNS queries from secondary nameservers"
|
||||
'';
|
||||
|
||||
# The main DNS server.
|
||||
services.coredns = {
|
||||
enable = true;
|
||||
|
||||
# NOTE: Currently, Hetzner DNS servers does not support DNSSEC. Will need
|
||||
# to visit the following document periodically to see if they support but
|
||||
# it is doubtful since they are doubting the benefits of supporting it. :(
|
||||
#
|
||||
# From what I can tell, it seems like DNSSEC is not much embraced by the
|
||||
# major organizations yet so I'll wait with them on this one.
|
||||
#
|
||||
# https://docs.hetzner.com/dns-console/dns/general/dnssec
|
||||
config = ''
|
||||
(common) {
|
||||
forward . /etc/resolv.conf
|
||||
log
|
||||
cache
|
||||
errors
|
||||
}
|
||||
|
||||
${fqdn} {
|
||||
import common
|
||||
|
||||
bind ${interfaces.internal.IPv4.address} ${interfaces.internal.IPv6.address}
|
||||
|
||||
local
|
||||
|
||||
acl {
|
||||
allow net ${lib.concatStringsSep " " (clientNetworks ++ serverNetworks)}
|
||||
block
|
||||
}
|
||||
|
||||
template ANY ANY {
|
||||
authority "{{ .Zone }} IN SOA {{ .Zone }} ${dnsEmail} (1 60 60 60 60)"
|
||||
fallthrough
|
||||
}
|
||||
|
||||
template IN A {
|
||||
answer "{{ .Zone }} IN 60 A ${interfaces.internal.IPv4.address}"
|
||||
answer "{{ .Zone }} IN 60 A ${interfaces.internal.IPv4.address}"
|
||||
}
|
||||
|
||||
template IN AAAA {
|
||||
answer "{{ .Zone }} IN 60 AAAA ${interfaces.internal.IPv6.address}"
|
||||
answer "{{ .Zone }} IN 60 AAAA ${interfaces.internal.IPv6.address}"
|
||||
}
|
||||
}
|
||||
|
||||
${domain} {
|
||||
import common
|
||||
|
||||
bind lo {
|
||||
# These are already taken from systemd-resolved.
|
||||
except 127.0.0.53 127.0.0.54
|
||||
}
|
||||
|
||||
acl {
|
||||
# We're setting this up as a "hidden" primary server.
|
||||
allow type AXFR net ${lib.concatStringsSep " " secondaryNameServersIPs}
|
||||
allow type IXFR net ${lib.concatStringsSep " " secondaryNameServersIPs}
|
||||
block type AXFR
|
||||
block type IXFR
|
||||
}
|
||||
|
||||
template IN NS {
|
||||
${lib.concatStringsSep "\n "
|
||||
(lib.lists.map
|
||||
(ns: ''answer "{{ .Zone }} IN NS ${ns}"'')
|
||||
secondaryNameserverDomains)}
|
||||
}
|
||||
|
||||
file ${domainZoneFile'}
|
||||
|
||||
transfer {
|
||||
to *
|
||||
}
|
||||
}
|
||||
|
||||
tls://${domain} {
|
||||
import common
|
||||
|
||||
tls {$CREDENTIALS_DIRECTORY}/cert.pem {$CREDENTIALS_DIRECTORY}/key.pem {$CREDENTIALS_DIRECTORY}/fullchain.pem
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
# This is based from the Gitea pre-start script.
|
||||
systemd.services.${corednsServiceName} = {
|
||||
requires = [ "acme-finished-${dnsDomainName}.target" ];
|
||||
preStart =
|
||||
let
|
||||
secretsPath = path: config.sops.secrets."plover/${path}".path;
|
||||
replaceSecretBin = "${lib.getBin pkgs.replace-secret}/bin/replace-secret";
|
||||
in
|
||||
lib.mkBefore ''
|
||||
install -Dm0644 ${domainZoneFile} ${domainZoneFile'}
|
||||
|
||||
${replaceSecretBin} '#mailboxSecurityKey#' '${secretsPath "dns/mailbox-security-key"}' '${domainZoneFile'}'
|
||||
${replaceSecretBin} '#mailboxSecurityKeyRecord#' '${secretsPath "dns/mailbox-security-key-record"}' '${domainZoneFile'}'
|
||||
'';
|
||||
serviceConfig.LoadCredential = let
|
||||
certDirectory = certs."${dnsDomainName}".directory;
|
||||
in
|
||||
[
|
||||
"cert.pem:${certDirectory}/cert.pem"
|
||||
"key.pem:${certDirectory}/key.pem"
|
||||
"fullchain.pem:${certDirectory}/fullchain.pem"
|
||||
];
|
||||
};
|
||||
}
|
@ -12,7 +12,7 @@ let
|
||||
keycloakDbName = if config.services.keycloak.database.createLocally then keycloakUser else config.services.keycloak.database.username;
|
||||
|
||||
certs = config.security.acme.certs;
|
||||
host = interfaces.internal.IPv4.address;
|
||||
host = "127.0.0.1";
|
||||
in
|
||||
{
|
||||
# Hey, the hub for your application sign-in.
|
||||
@ -69,9 +69,6 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
# Attach an domain name to the DNS server.
|
||||
services.dnsmasq.settings.address = [ "/${authInternalDomain}/${host}" ];
|
||||
|
||||
# Attaching it to the reverse proxy of choice.
|
||||
services.nginx.virtualHosts = {
|
||||
"${authDomain}" = {
|
||||
|
@ -58,11 +58,9 @@ in
|
||||
matchConfig.Name = wireguardIFName;
|
||||
|
||||
networkConfig = {
|
||||
DNS = with interfaces.internal; let
|
||||
internalDNSPort = config.services.dnsmasq.settings.port;
|
||||
in [
|
||||
"${IPv4.address}:${toString internalDNSPort}"
|
||||
"${IPv6.address}:${toString internalDNSPort}"
|
||||
DNS = with interfaces.internal; [
|
||||
"127.0.0.1"
|
||||
"::1"
|
||||
];
|
||||
Domains = lib.concatStringsSep " " internalDomains;
|
||||
DNSDefaultRoute = false;
|
||||
|
@ -36,6 +36,9 @@ wireguard:
|
||||
preshared-keys:
|
||||
ni: ENC[AES256_GCM,data:NAgNnVtPKCaaSagWCIet5pd5ZehymJPmhQShoO/ktqa1pl6MtzJsygbTktk=,iv:2/sOdNN6QX1Rou5xnq87t/m/kguPTthOXD8oXJfvM90=,tag:F/I2CYR9O1LAlLs/9LaXGg==,type:str]
|
||||
phone: ENC[AES256_GCM,data:3wIv8mE7eYhvSjwcE9fwsUZhh2Svmzg+RFjJzvjvMyB9V3uvBYG8vmB751w=,iv:iSm4dXNVqFa52eq0Hhct1MGSoq4x7FFzWdjXHlkGTW8=,tag:Lr463ee5r/ZhEC78uYyzfQ==,type:str]
|
||||
dns:
|
||||
mailbox-security-key: ENC[AES256_GCM,data:e1/y+JNNUxdf5D0OVhTD8hsoPlvV2Jpp3/+nHBktZH02/ZOfa9W5oA==,iv:tR9aVFHuMekr2uz4MaGAddlRsAh9XctS25EO+yMyvhE=,tag:BImSGpx4ltuU1qPTrmioKg==,type:str]
|
||||
mailbox-security-key-record: ENC[AES256_GCM,data:bP1kKQczfjOQyokOa+cScNs7jKLaXamUHYqzW7k0QRXnin5Nsj7G9w==,iv:l8NtJcYll8rdQJLsuxPIj3Ch3Tc/ESs1wUwPrGRTI7Y=,tag:RWD9mvinKW0xv6GDw/4jkQ==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
@ -51,8 +54,8 @@ sops:
|
||||
ZCtNbnFqdzNkVlBtNjVCdE4yNHMrRjQKfFV4GaReO0UO81xsTB0EuN5ibVsafXJY
|
||||
miBgZAZWbJjSBcM4X+Fym/DlxHRoB1a6iFEFN9yg+Z9WI8PfjKnbsA==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2023-01-17T09:10:51Z"
|
||||
mac: ENC[AES256_GCM,data:wzxOoyd+Zq6Fna1GxCZ6Uha6rdW3xVRx3uJniyuJ6TpGCpMoCzv9O0F7JgYyK7je2GR1RomynECEGu84re46yK9AkwV9KKWXVAs8jaI9QeZ6usEbFdr7KmyLFZbO/OMP72OIV03wxJ7Hguz2snF5ONjjhbAfZ2n+xXTofFJqBZY=,iv:cMZdVJQ4Vpf1FB70De3Rf/iMqp2Uv1QARp6897bew1A=,tag:rRx+ufoCVqqOGWhURxo6aQ==,type:str]
|
||||
lastmodified: "2023-02-08T09:58:04Z"
|
||||
mac: ENC[AES256_GCM,data:VJiZJclfId8pwfKNKyRWtMVX3e6yAjrQmEmQPbW/0nQCxfSe6ixapmoEheMEaF1WbJe0sOiKV8i3GZbxW+aLX9RN6+fOB/lKqSUigQOLgFjs9fgDG9WN4HCzeWPWm+vkfsL3+A5T3ucKHyqjEFJ91BpcA1x+fa5qNAnnaXCifJM=,iv:/oPeVaLbu+yWXF86b8Dc16JuuhCDlJKluK+GrQl0VMU=,tag:0ox7Qf8FdPtOY9GXkqAhkQ==,type:str]
|
||||
pgp: []
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.7.3
|
||||
|
Loading…
Reference in New Issue
Block a user