From fd267085bcb5e7401a1e66271b3c5f66b000670e Mon Sep 17 00:00:00 2001 From: Astro Date: Thu, 6 May 2021 03:21:58 +0200 Subject: [PATCH] nixos-module/container/{dns, dhcp-server}: implement internal ipv4 dyndns --- nix/lib/config/legacy.nix | 12 ++ nix/nixos-module/container/dhcp-server.nix | 28 ++++- nix/nixos-module/container/dns.nix | 124 ++++++++++++++------- salt-pillar/dhcp/init.sls | 84 +++++++------- salt-pillar/hosts/init.sls | 6 - 5 files changed, 166 insertions(+), 88 deletions(-) diff --git a/nix/lib/config/legacy.nix b/nix/lib/config/legacy.nix index 3c1f3ef..1237b41 100644 --- a/nix/lib/config/legacy.nix +++ b/nix/lib/config/legacy.nix @@ -46,6 +46,17 @@ in domainName = dhcpData.string-opts.domain-name; }) pillar.dhcp) { core.ospf.secret = pillar.ospf.secret; } + + # net priv* settings + ( + builtins.mapAttrs (netName: _: { + dynamicDomain = true; + }) ( + lib.filterAttrs (netName: _: + builtins.match "priv[[:digit:]]+" netName != null + ) pillar.hosts-inet + ) + ) ] ++ ( map (ctx: builtins.mapAttrs (_: subnet: { subnets6.${ctx} = subnet; }) pillar.subnets-inet6.${ctx} @@ -99,6 +110,7 @@ in c3d2-anon.ospf.allowedUpstreams = [ "anon1" "freifunk" ]; } + # host priv*-gw settings ( builtins.mapAttrs (hostName: _: { ospf.allowedUpstreams = [ "upstream2" "upstream1" "freifunk" ]; diff --git a/nix/nixos-module/container/dhcp-server.nix b/nix/nixos-module/container/dhcp-server.nix index 88d1b24..f70a16f 100644 --- a/nix/nixos-module/container/dhcp-server.nix +++ b/nix/nixos-module/container/dhcp-server.nix @@ -1,5 +1,5 @@ # ISC DHCP/IPv4 server configuration -{ hostName, config, lib, ... }: +{ hostName, inputs, config, lib, ... }: let dhcpNets = @@ -21,17 +21,43 @@ in builtins.attrValues ( builtins.mapAttrs (net: { dhcp, subnet4Net, subnet4Len, domainName, ...}: '' + ddns-update-style standard; + key dyndns { + algorithm hmac-sha256; + secret ${inputs.zentralwerk-network-key.lib.dyndnsKey}; + }; + zone ${domainName}. { + primary ${config.site.net.serv.hosts4.dns}; + primary6 ${config.site.net.serv.hosts6.dn42.dns}; + key dyndns; + } + ${lib.concatMapStrings ({ name, dynamic, ... }: + lib.optionalString ( + dynamic && + lib.hasSuffix ".in-addr.arpa" name + ) '' + zone ${name}. { + primary ${config.site.net.serv.hosts4.dns}; + primary6 ${config.site.net.serv.hosts6.dn42.dns}; + key dyndns; + } + '' + ) config.site.dns.localZones} + group { default-lease-time ${toString dhcp.time}; max-lease-time ${toString dhcp.max-time}; option routers ${config.site.net.${net}.hosts4.${builtins.replaceStrings [".${net}"] [""] dhcp.router}}; option domain-name "${domainName}"; option domain-name-servers 172.20.73.8, 9.9.9.9; + ddns-domainname "${domainName}"; subnet ${subnet4Net} netmask ${lib.netmasks.${toString subnet4Len}} { range ${dhcp.start} ${dhcp.end}; } + update-static-leases on; + ${builtins.concatStringsSep "\n" ( builtins.attrValues ( builtins.mapAttrs (addr: hwaddr: diff --git a/nix/nixos-module/container/dns.nix b/nix/nixos-module/container/dns.nix index 515627c..b5ac1a5 100644 --- a/nix/nixos-module/container/dns.nix +++ b/nix/nixos-module/container/dns.nix @@ -1,9 +1,45 @@ -{ hostName, config, lib, pkgs, self, ... }: +{ hostName, config, lib, pkgs, self, inputs, ... }: let fqdn = "${hostName}.serv.zentralwerk.org"; # public servers (slaves) publicNS = [ "ns.c3d2.de" "ns.spaceboyz.net" ]; + dynamicReverseZones = [ + "74.20.172.in-addr.arpa" + "75.20.172.in-addr.arpa" + "76.20.172.in-addr.arpa" + "77.20.172.in-addr.arpa" + "78.20.172.in-addr.arpa" + "79.20.172.in-addr.arpa" + ]; + + serial = + let + timestamp = toString self.lastModified; + datePkg = pkgs.runCommandLocal "date-${timestamp}" {} '' + date -d @${timestamp} +%Y%m%d%H > $out + ''; + in + toString (import datePkg); + + generateZoneFile = { name, ns, records, dynamic }: + builtins.toFile "${name}.zone" '' + $ORIGIN ${name}. + $TTL 1h + + @ IN SOA ${fqdn}. astro.spaceboyz.net. ( + ${serial} ; serial + 1h ; refresh + 1m ; retry + 2h ; expire + 1m ; minimum + ) + ${lib.concatMapStrings (ns: " IN NS ${ns}.\n") ns} + + ${lib.concatMapStrings ({ name, type, data }: + "${name} IN ${type} ${data}\n" + ) records} + ''; in { options = @@ -35,6 +71,10 @@ in options = recordOpts; }); }; + dynamic = mkOption { + type = types.bool; + default = false; + }; }; in { @@ -69,9 +109,9 @@ in ); # generate zones only for nets with hosts - namedNets = lib.filterAttrs (_: { hosts4, hosts6, dynamicDomain, ... }: + namedNets = lib.filterAttrs (name: { hosts4, hosts6, dynamicDomain, ... }: (hosts4 != [] && hosts6 != []) || - dynamicDomain + dynamicDomain ) config.site.net; # converts an IPv4 address to its reverse DNS form @@ -200,15 +240,14 @@ in } ] ++ builtins.concatLists ( builtins.attrValues ( builtins.mapAttrs (net: { dynamicDomain, hosts4, hosts6, ... }: [ - (if dynamicDomain - then throw "TODO" - else { - name = "${net}.zentralwerk.dn42"; - ns = [ fqdn ]; - records = - hosts4Records hosts4 ++ - lib.optionals (hosts6 ? dn42) (hosts6Records hosts6.dn42); - }) + { + name = "${net}.zentralwerk.dn42"; + ns = [ fqdn ]; + records = + hosts4Records hosts4 ++ + lib.optionals (hosts6 ? dn42) (hosts6Records hosts6.dn42); + dynamic = dynamicDomain; + } { name = "${net}.zentralwerk.org"; ns = publicNS; @@ -232,6 +271,7 @@ in builtins.filter (lib.hasSuffix ".${zone}") (builtins.attrNames reverseHosts4) ); + dynamic = builtins.elem zone dynamicReverseZones; }) reverseZones4 ++ builtins.concatMap (ctx: map (zone: { @@ -256,16 +296,7 @@ in services.bind = lib.mkIf config.site.hosts.${hostName}.services.dns.enable ( let - serial = - let - timestamp = toString self.lastModified; - datePkg = pkgs.runCommandLocal "date-${timestamp}" {} '' - date -d @${timestamp} +%Y%m%d%H > $out - ''; - in - toString (import datePkg); - - generateZone = { name, ns, records }: { + generateZone = zone@{ name, dynamic, ... }: { inherit name; master = true; # allowed for zone-transfer @@ -275,29 +306,44 @@ in # ns.spaceboyz.net "172.22.24.4" "2a01:4f9:4b:39ec::4" ]; - file = builtins.toFile "${name}.zone" '' - $ORIGIN ${name}. - $TTL 1h - - @ IN SOA ${fqdn}. astro.spaceboyz.net. ( - ${serial} ; serial - 1h ; refresh - 1m ; retry - 2h ; expire - 1m ; minimum - ) - ${lib.concatMapStrings (ns: " IN NS ${ns}.\n") ns} - - ${lib.concatMapStrings ({ name, type, data }: - "${name} IN ${type} ${data}\n" - ) records} + file = + if dynamic + then "/var/db/bind/${name}.zone" + else generateZoneFile zone; + extraConfig = lib.optionalString dynamic '' + allow-update { key "dyndns"; }; ''; }; + in { enable = true; zones = map generateZone config.site.dns.localZones; + + extraConfig = '' + key "dyndns" { + algorithm hmac-sha256; + secret "${inputs.zentralwerk-network-key.lib.dyndnsKey}"; + }; + ''; }); - # TODO: dyn + systemd.services.dynamic-zones = { + requiredBy = [ "bind.service" ]; + before = [ "bind.service" ]; + serviceConfig.Type = "oneshot"; + # TODO: initial records + script = '' + mkdir -p /var/db/bind + + ${lib.concatMapStringsSep "\n" (zone@{ name, ... }: '' + [ -e /var/db/bind/${name}.zone ] || \ + cp ${generateZoneFile zone} /var/db/bind/${name}.zone + chown -R named /var/db/bind + chmod -R u+rwX /var/db/bind + '') ( + builtins.filter ({ dynamic, ... }: dynamic) config.site.dns.localZones + )} + ''; + }; }; } diff --git a/salt-pillar/dhcp/init.sls b/salt-pillar/dhcp/init.sls index 3f7feb1..a814559 100644 --- a/salt-pillar/dhcp/init.sls +++ b/salt-pillar/dhcp/init.sls @@ -9,7 +9,7 @@ dhcp: host-opts: routers: serv-gw.serv string-opts: - domain-name: serv.zentralwerk.org + domain-name: serv.zentralwerk.dn42 pub: start: 172.20.78.2 @@ -22,7 +22,7 @@ dhcp: host-opts: routers: pub-gw.pub string-opts: - domain-name: pub.zentralwerk.org + domain-name: pub.zentralwerk.dn42 priv1: start: 172.20.74.2 @@ -34,7 +34,7 @@ dhcp: host-opts: routers: priv1-gw.priv1 string-opts: - domain-name: priv1.zentralwerk.org + domain-name: priv1.zentralwerk.dn42 priv2: start: 172.20.75.2 @@ -46,7 +46,7 @@ dhcp: host-opts: routers: priv2-gw.priv2 string-opts: - domain-name: priv2.zentralwerk.org + domain-name: priv2.zentralwerk.dn42 fixed-hosts: 172.20.75.7: 60:33:4b:0b:cd:fc 172.20.75.9: 00:11:32:22:95:79 @@ -61,7 +61,7 @@ dhcp: host-opts: routers: priv3-gw.priv3 string-opts: - domain-name: priv3.zentralwerk.org + domain-name: priv3.zentralwerk.dn42 priv4: start: 172.20.75.130 @@ -73,7 +73,7 @@ dhcp: host-opts: routers: priv4-gw.priv4 string-opts: - domain-name: priv4.zentralwerk.org + domain-name: priv4.zentralwerk.dn42 priv5: start: 172.20.74.66 @@ -85,7 +85,7 @@ dhcp: host-opts: routers: priv5-gw.priv5 string-opts: - domain-name: priv5.zentralwerk.org + domain-name: priv5.zentralwerk.dn42 priv6: start: 172.20.74.194 @@ -97,7 +97,7 @@ dhcp: host-opts: routers: priv6-gw.priv6 string-opts: - domain-name: priv6.zentralwerk.org + domain-name: priv6.zentralwerk.dn42 priv7: start: 172.20.75.66 @@ -109,7 +109,7 @@ dhcp: host-opts: routers: priv7-gw.priv7 string-opts: - domain-name: priv7.zentralwerk.org + domain-name: priv7.zentralwerk.dn42 priv8: start: 172.20.75.194 @@ -121,7 +121,7 @@ dhcp: host-opts: routers: priv8-gw.priv8 string-opts: - domain-name: priv8.zentralwerk.org + domain-name: priv8.zentralwerk.dn42 priv9: start: 172.20.74.34 @@ -133,7 +133,7 @@ dhcp: host-opts: routers: priv9-gw.priv9 string-opts: - domain-name: priv9.zentralwerk.org + domain-name: priv9.zentralwerk.dn42 priv10: start: 172.20.74.98 @@ -145,7 +145,7 @@ dhcp: host-opts: routers: priv10-gw.priv10 string-opts: - domain-name: priv10.zentralwerk.org + domain-name: priv10.zentralwerk.dn42 priv11: start: 172.20.74.162 @@ -157,7 +157,7 @@ dhcp: host-opts: routers: priv11-gw.priv11 string-opts: - domain-name: priv11.zentralwerk.org + domain-name: priv11.zentralwerk.dn42 priv12: start: 172.20.74.226 @@ -169,7 +169,7 @@ dhcp: host-opts: routers: priv12-gw.priv12 string-opts: - domain-name: priv12.zentralwerk.org + domain-name: priv12.zentralwerk.dn42 priv13: start: 172.20.75.34 @@ -181,7 +181,7 @@ dhcp: host-opts: routers: priv13-gw.priv13 string-opts: - domain-name: priv13.zentralwerk.org + domain-name: priv13.zentralwerk.dn42 priv14: start: 172.20.75.98 @@ -193,7 +193,7 @@ dhcp: host-opts: routers: priv14-gw.priv14 string-opts: - domain-name: priv14.zentralwerk.org + domain-name: priv14.zentralwerk.dn42 priv15: start: 172.20.75.162 @@ -205,7 +205,7 @@ dhcp: host-opts: routers: priv15-gw.priv15 string-opts: - domain-name: priv15.zentralwerk.org + domain-name: priv15.zentralwerk.dn42 priv16: start: 172.20.75.226 @@ -217,7 +217,7 @@ dhcp: host-opts: routers: priv16-gw.priv16 string-opts: - domain-name: priv16.zentralwerk.org + domain-name: priv16.zentralwerk.dn42 priv17: start: 172.20.73.130 @@ -229,7 +229,7 @@ dhcp: host-opts: routers: priv17-gw.priv17 string-opts: - domain-name: priv17.zentralwerk.org + domain-name: priv17.zentralwerk.dn42 priv18: start: 172.20.74.50 @@ -241,7 +241,7 @@ dhcp: host-opts: routers: priv18-gw.priv18 string-opts: - domain-name: priv18.zentralwerk.org + domain-name: priv18.zentralwerk.dn42 priv19: start: 172.20.73.194 @@ -254,7 +254,7 @@ dhcp: host-opts: routers: priv19-gw.priv19 string-opts: - domain-name: priv19.zentralwerk.org + domain-name: priv19.zentralwerk.dn42 priv20: start: 172.20.74.114 @@ -266,7 +266,7 @@ dhcp: host-opts: routers: priv20-gw.priv20 string-opts: - domain-name: priv20.zentralwerk.org + domain-name: priv20.zentralwerk.dn42 priv21: start: 172.20.74.146 @@ -278,7 +278,7 @@ dhcp: host-opts: routers: priv21-gw.priv21 string-opts: - domain-name: priv21.zentralwerk.org + domain-name: priv21.zentralwerk.dn42 priv22: start: 172.20.74.178 @@ -290,7 +290,7 @@ dhcp: host-opts: routers: priv22-gw.priv22 string-opts: - domain-name: priv22.zentralwerk.org + domain-name: priv22.zentralwerk.dn42 priv23: start: 172.20.73.165 @@ -302,7 +302,7 @@ dhcp: host-opts: routers: priv23-gw.priv23 string-opts: - domain-name: priv23.zentralwerk.org + domain-name: priv23.zentralwerk.dn42 fixed-hosts: 172.20.73.162: da:2c:3a:2c:87:22 172.20.73.163: ca:9f:27:b2:bf:6d @@ -318,7 +318,7 @@ dhcp: host-opts: routers: priv24-gw.priv24 string-opts: - domain-name: priv24.zentralwerk.org + domain-name: priv24.zentralwerk.dn42 priv25: start: 172.20.74.82 @@ -330,7 +330,7 @@ dhcp: host-opts: routers: priv25-gw.priv25 string-opts: - domain-name: priv25.zentralwerk.org + domain-name: priv25.zentralwerk.dn42 priv26: start: 172.20.75.50 @@ -342,7 +342,7 @@ dhcp: host-opts: routers: priv26-gw.priv26 string-opts: - domain-name: priv26.zentralwerk.org + domain-name: priv26.zentralwerk.dn42 priv27: start: 172.20.75.82 @@ -354,7 +354,7 @@ dhcp: host-opts: routers: priv27-gw.priv27 string-opts: - domain-name: priv27.zentralwerk.org + domain-name: priv27.zentralwerk.dn42 priv28: start: 172.20.75.114 @@ -366,7 +366,7 @@ dhcp: host-opts: routers: priv28-gw.priv28 string-opts: - domain-name: priv28.zentralwerk.org + domain-name: priv28.zentralwerk.dn42 priv29: start: 172.20.75.146 @@ -378,7 +378,7 @@ dhcp: host-opts: routers: priv29-gw.priv29 string-opts: - domain-name: priv29.zentralwerk.org + domain-name: priv29.zentralwerk.dn42 priv30: start: 172.20.75.178 @@ -390,7 +390,7 @@ dhcp: host-opts: routers: priv30-gw.priv30 string-opts: - domain-name: priv30.zentralwerk.org + domain-name: priv30.zentralwerk.dn42 priv31: start: 172.20.75.210 @@ -402,7 +402,7 @@ dhcp: host-opts: routers: priv31-gw.priv31 string-opts: - domain-name: priv31.zentralwerk.org + domain-name: priv31.zentralwerk.dn42 priv32: start: 172.20.75.242 @@ -414,7 +414,7 @@ dhcp: host-opts: routers: priv32-gw.priv32 string-opts: - domain-name: priv32.zentralwerk.org + domain-name: priv32.zentralwerk.dn42 priv33: start: 172.20.74.18 @@ -426,7 +426,7 @@ dhcp: host-opts: routers: priv33-gw.priv33 string-opts: - domain-name: priv33.zentralwerk.org + domain-name: priv33.zentralwerk.dn42 priv34: start: 172.20.74.210 @@ -438,7 +438,7 @@ dhcp: host-opts: routers: priv34-gw.priv34 string-opts: - domain-name: priv34.zentralwerk.org + domain-name: priv34.zentralwerk.dn42 priv35: start: 172.20.76.2 @@ -450,7 +450,7 @@ dhcp: host-opts: routers: priv35-gw.priv35 string-opts: - domain-name: priv35.zentralwerk.org + domain-name: priv35.zentralwerk.dn42 priv36: start: 172.20.76.66 @@ -462,7 +462,7 @@ dhcp: host-opts: routers: priv36-gw.priv36 string-opts: - domain-name: priv36.zentralwerk.org + domain-name: priv36.zentralwerk.dn42 priv37: start: 172.20.76.130 @@ -474,7 +474,7 @@ dhcp: host-opts: routers: priv37-gw.priv37 string-opts: - domain-name: priv37.zentralwerk.org + domain-name: priv37.zentralwerk.dn42 priv38: start: 172.20.76.194 @@ -486,7 +486,7 @@ dhcp: host-opts: routers: priv38-gw.priv38 string-opts: - domain-name: priv38.zentralwerk.org + domain-name: priv38.zentralwerk.dn42 priv39: start: 172.20.77.130 @@ -498,7 +498,7 @@ dhcp: host-opts: routers: priv39-gw.priv39 string-opts: - domain-name: priv39.zentralwerk.org + domain-name: priv39.zentralwerk.dn42 priv40: start: 172.20.77.66 @@ -510,4 +510,4 @@ dhcp: host-opts: routers: priv40-gw.priv40 string-opts: - domain-name: priv40.zentralwerk.org + domain-name: priv40.zentralwerk.dn42 diff --git a/salt-pillar/hosts/init.sls b/salt-pillar/hosts/init.sls index 298085f..5cc2322 100644 --- a/salt-pillar/hosts/init.sls +++ b/salt-pillar/hosts/init.sls @@ -159,12 +159,6 @@ hosts-inet: pub: pub-gw: 172.20.78.1 -{%- for i in range(2, 256) %} - guest{{ i }}: 172.20.78.{{ i }} -{%- endfor %} -{%- for i in range(0, 255) %} - guest{{ 256 + i }}: 172.20.79.{{ i }} -{%- endfor %} serv: serv-gw: 172.20.73.1 dns: 172.20.73.2