some dns fix + dnsmasq
This commit is contained in:
parent
7b3c103b5b
commit
b46c2a8355
5 changed files with 154 additions and 36 deletions
13
mapping.nix
13
mapping.nix
|
@ -26,17 +26,4 @@
|
||||||
./shared/dns.nix
|
./shared/dns.nix
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
# For instance:
|
|
||||||
# psql = rec {
|
|
||||||
# master = "some-node-1";
|
|
||||||
# slaves = [
|
|
||||||
# "some-node-2"
|
|
||||||
# "some-node-3"
|
|
||||||
# ];
|
|
||||||
# hosts = [ master ] ++ slaves;
|
|
||||||
# _inherit = [
|
|
||||||
# "./shared/psql.nix"
|
|
||||||
# ];
|
|
||||||
# };
|
|
||||||
}
|
}
|
|
@ -9,5 +9,6 @@
|
||||||
./commons/networking.nix
|
./commons/networking.nix
|
||||||
./commons/mesh.nix
|
./commons/mesh.nix
|
||||||
./commons/nftables.nix
|
./commons/nftables.nix
|
||||||
|
./commons/resolver.nix
|
||||||
];
|
];
|
||||||
}
|
}
|
|
@ -53,6 +53,18 @@ in
|
||||||
udp dport 51920 accept
|
udp dport 51920 accept
|
||||||
'' else ""}
|
'' else ""}
|
||||||
|
|
||||||
|
${if myName == mapping.dns.master then ''
|
||||||
|
# DNS Master
|
||||||
|
iifname mesh tcp dport 53 accept
|
||||||
|
iifname mesh udp dport 53 accept
|
||||||
|
'' else ""}
|
||||||
|
|
||||||
|
${if lib.elem myName mapping.dns.secondary then ''
|
||||||
|
# DNS Secondary
|
||||||
|
tcp dport 53 accept
|
||||||
|
udp dport 53 accept
|
||||||
|
'' else ""}
|
||||||
|
|
||||||
# Log anything else
|
# Log anything else
|
||||||
ip protocol tcp counter log prefix "tcp.in.dropped: "
|
ip protocol tcp counter log prefix "tcp.in.dropped: "
|
||||||
ip protocol udp counter log prefix "udp.in.dropped: "
|
ip protocol udp counter log prefix "udp.in.dropped: "
|
||||||
|
@ -65,11 +77,8 @@ in
|
||||||
ct state invalid counter drop
|
ct state invalid counter drop
|
||||||
|
|
||||||
${if lib.elem myName mapping.bastion.hosts then ''
|
${if lib.elem myName mapping.bastion.hosts then ''
|
||||||
iifname mgmt oifname mesh* accept
|
iifname mgmt oifname mesh accept
|
||||||
'' else ""}
|
'' else ""}
|
||||||
|
|
||||||
# Allow mesh bounces
|
|
||||||
iifname mesh* oifname mesh* accept
|
|
||||||
}
|
}
|
||||||
chain output {
|
chain output {
|
||||||
type filter hook output priority 0; policy accept;
|
type filter hook output priority 0; policy accept;
|
||||||
|
|
53
shared/commons/resolver.nix
Normal file
53
shared/commons/resolver.nix
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
{ ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
# Import nodes
|
||||||
|
nodes = import ./../../nodes.nix;
|
||||||
|
myName = config.hostName;
|
||||||
|
myPeer = nodes."${myName}";
|
||||||
|
myId = myPeer.id;
|
||||||
|
myZone = myPeer.zone;
|
||||||
|
|
||||||
|
# Import mapping
|
||||||
|
mapping = import ./../../mapping.nix;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
services.resolved.enable = false;
|
||||||
|
networking.resolvconf.enable = false;
|
||||||
|
|
||||||
|
networking.domain = "lf";
|
||||||
|
|
||||||
|
environment.etc."resolv.conf".text = ''
|
||||||
|
# Do not edit, will be overwritten by Nixos
|
||||||
|
domain ${config.networking.domain}
|
||||||
|
search ${config.networking.domain}
|
||||||
|
${builtins.concatStringsSep "\n" (map (ip: "nameserver ${ip}") config.services.dnsmasq.settings.listen-address)}
|
||||||
|
options edns0 trust-ad
|
||||||
|
'';
|
||||||
|
|
||||||
|
services.dnsmasq = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
listen-address = [
|
||||||
|
"::1"
|
||||||
|
"127.0.0.1"
|
||||||
|
];
|
||||||
|
local = [
|
||||||
|
"/${config.networking.domain}/"
|
||||||
|
];
|
||||||
|
server = [
|
||||||
|
"1.1.1.1"
|
||||||
|
"8.8.8.8"
|
||||||
|
"9.9.9.9"
|
||||||
|
] ++ map (hostName: "/lf/172.19.${nodes.${hostName}.zone}.${nodes.${hostName}.id}") mapping.dns.hosts
|
||||||
|
++ map (hostName: "/lf/fc00::${nodes.${hostName}.zone}:${nodes.${hostName}.id}") mapping.dns.hosts;
|
||||||
|
no-resolv = true;
|
||||||
|
# Resolvconf can auto-generated /etc/dnsmasq-{conf,resolv}.conf
|
||||||
|
# By default dnsmasq import them
|
||||||
|
# We've disable resolvconf, but just to be on the safe side
|
||||||
|
resolv-file = false;
|
||||||
|
conf-file = false;
|
||||||
|
log-queries = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -3,7 +3,8 @@
|
||||||
let
|
let
|
||||||
# Import nodes
|
# Import nodes
|
||||||
nodes = import ./../../nodes.nix;
|
nodes = import ./../../nodes.nix;
|
||||||
myNode = nodes."${config.hostName}";
|
myName = config.hostName;
|
||||||
|
myNode = nodes."${myName}";
|
||||||
|
|
||||||
# And mapping
|
# And mapping
|
||||||
mapping = import ./../../mapping.nix;
|
mapping = import ./../../mapping.nix;
|
||||||
|
@ -24,13 +25,12 @@ let
|
||||||
segments = ((lib.stringLength domainkey) / 255);
|
segments = ((lib.stringLength domainkey) / 255);
|
||||||
domainkeySplitted = map (x: lib.substring (x*255) 255 domainkey) (lib.range 0 segments);
|
domainkeySplitted = map (x: lib.substring (x*255) 255 domainkey) (lib.range 0 segments);
|
||||||
|
|
||||||
|
|
||||||
#####
|
#####
|
||||||
## Knot specific
|
## Knot specific
|
||||||
#####
|
#####
|
||||||
|
|
||||||
# Define remote based on current role
|
# Define remote based on current role
|
||||||
remotes = if myNode == mapping.dns.master then
|
remotes = if myName == mapping.dns.master then
|
||||||
map (hostname: {
|
map (hostname: {
|
||||||
id = hostname;
|
id = hostname;
|
||||||
address = "172.19.${toString nodes.${hostname}.zone}.${toString nodes.${hostname}.id}@53";
|
address = "172.19.${toString nodes.${hostname}.zone}.${toString nodes.${hostname}.id}@53";
|
||||||
|
@ -44,23 +44,23 @@ let
|
||||||
remotesNames = map (remote: remote.id) remotes;
|
remotesNames = map (remote: remote.id) remotes;
|
||||||
|
|
||||||
# Remotes ACL
|
# Remotes ACL
|
||||||
remotesACL = if myNode == mapping.dns.master then
|
remotesACL = if myName == mapping.dns.master then
|
||||||
map (hostname: {
|
map (hostname: {
|
||||||
id = "acl_${hostname}";
|
id = "acl_${hostname}";
|
||||||
address = "172.19.${toString nodes.${hostname}.zone}.${toString nodes.${hostname}.id}@53";
|
address = "172.19.${toString nodes.${hostname}.zone}.${toString nodes.${hostname}.id}";
|
||||||
action = "transfer";
|
action = "transfer";
|
||||||
}) mapping.dns.secondary
|
}) mapping.dns.secondary
|
||||||
else
|
else
|
||||||
[{
|
[{
|
||||||
id = "acl_${mapping.dns.master}";
|
id = "acl_${mapping.dns.master}";
|
||||||
address = "172.19.${toString nodes.${mapping.dns.master}.zone}.${toString nodes.${mapping.dns.master}.id}@53";
|
address = "172.19.${toString nodes.${mapping.dns.master}.zone}.${toString nodes.${mapping.dns.master}.id}";
|
||||||
action = "notify";
|
action = "notify";
|
||||||
}];
|
}];
|
||||||
|
|
||||||
remotesACLNames = map (remote: remote.id) remotesACL;
|
remotesACLNames = map (remote: remote.id) remotesACL;
|
||||||
|
|
||||||
# Other ACL
|
# Other ACL
|
||||||
letsencryptACL = if myNode == mapping.dns.master then
|
letsencryptACL = if myName == mapping.dns.master then
|
||||||
[{
|
[{
|
||||||
id = "acl_le_challenge";
|
id = "acl_le_challenge";
|
||||||
address = [
|
address = [
|
||||||
|
@ -73,35 +73,64 @@ let
|
||||||
}]
|
}]
|
||||||
else [];
|
else [];
|
||||||
|
|
||||||
|
acls = remotesACL ++ letsencryptACL;
|
||||||
|
|
||||||
|
# Mod-query ACLs
|
||||||
|
modQueryACLs = [{
|
||||||
|
id = "local";
|
||||||
|
address = [
|
||||||
|
"172.19.0.0/16"
|
||||||
|
"fc00::/96"
|
||||||
|
];
|
||||||
|
}];
|
||||||
|
|
||||||
#####
|
#####
|
||||||
## Zone specific
|
## Zone specific
|
||||||
#####
|
#####
|
||||||
|
|
||||||
# host to dn
|
# host to dn
|
||||||
hostToDomain = hostname: builtins.replaceStrings ["-"] ["."] hostname;
|
hostToDomain = hostname: builtins.replaceStrings ["-"] ["."] hostname;
|
||||||
|
hostToLfDomain = hostname: builtins.replaceStrings [".lasuite.federez"] [".lf."] (hostToDomain hostname);
|
||||||
|
|
||||||
|
# Remove cidr notation
|
||||||
|
rmCidr = ip: builtins.head (builtins.split "/" ip);
|
||||||
|
|
||||||
# Gen NS
|
# Gen NS
|
||||||
toNSRecord = host: "IN NS ${hostToDomain host}.net.";
|
toNSRecord = host: "\tIN NS ${hostToDomain host}.net.";
|
||||||
nsRecords = map toNSRecord mapping.dns.secondary;
|
nsRecords = map toNSRecord mapping.dns.secondary;
|
||||||
|
|
||||||
dnsSecondaryConfigs = lib.filterAttrs (peerName: _peerConfig: lib.elem peerName mapping.dns.secondary) nodes;
|
dnsSecondaryConfigs = lib.filterAttrs (peerName: _peerConfig: lib.elem peerName mapping.dns.secondary) nodes;
|
||||||
|
|
||||||
# Gen A NS
|
# Gen A NS
|
||||||
nsARecords = lib.flatten (lib.mapAttrsToList (hostname: node:
|
nsARecords = lib.flatten (lib.mapAttrsToList (hostname: node:
|
||||||
lib.optional (supportsIPv4 node) "${hostToDomain hostname}.net. IN A ${node.ip4}"
|
lib.optional (supportsIPv4 node) "${hostToDomain hostname}.net. IN A ${rmCidr node.ip4}"
|
||||||
) dnsSecondaryConfigs);
|
) dnsSecondaryConfigs);
|
||||||
|
|
||||||
# Gen AAAA NS
|
# Gen AAAA NS
|
||||||
nsAAAARecords = lib.flatten (lib.mapAttrsToList (hostname: node:
|
nsAAAARecords = lib.flatten (lib.mapAttrsToList (hostname: node:
|
||||||
lib.optional (supportsIPv6 node) "${hostToDomain hostname}.net. IN AAAA ${node.ip6}"
|
lib.optional (supportsIPv6 node) "${hostToDomain hostname}.net. IN AAAA ${rmCidr node.ip6}"
|
||||||
) dnsSecondaryConfigs);
|
) dnsSecondaryConfigs);
|
||||||
|
|
||||||
|
# Gen A records for lf zone
|
||||||
|
lfARecords = lib.flatten (lib.mapAttrsToList (hostname: node:
|
||||||
|
lib.optional (supportsIPv4 node) "${hostToLfDomain hostname} IN A 172.19.${toString node.zone}.${toString node.id}"
|
||||||
|
) nodes);
|
||||||
|
|
||||||
|
# Gen AAAA records for lf zone
|
||||||
|
lfAAAARecords = lib.flatten (lib.mapAttrsToList (hostname: node:
|
||||||
|
lib.optional (supportsIPv6 node) "${hostToLfDomain hostname} IN AAAA fc00::${toString node.zone}:${toString node.id}"
|
||||||
|
) nodes);
|
||||||
|
|
||||||
|
# Gen first NS for SOA
|
||||||
|
firstNS = builtins.head mapping.dns.secondary;
|
||||||
|
firstNSDn = "${hostToDomain firstNS}.net.";
|
||||||
|
|
||||||
# Zone conf
|
# Zone conf
|
||||||
zoneFilePath = "/var/lib/knot/zones/zone-lasuite-federez-net";
|
zoneLasuiteFederezNetFilePath = "/var/lib/knot/zones/zone-lasuite-federez-net";
|
||||||
zone-lasuite-federez-net = pkgs.writeText "zone-lasuite-federez-net" ''
|
zone-lasuite-federez-net = pkgs.writeText "zone-lasuite-federez-net" ''
|
||||||
$ORIGIN lasuite.federez.net.
|
$ORIGIN lasuite.federez.net.
|
||||||
$TTL 60
|
$TTL 60
|
||||||
@ IN SOA ${builtins.head nsRecords}. monitoring.lasuite.federez.net. (
|
@ IN SOA ${firstNSDn} monitoring.lasuite.federez.net. (
|
||||||
${timestamp} ; serial
|
${timestamp} ; serial
|
||||||
60 ; refresh
|
60 ; refresh
|
||||||
60 ; retry
|
60 ; retry
|
||||||
|
@ -110,7 +139,7 @@ let
|
||||||
|
|
||||||
IN TXT "v=spf1 a:lasuite.federez.net ~all"
|
IN TXT "v=spf1 a:lasuite.federez.net ~all"
|
||||||
|
|
||||||
${builtins.concatStringsSep "\n" nsRecords}
|
${builtins.concatStringsSep "\n" nsRecords}
|
||||||
|
|
||||||
${builtins.concatStringsSep "\n" nsARecords}
|
${builtins.concatStringsSep "\n" nsARecords}
|
||||||
${builtins.concatStringsSep "\n" nsAAAARecords}
|
${builtins.concatStringsSep "\n" nsAAAARecords}
|
||||||
|
@ -119,7 +148,21 @@ let
|
||||||
_mta-sts IN TXT "v=STSv1; id=1"
|
_mta-sts IN TXT "v=STSv1; id=1"
|
||||||
_smtp._tls IN TXT "v=TLSRPTv1;rua=mailto:postmaster@lasuite.federez.net"
|
_smtp._tls IN TXT "v=TLSRPTv1;rua=mailto:postmaster@lasuite.federez.net"
|
||||||
default._domainkey IN TXT "${lib.concatStringsSep "\" \"" domainkeySplitted}"
|
default._domainkey IN TXT "${lib.concatStringsSep "\" \"" domainkeySplitted}"
|
||||||
cause-toujours IN TXT "v=spf1 a:lasuite.federez.net ~all"
|
'';
|
||||||
|
|
||||||
|
zoneLfFilePath = "/var/lib/knot/zones/zone-lf";
|
||||||
|
zone-lf = pkgs.writeText "zone-lf" ''
|
||||||
|
$ORIGIN lf.
|
||||||
|
$TTL 60
|
||||||
|
@ IN SOA dns.lf. monitoring.lasuite.federez.net. (
|
||||||
|
${timestamp} ; serial
|
||||||
|
60 ; refresh
|
||||||
|
60 ; retry
|
||||||
|
60 ; expire
|
||||||
|
60 ) ; minimum TTL
|
||||||
|
|
||||||
|
${builtins.concatStringsSep "\n" lfARecords}
|
||||||
|
${builtins.concatStringsSep "\n" lfAAAARecords}
|
||||||
'';
|
'';
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
@ -170,23 +213,40 @@ in
|
||||||
|
|
||||||
remote = remotes;
|
remote = remotes;
|
||||||
|
|
||||||
acl = remotesACL ++ otherACL;
|
acl = acls;
|
||||||
|
mod-queryacl = modQueryACLs;
|
||||||
|
|
||||||
zone = if myNode == mapping.dns.master then [
|
zone = if myName == mapping.dns.master then [
|
||||||
{
|
{
|
||||||
domain = "lasuite.federez.net";
|
domain = "lasuite.federez.net";
|
||||||
file = zoneFilePath;
|
file = zoneLasuiteFederezNetFilePath;
|
||||||
|
dnssec-signing = "on";
|
||||||
|
dnssec-policy = "default";
|
||||||
|
zonefile-load = "difference";
|
||||||
notify = remotesNames;
|
notify = remotesNames;
|
||||||
acl = remotesACLNames ++ [
|
acl = remotesACLNames ++ [
|
||||||
"acl_le_challenge"
|
"acl_le_challenge"
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
domain = "lf";
|
||||||
|
file = zoneLfFilePath;
|
||||||
|
notify = remotesNames;
|
||||||
|
acl = remotesACLNames;
|
||||||
|
module = "mod-queryacl/local";
|
||||||
|
}
|
||||||
] else [
|
] else [
|
||||||
{
|
{
|
||||||
domain = "lasuite.federez.net";
|
domain = "lasuite.federez.net";
|
||||||
master = builtins.head remotesNames;
|
master = builtins.head remotesNames;
|
||||||
acl = remotesACLNames;
|
acl = remotesACLNames;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
domain = "lf";
|
||||||
|
master = builtins.head remotesNames;
|
||||||
|
acl = remotesACLNames;
|
||||||
|
module = "mod-queryacl/local";
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
log = [
|
log = [
|
||||||
|
@ -199,11 +259,19 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
# Write the generated zone file to the writable path
|
# Write the generated zone file to the writable path
|
||||||
systemd.services.writeZoneFile = {
|
systemd.services.writeLasuiteFederezNetZoneFile = {
|
||||||
before = [ "knot.service" ];
|
before = [ "knot.service" ];
|
||||||
description = "Write initial zone file for lasuite.federez.net";
|
description = "Write initial zone file for lasuite.federez.net";
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = "${pkgs.coreutils}/bin/cp '${zone-lasuite-federez-net}' ${zoneFilePath}";
|
ExecStart = "${pkgs.coreutils}/bin/cp '${zone-lasuite-federez-net}' ${zoneLasuiteFederezNetFilePath}";
|
||||||
|
};
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
};
|
||||||
|
systemd.services.writeLfZoneFile = {
|
||||||
|
before = [ "knot.service" ];
|
||||||
|
description = "Write initial zone file for lasuite.federez";
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${pkgs.coreutils}/bin/cp '${zone-lf}' ${zoneLfFilePath}";
|
||||||
};
|
};
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue