diff --git a/README.md b/README.md new file mode 100644 index 0000000..38ea538 --- /dev/null +++ b/README.md @@ -0,0 +1,48 @@ +# Nyota - PVVs network host configuration + +Nyota, named after Nyota Uhura, is intended to serve as _the_ source of truth for PVVs DNS and DHCP configurations. +It is based on nix, and contains both the generating code and actual data. + +Normal PVV "hosts" (servers or similar) can be defined in ./hosts.nix, and custom DNS configurations can be placed in each zone configuration file in ./zones, such as ./zones/pvv.ntnu.no.nix. + +## Building DNS zone files + +Provided you already have nix, you should be able to run `nix build .#zoneConfig`, and the resulting config is placed in `./result/zones`. + +## Building DHCP configuration + +(not implemented) + + +## Examples; + +A host configuration like + +```nix + drolsum = { + ipv4 = pvvv4 217; + ipv6 = pvvv6 217; + aliases = [ "login2" ]; + }; + + roundrobin = { + ipv4 = [ (pvvv4 101) (pvvv4 102) ]; + ipv6 = [ (pvvv6 101) (pvvv6 102) ]; + }; + +``` + +... will generate a bind configuration like + + +```bind +drolsum.pvv.ntnu.no. IN A 129.241.210.217 +drolsum.pvv.ntnu.no. IN AAAA 2001:700:300:1900::217 +login2.pvv.ntnu.no. IN CNAME drolsum + + +roundrobin.pvv.ntnu.no. IN A 129.241.210.101 +roundrobin.pvv.ntnu.no. IN A 129.241.210.102 +roundrobin.pvv.ntnu.no. IN AAAA 2001:700:300:1900::101 +roundrobin.pvv.ntnu.no. IN AAAA 2001:700:300:1900::102 +``` diff --git a/hosts.nix b/hosts.nix new file mode 100644 index 0000000..15584a4 --- /dev/null +++ b/hosts.nix @@ -0,0 +1,35 @@ +let + pvvv4 = hostPart: "129.241.210.${toString hostPart}"; + pvvv6 = hostPart: "2001:700:300:1900::${toString hostPart}"; +in { + + # Terminaler + demiurgen = { + ipv4 = pvvv4 200; + ipv6 = pvvv6 200; + # hinfo = ["Terminal" "Debian"]; + aliases = [ "rurgen" ]; + }; + + # Andre servere + drolsum = { + ipv4 = pvvv4 217; + ipv6 = pvvv6 217; + # hinfo = ["Login-boks" "Debian-konteiner"]; + aliases = [ "login2" ]; + }; + + # DNS-testere + utenipv4 = { + ipv6 = pvvv6 1337; + }; + + utenipv6 = { + ipv4 = pvvv4 137; + }; + + roundrobin = { + ipv4 = [ (pvvv4 101) (pvvv4 102) ]; + ipv6 = [ (pvvv6 101) (pvvv6 102) ]; + }; +} diff --git a/zoneConfig.nix b/zoneConfig.nix index 00f5e93..dea93f7 100644 --- a/zoneConfig.nix +++ b/zoneConfig.nix @@ -9,9 +9,12 @@ let zoneConfigs = lib.mapAttrs - (name: path: writeText "${name}.zone" (dns.lib.toString name (import path { inherit dns; }))) + (name: path: writeText "${name}.zone" (dns.lib.toString name (import path { inherit dns lib; }))) { "pvv.ntnu.no" = ./zones/pvv.ntnu.no.nix; + #"pvv.org" = ./zones/pvv.ntnu.no.nix; + #"reverse-ipv4" = /zones/reverse-ipv4.nix + #"reverse-ipv6" = /zones/reverse-ipv6.nix }; in stdenvNoCC.mkDerivation { diff --git a/zones/pvv.ntnu.no.nix b/zones/pvv.ntnu.no.nix index 3ddb2df..c5b7a7e 100644 --- a/zones/pvv.ntnu.no.nix +++ b/zones/pvv.ntnu.no.nix @@ -1,23 +1,59 @@ -{ dns, ... }: +{ dns, lib, ... }: with dns.lib.combinators; +let + hosts = import ../hosts.nix; +in { SOA = { - nameServer = "ns1.pvv.ntnu.no"; + nameServer = "dvask.pvv.ntnu.no"; adminEmail = "drift@pvv.ntnu.no"; serial = 2025021701; # TODO: Automate }; NS = [ - "ns1.pvv.ntnu.no" - "ns2.pvv.ntnu.no" + "dvask.pvv.ntnu.no" + "nn.unintett.no" ]; CNAME = [ "www.pvv.ntnu.no" ]; - subdomains = rec { - foobar = host "203.0.113.2" "4321:0:1:2:3:4:567:89bb"; + subdomains = + # Normal host forward records + (lib.mapAttrs ( + name: host: + lib.filterAttrs (_: value: !builtins.isNull value) { - ns1 = foobar; - ns2 = host "203.0.113.3" "4321:0:1:2:3:4:567:89cc"; - }; + A = if !builtins.hasAttr "ipv4" host then null + else if builtins.elem (builtins.typeOf host.ipv4) [ "list" "set" ] then host.ipv4 + else [ host.ipv4 ]; + + AAAA = if !builtins.hasAttr "ipv6" host then null + else if builtins.elem (builtins.typeOf host.ipv6) [ "list" "set" ] then host.ipv6 + else [ host.ipv6 ]; + } + ) hosts) + + # Above can be replaced using dns.nix helpers, without support for roundrobin, custom TTL, etc; + # (lib.mapAttrs (name: host: dns.lib.host (host.ipv4 or null) (host.ipv6 or null)) hosts) + + + # CNAMEs + // builtins.listToAttrs ( + lib.concatLists ( + lib.mapAttrsToList ( + target: host: + if (!builtins.hasAttr "aliases" host) then [ ] + else + lib.map (source: { + name = source; + value.CNAME = [ target ]; + }) host.aliases + ) hosts + ) + ) + + # Custom DNS subdomains + // { + "_dmarc".TXT = [ "v=DMARC1; p=quarantine; fo=1;" ]; # TODO: Better example, as dns.nix has the DMARC type + }; }