From b1bd6ca40a14fa36db2aa3bb7a47d342bc298668 Mon Sep 17 00:00:00 2001 From: Brendan Golden Date: Tue, 16 Jul 2024 22:31:28 +0100 Subject: [PATCH 01/12] feat: unify the record options --- applications/dns.nix | 23 +++-------------------- applications/dns/options-records.nix | 23 +++++++++++++++++++++++ config/dns.nix | 25 +++---------------------- 3 files changed, 29 insertions(+), 42 deletions(-) create mode 100644 applications/dns/options-records.nix diff --git a/applications/dns.nix b/applications/dns.nix index deec46d..9bb7d48 100644 --- a/applications/dns.nix +++ b/applications/dns.nix @@ -316,28 +316,11 @@ in { }; }; - # mirrorred in ../config/dns.nix records = lib.mkOption { description = "Records, sorted based on therir type"; - type = with lib.types; - listOf (submodule { - options = { - record = lib.mkOption { - type = str; - }; - r_type = lib.mkOption { - type = enum ["A" "CNAME" "TXT" "PTR" "SRV" "MX"]; - }; - value = lib.mkOption { - type = str; - }; - server = lib.mkOption { - description = "Core record for a server"; - type = bool; - default = false; - }; - }; - }); + type = lib.types.listOf (lib.types.submodule (import ./dns/options-records.nix { + inherit lib; + })); }; }; diff --git a/applications/dns/options-records.nix b/applications/dns/options-records.nix new file mode 100644 index 0000000..1795099 --- /dev/null +++ b/applications/dns/options-records.nix @@ -0,0 +1,23 @@ +/* +Define the options for dns records here. +They are imported into anything that needs to use them +*/ +{lib, ...}: +with lib; { + options = { + record = lib.mkOption { + type = lib.types.str; + }; + r_type = lib.mkOption { + type = lib.types.enum ["A" "CNAME" "TXT" "PTR" "SRV" "MX"]; + }; + value = lib.mkOption { + type = lib.types.str; + }; + server = lib.mkOption { + description = "Core record for a server"; + type = lib.types.bool; + default = false; + }; + }; +} diff --git a/config/dns.nix b/config/dns.nix index ef07285..931a176 100644 --- a/config/dns.nix +++ b/config/dns.nix @@ -1,31 +1,12 @@ {lib, ...}: { imports = [ - # Paths to other modules. - # Compose this module out of smaller ones. ]; - # this needs to mirror ../applications/dns.nix options.skynet.records = lib.mkOption { description = "Records, sorted based on therir type"; - type = with lib.types; - listOf (submodule { - options = { - record = lib.mkOption { - type = str; - }; - r_type = lib.mkOption { - type = enum ["A" "CNAME" "TXT" "PTR" "SRV" "MX"]; - }; - value = lib.mkOption { - type = str; - }; - server = lib.mkOption { - description = "Core record for a server"; - type = bool; - default = false; - }; - }; - }); + type = lib.types.listOf (lib.types.submodule (import ../applications/dns/options-records.nix { + inherit lib; + })); }; config = { From cb0cfbaf4a7d27403e4fef891639b00a764834a9 Mon Sep 17 00:00:00 2001 From: Brendan Golden Date: Tue, 16 Jul 2024 22:33:27 +0100 Subject: [PATCH 02/12] fmt: move the dns into its own folder --- applications/_base.nix | 2 +- applications/{ => dns}/dns.nix | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) rename applications/{ => dns}/dns.nix (98%) diff --git a/applications/_base.nix b/applications/_base.nix index bd1f017..3224563 100644 --- a/applications/_base.nix +++ b/applications/_base.nix @@ -10,7 +10,7 @@ with lib; let in { imports = [ ./acme.nix - ./dns.nix + ../dns/dns.nix ./nginx.nix ]; diff --git a/applications/dns.nix b/applications/dns/dns.nix similarity index 98% rename from applications/dns.nix rename to applications/dns/dns.nix index 9bb7d48..9503539 100644 --- a/applications/dns.nix +++ b/applications/dns/dns.nix @@ -291,8 +291,8 @@ else "ns2"; in { imports = [ - ./firewall.nix - ../config/dns.nix + ../firewall.nix + ../../config/dns.nix ]; options.services.skynet."${name}" = { @@ -318,7 +318,7 @@ in { records = lib.mkOption { description = "Records, sorted based on therir type"; - type = lib.types.listOf (lib.types.submodule (import ./dns/options-records.nix { + type = lib.types.listOf (lib.types.submodule (import ./options-records.nix { inherit lib; })); }; @@ -357,7 +357,7 @@ in { # secrets required age.secrets.dns_dnskeys = { - file = ../secrets/dns_dnskeys.conf.age; + file = ../../secrets/dns_dnskeys.conf.age; owner = "named"; group = "named"; }; From e9d5985adf7beca18f8c264da63b1edb0d04bc50 Mon Sep 17 00:00:00 2001 From: Brendan Golden Date: Tue, 16 Jul 2024 23:09:22 +0100 Subject: [PATCH 03/12] fmt: remove duplicate imports, now unified in applications/_base.nix --- applications/_base.nix | 17 ++++++++++++++++- applications/_retired/games.nix | 1 - applications/_retired/games/minecraft.nix | 4 ---- applications/bitwarden/vaultwarden.nix | 3 --- applications/dns/dns.nix | 1 - applications/email.nix | 3 --- applications/gitlab.nix | 4 ---- applications/grafana.nix | 2 -- applications/ldap/backend.nix | 3 --- applications/ldap/server.nix | 3 --- applications/nextcloud.nix | 3 --- applications/nix_cache/nix_cache.nix | 2 -- applications/open_governance/keyserver.nix | 2 -- .../open_governance/open_governance.nix | 2 -- applications/skynet_users.nix | 3 --- applications/ulfm.nix | 4 ---- machines/_base.nix | 17 +---------------- machines/retired/ash.nix | 3 --- 18 files changed, 17 insertions(+), 60 deletions(-) diff --git a/applications/_base.nix b/applications/_base.nix index 3224563..f96d7e4 100644 --- a/applications/_base.nix +++ b/applications/_base.nix @@ -9,9 +9,24 @@ with lib; let cfg = config.services.skynet; in { imports = [ + # every server needs to have a dns record + ./dns/dns.nix + + # every server should have proper certs ./acme.nix - ../dns/dns.nix ./nginx.nix + + # every server may need the firewall config stuff + ./firewall.nix + + # every server needs teh ldap client for admins + ./ldap/client.nix + + # every server will need the config to backup to + ./restic.nix + + # every server will be monitored for grafana + ./prometheus.nix ]; options.services.skynet = { diff --git a/applications/_retired/games.nix b/applications/_retired/games.nix index 7ffd9f7..2f48ae0 100644 --- a/applications/_retired/games.nix +++ b/applications/_retired/games.nix @@ -10,7 +10,6 @@ with lib; let cfg = config.services.skynet."${name}"; in { imports = [ - ./dns.nix ./nginx.nix ./games/minecraft.nix ]; diff --git a/applications/_retired/games/minecraft.nix b/applications/_retired/games/minecraft.nix index 8953efe..a71121c 100644 --- a/applications/_retired/games/minecraft.nix +++ b/applications/_retired/games/minecraft.nix @@ -13,10 +13,6 @@ with lib; let short_domain = "${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}"; in { imports = [ - ../acme.nix - ../dns.nix - ../firewall.nix - ../nginx.nix inputs.arion.nixosModules.arion ]; diff --git a/applications/bitwarden/vaultwarden.nix b/applications/bitwarden/vaultwarden.nix index 52e0422..fad00f4 100644 --- a/applications/bitwarden/vaultwarden.nix +++ b/applications/bitwarden/vaultwarden.nix @@ -13,9 +13,6 @@ with lib; let domain = "${domain_sub}.skynet.ie"; in { imports = [ - ../acme.nix - ../dns.nix - ../nginx.nix ]; options.services.skynet."${name}" = { diff --git a/applications/dns/dns.nix b/applications/dns/dns.nix index 9503539..ff80e89 100644 --- a/applications/dns/dns.nix +++ b/applications/dns/dns.nix @@ -291,7 +291,6 @@ else "ns2"; in { imports = [ - ../firewall.nix ../../config/dns.nix ]; diff --git a/applications/email.nix b/applications/email.nix index 182c280..f16a3e4 100644 --- a/applications/email.nix +++ b/applications/email.nix @@ -120,9 +120,6 @@ with lib; let ''; in { imports = [ - ./dns.nix - ./acme.nix - ./nginx.nix inputs.simple-nixos-mailserver.nixosModule # for teh config diff --git a/applications/gitlab.nix b/applications/gitlab.nix index 80664af..a65c43e 100644 --- a/applications/gitlab.nix +++ b/applications/gitlab.nix @@ -12,10 +12,6 @@ with lib; let domain_full = "${cfg.domain.sub}.${domain_base}"; in { imports = [ - ./acme.nix - ./dns.nix - ./firewall.nix - ./nginx.nix ]; options.services.skynet."${name}" = { diff --git a/applications/grafana.nix b/applications/grafana.nix index 15c076f..3bce51b 100644 --- a/applications/grafana.nix +++ b/applications/grafana.nix @@ -9,8 +9,6 @@ with lib; let port = 4444; in { imports = [ - ./acme.nix - ./dns.nix ]; options.services.skynet."${name}" = { diff --git a/applications/ldap/backend.nix b/applications/ldap/backend.nix index b4b0e13..180221e 100644 --- a/applications/ldap/backend.nix +++ b/applications/ldap/backend.nix @@ -11,9 +11,6 @@ with lib; let port_backend = "8087"; in { imports = [ - ../acme.nix - ../dns.nix - ../nginx.nix inputs.skynet_ldap_backend.nixosModule."x86_64-linux" ../../config/users.nix ]; diff --git a/applications/ldap/server.nix b/applications/ldap/server.nix index 67bd1fc..ee55600 100644 --- a/applications/ldap/server.nix +++ b/applications/ldap/server.nix @@ -15,9 +15,6 @@ with lib; let in { # these are needed for teh program in question imports = [ - ../acme.nix - ../dns.nix - ../nginx.nix ]; options.services.skynet."${name}" = { diff --git a/applications/nextcloud.nix b/applications/nextcloud.nix index 02bc5f6..e31f67c 100644 --- a/applications/nextcloud.nix +++ b/applications/nextcloud.nix @@ -10,9 +10,6 @@ with lib; let domain = "${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}"; in { imports = [ - ./acme.nix - ./dns.nix - ./nginx.nix ]; options.services.skynet."${name}" = { diff --git a/applications/nix_cache/nix_cache.nix b/applications/nix_cache/nix_cache.nix index 6716146..4dcfdae 100644 --- a/applications/nix_cache/nix_cache.nix +++ b/applications/nix_cache/nix_cache.nix @@ -24,8 +24,6 @@ with lib; let in { imports = [ inputs.attic.nixosModules.atticd - ../acme.nix - ../dns.nix ]; options.services.skynet."${name}" = { diff --git a/applications/open_governance/keyserver.nix b/applications/open_governance/keyserver.nix index c507a50..7e239a7 100644 --- a/applications/open_governance/keyserver.nix +++ b/applications/open_governance/keyserver.nix @@ -13,8 +13,6 @@ with lib; let port = 11371; in { imports = [ - ../acme.nix - ../dns.nix ]; options.services.skynet."${name}" = { diff --git a/applications/open_governance/open_governance.nix b/applications/open_governance/open_governance.nix index 93d2974..1b02248 100644 --- a/applications/open_governance/open_governance.nix +++ b/applications/open_governance/open_governance.nix @@ -15,8 +15,6 @@ with lib; let folder = "/var/skynet/${name}"; in { imports = [ - ../acme.nix - ../dns.nix ]; options.services.skynet."${name}" = { diff --git a/applications/skynet_users.nix b/applications/skynet_users.nix index 1b07875..56d9e07 100644 --- a/applications/skynet_users.nix +++ b/applications/skynet_users.nix @@ -11,9 +11,6 @@ with lib; let php_pool = name; in { imports = [ - ./acme.nix - ./dns.nix - ./nginx.nix ]; options.services.skynet."${name}" = { diff --git a/applications/ulfm.nix b/applications/ulfm.nix index b1013f3..d7bd97b 100644 --- a/applications/ulfm.nix +++ b/applications/ulfm.nix @@ -9,10 +9,6 @@ with lib; let cfg = config.services.skynet."${name}"; in { imports = [ - ./acme.nix - ./dns.nix - ./firewall.nix - ./nginx.nix ]; options.services.skynet."${name}" = { diff --git a/machines/_base.nix b/machines/_base.nix index 5972e49..f730ba3 100644 --- a/machines/_base.nix +++ b/machines/_base.nix @@ -18,23 +18,8 @@ in { # for the secrets inputs.agenix.nixosModules.default - # base config for all servers + # base application config for all servers ../applications/_base.nix - - # every sever may need the firewall config stuff - ../applications/firewall.nix - - # every sever needs to have a dns record - ../applications/dns.nix - - # every server needs teh ldap client for admins - ../applications/ldap/client.nix - - # every server will need the config to backup to - ../applications/restic.nix - - # every server will be monitored for grafana - ../applications/prometheus.nix ]; options.skynet = { diff --git a/machines/retired/ash.nix b/machines/retired/ash.nix index b16fc39..a350975 100644 --- a/machines/retired/ash.nix +++ b/machines/retired/ash.nix @@ -22,9 +22,6 @@ Notes: Thius vpn is for admin use only, to give access to all the servers via hostname = ip_pub; in { imports = [ - # applications for this particular server - ../applications/firewall.nix - ../applications/dns.nix ]; deployment = { From 15e534c2222cfe05a1716fbe5e12a412c5984d92 Mon Sep 17 00:00:00 2001 From: Brendan Golden Date: Tue, 16 Jul 2024 23:17:38 +0100 Subject: [PATCH 04/12] feat: add new option for dns records --- applications/dns/options-records.nix | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/applications/dns/options-records.nix b/applications/dns/options-records.nix index 1795099..53e443f 100644 --- a/applications/dns/options-records.nix +++ b/applications/dns/options-records.nix @@ -5,13 +5,21 @@ They are imported into anything that needs to use them {lib, ...}: with lib; { options = { + domain = lib.mkOption { + description = "Domain this record is for"; + type = lib.types.str; + default = "skynet.ie"; + }; record = lib.mkOption { + description = "What you want to name the subdomain."; type = lib.types.str; }; r_type = lib.mkOption { + description = "Type of record that this is."; type = lib.types.enum ["A" "CNAME" "TXT" "PTR" "SRV" "MX"]; }; value = lib.mkOption { + description = "What the record points to, normally ip or another record."; type = lib.types.str; }; server = lib.mkOption { From 1a07781c4dbd102a8f681d51c897b863872302b8 Mon Sep 17 00:00:00 2001 From: Brendan Golden Date: Wed, 17 Jul 2024 00:47:45 +0100 Subject: [PATCH 05/12] feat: the right width for records will now be auto calculated --- applications/dns/dns.nix | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/applications/dns/dns.nix b/applications/dns/dns.nix index ff80e89..6c355e2 100644 --- a/applications/dns/dns.nix +++ b/applications/dns/dns.nix @@ -30,7 +30,18 @@ sort_records_ptr = builtins.sort (a: b: (lib.strings.toInt a.record) < (lib.strings.toInt b.record)) (process_ptr (filter_records_type "PTR")); sort_records_srv = builtins.sort (a: b: a.record < b.record) (filter_records_type "SRV"); - format_records = records: offset: lib.strings.concatMapStrings (x: "${padString x.record offset} IN ${padString x.r_type 5} ${x.value}\n") records; + max = x: y: + assert builtins.isInt x; + assert builtins.isInt y; + if x < y + then y + else x; + max_len = records: lib.lists.foldr (a: b: (max a b)) 0 (lib.lists.forEach records (record: lib.strings.stringLength record.record)); + + format_records = records: let + offset = (max_len records) + 1; + in + lib.strings.concatMapStrings (x: "${padString x.record offset} IN ${padString x.r_type 5} ${x.value}\n") records; # small function to trim it down a tad padString = text: length: fixedWidthString_post length " " text; @@ -72,32 +83,32 @@ ; ------------------------------------------ ; Server Names (A Records) ; ------------------------------------------ - ${format_records sort_records_server 31} + ${format_records sort_records_server} ; ------------------------------------------ ; A (non server names ; ------------------------------------------ - ${format_records sort_records_a 31} + ${format_records sort_records_a} ; ------------------------------------------ ; CNAMES ; ------------------------------------------ - ${format_records sort_records_cname 31} + ${format_records sort_records_cname} ; ------------------------------------------ ; TXT ; ------------------------------------------ - ${format_records (filter_records_type "TXT") 31} + ${format_records (filter_records_type "TXT")} ; ------------------------------------------ ; MX ; ------------------------------------------ - ${format_records (filter_records_type "MX") 31} + ${format_records (filter_records_type "MX")} ; ------------------------------------------ ; SRV ; ------------------------------------------ - ${format_records sort_records_srv 65} + ${format_records sort_records_srv} '' @@ -125,7 +136,7 @@ ; ------------------------------------------ ; PTR ; ------------------------------------------ - ${format_records sort_records_ptr 3} + ${format_records sort_records_ptr} '' ); From 356ac2e505d52604a69c976a1a1dfc58dde866f9 Mon Sep 17 00:00:00 2001 From: Brendan Golden Date: Wed, 17 Jul 2024 00:52:55 +0100 Subject: [PATCH 06/12] fix: move the mailserver dns config to the proper file --- applications/dns/dns.nix | 5 ----- applications/email.nix | 8 ++++++++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/applications/dns/dns.nix b/applications/dns/dns.nix index 6c355e2..96dd70a 100644 --- a/applications/dns/dns.nix +++ b/applications/dns/dns.nix @@ -74,11 +74,6 @@ @ NS ns2.${domain}. ; @ stands for teh root domain so teh A record below is where ${domain} points to ;@ A 193.1.99.76 - ;@ MX 5 ${domain}. - - ; can have multiple mailserves - @ MX 10 mail.${domain}. - ; ------------------------------------------ ; Server Names (A Records) diff --git a/applications/email.nix b/applications/email.nix index f16a3e4..e988b0d 100644 --- a/applications/email.nix +++ b/applications/email.nix @@ -268,6 +268,14 @@ in { # set up dns record for it services.skynet.dns.records = [ + # core record + { + record = "@"; + r_type = "MX"; + # the number is the priority in teh case of multiple mailservers + value = "10 mail.${cfg.domain}."; + } + # basic one { record = "mail"; From 0b25b5ac548f9a1342c413085b0c5763f3baf56e Mon Sep 17 00:00:00 2001 From: Brendan Golden Date: Wed, 17 Jul 2024 00:53:28 +0100 Subject: [PATCH 07/12] fix: smol cleanup --- applications/dns/dns.nix | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/applications/dns/dns.nix b/applications/dns/dns.nix index 96dd70a..82bec0e 100644 --- a/applications/dns/dns.nix +++ b/applications/dns/dns.nix @@ -70,10 +70,9 @@ 3600 ; Minimum (1 hour) ) + ; @ stands for teh root domain so teh A record below is where ${domain} points to @ NS ns1.${domain}. @ NS ns2.${domain}. - ; @ stands for teh root domain so teh A record below is where ${domain} points to - ;@ A 193.1.99.76 ; ------------------------------------------ ; Server Names (A Records) From 2a8a7cc7f4471bb54159ad79ea2ece0b2b4f739a Mon Sep 17 00:00:00 2001 From: Brendan Golden Date: Wed, 17 Jul 2024 01:38:31 +0100 Subject: [PATCH 08/12] feat: simplify the zone creation --- applications/dns/dns.nix | 58 +++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/applications/dns/dns.nix b/applications/dns/dns.nix index 82bec0e..a2725f3 100644 --- a/applications/dns/dns.nix +++ b/applications/dns/dns.nix @@ -11,6 +11,22 @@ # reads that date to a string (will need to be fixed in 2038) current_date = lib.readFile "${pkgs.runCommand "timestamp" {} "echo -n `date +%s` > $out"}"; + # this gets a list of all domains we have records for + domains = lib.lists.naturalSort ( + lib.lists.unique ( + lib.lists.forEach records (record: record.domain) + ) + ); + + domains_owned = [ + # for historic reasons we own this + "csn.ul.ie" + # the main one we use now + "skynet.ie" + # a backup + "ulcompsoc.ie" + ]; + # gets a list of records that match this type filter_records_type = r_type: builtins.filter (x: x.r_type == r_type) records; filter_records_server = builtins.filter (x: builtins.hasAttr "server" x && x.server) (filter_records_type "A"); @@ -205,10 +221,19 @@ then create_entry_etc_sub domain (text.old domain) else {}; - create_entry_zone = domain: extraConfig: { + create_entry_zone = domain: let + if_primary_and_owned = + if cfg.server.primary && (lib.lists.any (item: item == domain) domains_owned) + then '' + allow-update { key rfc2136key.skynet.ie.; }; + dnssec-policy default; + inline-signing yes; + '' + else ""; + in { "${domain}" = { extraConfig = '' - ${extraConfig} + ${if_primary_and_owned} // for bumping the config // ${current_date} ''; @@ -229,23 +254,6 @@ old = domain: get_config_file_old_domains domain; }; - extraConfig = { - owned = - if cfg.server.primary - then '' - allow-update { key rfc2136key.skynet.ie.; }; - - dnssec-policy default; - inline-signing yes; - '' - else ""; - - # no extra config for reverse - reverse = ""; - - old = ""; - }; - records = config.skynet.records ++ builtins.concatLists ( @@ -344,12 +352,12 @@ in { ]; services.bind.zones = - (create_entry_zone "csn.ul.ie" extraConfig.owned) - // (create_entry_zone "skynet.ie" extraConfig.owned) - // (create_entry_zone "ulcompsoc.ie" extraConfig.owned) - // (create_entry_zone "64-64.99.1.193.in-addr.arpa" extraConfig.reverse) - // (create_entry_zone "conradcollins.net" extraConfig.old) - // (create_entry_zone "edelharty.net" extraConfig.old); + (create_entry_zone "csn.ul.ie") + // (create_entry_zone "skynet.ie") + // (create_entry_zone "ulcompsoc.ie") + // (create_entry_zone "64-64.99.1.193.in-addr.arpa") + // (create_entry_zone "conradcollins.net") + // (create_entry_zone "edelharty.net"); environment.etc = (create_entry_etc "csn.ul.ie" "owned") From 454e58b08575f17e33d203dfc73c34fb87bbf5ec Mon Sep 17 00:00:00 2001 From: Brendan Golden Date: Wed, 17 Jul 2024 03:00:20 +0100 Subject: [PATCH 09/12] feat: generate the zones directly from teh dns records --- applications/dns/dns.nix | 27 ++++--- config/dns.nix | 161 ++++++++++++++++++++++----------------- 2 files changed, 107 insertions(+), 81 deletions(-) diff --git a/applications/dns/dns.nix b/applications/dns/dns.nix index a2725f3..044632c 100644 --- a/applications/dns/dns.nix +++ b/applications/dns/dns.nix @@ -14,7 +14,7 @@ # this gets a list of all domains we have records for domains = lib.lists.naturalSort ( lib.lists.unique ( - lib.lists.forEach records (record: record.domain) + lib.lists.forEach records (x: x.domain) ) ); @@ -76,8 +76,8 @@ get_config_file = ( domain: '' $TTL 60 ; 1 minute - ; hostmaster@${domain} is an email address that recieves stuff related to dns - @ IN SOA ${nameserver}.${domain}. hostmaster.${domain}. ( + ; hostmaster@skynet.ie is an email address that recieves stuff related to dns + @ IN SOA ${nameserver}.skynet.ie. hostmaster.skynet.ie. ( ; Serial (YYYYMMDDCC) this has to be updated for each time the record is updated ${current_date} 600 ; Refresh (10 minutes) @@ -87,8 +87,8 @@ ) ; @ stands for teh root domain so teh A record below is where ${domain} points to - @ NS ns1.${domain}. - @ NS ns2.${domain}. + @ NS ns1.skynet.ie. + @ NS ns2.skynet.ie. ; ------------------------------------------ ; Server Names (A Records) @@ -274,6 +274,7 @@ details_records ++ [ { + domain = "skynet.ie"; record = "ns1"; r_type = "A"; value = details_server.ip; @@ -284,6 +285,7 @@ details_records ++ [ { + domain = "skynet.ie"; record = "ns2"; r_type = "A"; value = details_server.ip; @@ -351,13 +353,14 @@ in { "ip daddr ${cfg.server.ip} udp dport 53 counter packets 0 bytes 0 accept" ]; - services.bind.zones = - (create_entry_zone "csn.ul.ie") - // (create_entry_zone "skynet.ie") - // (create_entry_zone "ulcompsoc.ie") - // (create_entry_zone "64-64.99.1.193.in-addr.arpa") - // (create_entry_zone "conradcollins.net") - // (create_entry_zone "edelharty.net"); + services.bind.zones = lib.attrsets.mergeAttrsList ( + # uses teh domains lsited in teh records + (lib.lists.forEach domains (domain: (create_entry_zone domain))) + # we have to do a reverse dns + ++ [ + (create_entry_zone "64-64.99.1.193.in-addr.arpa") + ] + ); environment.etc = (create_entry_etc "csn.ul.ie" "owned") diff --git a/config/dns.nix b/config/dns.nix index 931a176..08eeb4c 100644 --- a/config/dns.nix +++ b/config/dns.nix @@ -10,74 +10,97 @@ }; config = { - skynet.records = [ - { - record = "optimus"; - r_type = "A"; - value = "193.1.99.90"; - server = true; - } - { - record = "panel.games"; - r_type = "CNAME"; - value = "optimus"; - } - { - record = "bumblebee"; - r_type = "A"; - value = "193.1.99.91"; - server = true; - } - { - record = "minecraft.compsoc.games"; - r_type = "CNAME"; - value = "bumblebee"; - } - { - record = "_minecraft._tcp.minecraft.compsoc.games.skynet.ie."; - r_type = "SRV"; - value = "0 10 25518 minecraft.compsoc.games.skynet.ie."; - } - { - record = "minecraft-classic.compsoc.games"; - r_type = "CNAME"; - value = "bumblebee"; - } - { - record = "_minecraft._tcp.minecraft-classic.compsoc.games.skynet.ie."; - r_type = "SRV"; - value = "0 10 25518 minecraft-classic.compsoc.games.skynet.ie."; - } - { - record = "minecraft.gsoc.games"; - r_type = "CNAME"; - value = "bumblebee"; - } - { - record = "_minecraft._tcp.minecraft.gsoc.games.skynet.ie."; - r_type = "SRV"; - value = "0 10 25521 minecraft.gsoc.games.skynet.ie."; - } - { - record = "minecraft.phildeb.games"; - r_type = "CNAME"; - value = "bumblebee"; - } - { - record = "_minecraft._tcp.minecraft.phildeb.games.skynet.ie."; - r_type = "SRV"; - value = "0 10 25522 minecraft.phildeb.games.skynet.ie."; - } - { - record = "minecraft-aged.compsoc.games"; - r_type = "CNAME"; - value = "bumblebee"; - } - { - record = "_minecraft._tcp.minecraft-aged.compsoc.games.skynet.ie."; - r_type = "SRV"; - value = "0 10 25519 minecraft.phildeb.games.skynet.ie."; - } - ]; + skynet.records = + [ + { + record = "optimus"; + r_type = "A"; + value = "193.1.99.90"; + server = true; + } + { + record = "panel.games"; + r_type = "CNAME"; + value = "optimus"; + } + { + record = "bumblebee"; + r_type = "A"; + value = "193.1.99.91"; + server = true; + } + { + record = "minecraft.compsoc.games"; + r_type = "CNAME"; + value = "bumblebee"; + } + { + record = "_minecraft._tcp.minecraft.compsoc.games.skynet.ie."; + r_type = "SRV"; + value = "0 10 25518 minecraft.compsoc.games.skynet.ie."; + } + { + record = "minecraft-classic.compsoc.games"; + r_type = "CNAME"; + value = "bumblebee"; + } + { + record = "_minecraft._tcp.minecraft-classic.compsoc.games.skynet.ie."; + r_type = "SRV"; + value = "0 10 25518 minecraft-classic.compsoc.games.skynet.ie."; + } + { + record = "minecraft.gsoc.games"; + r_type = "CNAME"; + value = "bumblebee"; + } + { + record = "_minecraft._tcp.minecraft.gsoc.games.skynet.ie."; + r_type = "SRV"; + value = "0 10 25521 minecraft.gsoc.games.skynet.ie."; + } + { + record = "minecraft.phildeb.games"; + r_type = "CNAME"; + value = "bumblebee"; + } + { + record = "_minecraft._tcp.minecraft.phildeb.games.skynet.ie."; + r_type = "SRV"; + value = "0 10 25522 minecraft.phildeb.games.skynet.ie."; + } + { + record = "minecraft-aged.compsoc.games"; + r_type = "CNAME"; + value = "bumblebee"; + } + { + record = "_minecraft._tcp.minecraft-aged.compsoc.games.skynet.ie."; + r_type = "SRV"; + value = "0 10 25519 minecraft.phildeb.games.skynet.ie."; + } + ] + # non skynet domains + ++ [ + { + domain = "conradcollins.net"; + record = "www"; + r_type = "CNAME"; + value = "skynet.skynet.ie."; + } + + { + domain = "edelharty.net"; + record = "www"; + r_type = "CNAME"; + value = "skynet.skynet.ie."; + } + { + domain = "damienconroy.com"; + record = "www"; + r_type = "CNAME"; + value = "skynet.skynet.ie."; + } + ]; }; } From 4c8ebb455e7a23c057f56b2ba7067f3a955f564f Mon Sep 17 00:00:00 2001 From: Brendan Golden Date: Wed, 17 Jul 2024 03:50:20 +0100 Subject: [PATCH 10/12] feat: the actual bind files are now created directly from teh records --- applications/dns/dns.nix | 83 ++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 54 deletions(-) diff --git a/applications/dns/dns.nix b/applications/dns/dns.nix index 044632c..0202922 100644 --- a/applications/dns/dns.nix +++ b/applications/dns/dns.nix @@ -28,9 +28,9 @@ ]; # gets a list of records that match this type - filter_records_type = r_type: builtins.filter (x: x.r_type == r_type) records; - filter_records_server = builtins.filter (x: builtins.hasAttr "server" x && x.server) (filter_records_type "A"); - filter_records_a = builtins.filter (x: builtins.hasAttr "server" x && !x.server) (filter_records_type "A"); + filter_records_type = records: r_type: builtins.filter (x: x.r_type == r_type) records; + filter_records_server = records: builtins.filter (x: builtins.hasAttr "server" x && x.server) (filter_records_type records "A"); + filter_records_a = records: builtins.filter (x: builtins.hasAttr "server" x && !x.server) (filter_records_type records "A"); process_ptr = records: lib.lists.forEach records (x: process_ptr_sub x); process_ptr_sub = record: { @@ -40,11 +40,11 @@ }; ip_ptr_to_int = ip: lib.strings.toInt (builtins.substring 9 3 ip); - sort_records_server = builtins.sort (a: b: a.record < b.record) filter_records_server; - sort_records_a = builtins.sort (a: b: (ip_ptr_to_int a.value) < (ip_ptr_to_int b.value)) filter_records_a; - sort_records_cname = builtins.sort (a: b: a.value < b.value) (filter_records_type "CNAME"); - sort_records_ptr = builtins.sort (a: b: (lib.strings.toInt a.record) < (lib.strings.toInt b.record)) (process_ptr (filter_records_type "PTR")); - sort_records_srv = builtins.sort (a: b: a.record < b.record) (filter_records_type "SRV"); + sort_records_server = records: builtins.sort (a: b: a.record < b.record) (filter_records_server records); + sort_records_a = records: builtins.sort (a: b: (ip_ptr_to_int a.value) < (ip_ptr_to_int b.value)) (filter_records_a records); + sort_records_cname = records: builtins.sort (a: b: a.value < b.value) (filter_records_type records "CNAME"); + sort_records_ptr = records: builtins.sort (a: b: (lib.strings.toInt a.record) < (lib.strings.toInt b.record)) (process_ptr (filter_records_type records "PTR")); + sort_records_srv = records: builtins.sort (a: b: a.record < b.record) (filter_records_type records "SRV"); max = x: y: assert builtins.isInt x; @@ -74,7 +74,7 @@ # base config for domains we own (skynet.ie, csn.ul.ie, ulcompsoc.ie) get_config_file = ( - domain: '' + domain: records: '' $TTL 60 ; 1 minute ; hostmaster@skynet.ie is an email address that recieves stuff related to dns @ IN SOA ${nameserver}.skynet.ie. hostmaster.skynet.ie. ( @@ -93,32 +93,32 @@ ; ------------------------------------------ ; Server Names (A Records) ; ------------------------------------------ - ${format_records sort_records_server} + ${format_records (sort_records_server records)} ; ------------------------------------------ ; A (non server names ; ------------------------------------------ - ${format_records sort_records_a} + ${format_records (sort_records_a records)} ; ------------------------------------------ ; CNAMES ; ------------------------------------------ - ${format_records sort_records_cname} + ${format_records (sort_records_cname records)} ; ------------------------------------------ ; TXT ; ------------------------------------------ - ${format_records (filter_records_type "TXT")} + ${format_records (filter_records_type records "TXT")} ; ------------------------------------------ ; MX ; ------------------------------------------ - ${format_records (filter_records_type "MX")} + ${format_records (filter_records_type records "MX")} ; ------------------------------------------ ; SRV ; ------------------------------------------ - ${format_records sort_records_srv} + ${format_records (sort_records_srv records)} '' @@ -146,27 +146,7 @@ ; ------------------------------------------ ; PTR ; ------------------------------------------ - ${format_records sort_records_ptr} - '' - ); - - # domains we dont have proper ownship over, only here to ensure the logs dont get cluttered. - get_config_file_old_domains = ( - domain: '' - $TTL 60 ; 1 minute - ; hostmaster@skynet.ie is an email address that recieves stuff related to dns - @ IN SOA ${nameserver}.skynet.ie. hostmaster.skynet.ie. ( - ; Serial (YYYYMMDDCC) this has to be updated for each time the record is updated - ${current_date} - 600 ; Refresh (10 minutes) - 300 ; Retry (5 minutes) - 604800 ; Expire (1 week) - 3600 ; Minimum (1 hour) - ) - - @ NS ns1.skynet.ie. - @ NS ns2.skynet.ie. - + ${format_records (sort_records_ptr records)} '' ); @@ -212,13 +192,13 @@ # (text.owned "csn.ul.ie") # standard function to create the etc file, pass in the text and domain and it makes it - create_entry_etc = domain: type: + create_entry_etc = domain: type: let + domain_records = lib.lists.filter (x: x.domain == domain) records; + in if type == "owned" - then create_entry_etc_sub domain (text.owned domain) + then create_entry_etc_sub domain (get_config_file domain domain_records) else if type == "reverse" - then create_entry_etc_sub domain (text.reverse domain) - else if type == "old" - then create_entry_etc_sub domain (text.old domain) + then create_entry_etc_sub domain (get_config_file_rev domain) else {}; create_entry_zone = domain: let @@ -248,12 +228,6 @@ }; }; - text = { - owned = domain: get_config_file domain; - reverse = domain: get_config_file_rev domain; - old = domain: get_config_file_old_domains domain; - }; - records = config.skynet.records ++ builtins.concatLists ( @@ -362,13 +336,14 @@ in { ] ); - environment.etc = - (create_entry_etc "csn.ul.ie" "owned") - // (create_entry_etc "skynet.ie" "owned") - // (create_entry_etc "ulcompsoc.ie" "owned") - // (create_entry_etc "64-64.99.1.193.in-addr.arpa" "reverse") - // (create_entry_etc "conradcollins.net" "old") - // (create_entry_etc "edelharty.net" "old"); + environment.etc = lib.attrsets.mergeAttrsList ( + # uses teh domains lsited in teh records + (lib.lists.forEach domains (domain: (create_entry_etc domain "owned"))) + # we have to do a reverse dns + ++ [ + (create_entry_etc "64-64.99.1.193.in-addr.arpa" "reverse") + ] + ); # secrets required age.secrets.dns_dnskeys = { From 1287160cdf7d95a0876e76ff3f8b90d6f84dadd0 Mon Sep 17 00:00:00 2001 From: Brendan Golden Date: Wed, 17 Jul 2024 04:08:04 +0100 Subject: [PATCH 11/12] feat: reduced some complexity --- applications/dns/dns.nix | 52 +++++++++++----------------------------- 1 file changed, 14 insertions(+), 38 deletions(-) diff --git a/applications/dns/dns.nix b/applications/dns/dns.nix index 0202922..ec32461 100644 --- a/applications/dns/dns.nix +++ b/applications/dns/dns.nix @@ -230,46 +230,14 @@ records = config.skynet.records + /* + Need to "manually" grab it from each server. + Nix is laxy evalusted so if it does not need to open a file it wont. + This is to iterate through each server (node) and evaluate the dns records for that server. + */ ++ builtins.concatLists ( lib.attrsets.mapAttrsToList ( - key: value: let - details_server = value.config.services.skynet."${name}".server; - details_records = value.config.services.skynet."${name}".records; - in - if builtins.hasAttr "dns" value.config.services.skynet - then - ( - # got to handle habing a dns record for the dns serves themselves. - if details_server.enable - then - ( - if details_server.primary - then - details_records - ++ [ - { - domain = "skynet.ie"; - record = "ns1"; - r_type = "A"; - value = details_server.ip; - server = false; - } - ] - else - details_records - ++ [ - { - domain = "skynet.ie"; - record = "ns2"; - r_type = "A"; - value = details_server.ip; - server = false; - } - ] - ) - else details_records - ) - else [] + key: value: value.config.services.skynet."${name}".records ) nodes ); @@ -327,6 +295,14 @@ in { "ip daddr ${cfg.server.ip} udp dport 53 counter packets 0 bytes 0 accept" ]; + services.skynet.dns.records = [ + { + record = nameserver; + r_type = "A"; + value = config.services.skynet.host.ip; + } + ]; + services.bind.zones = lib.attrsets.mergeAttrsList ( # uses teh domains lsited in teh records (lib.lists.forEach domains (domain: (create_entry_zone domain))) From c5c44acc8bd1cdfedf1d09067438d072e97d127f Mon Sep 17 00:00:00 2001 From: Brendan Golden Date: Wed, 17 Jul 2024 04:20:48 +0100 Subject: [PATCH 12/12] fmt: prepping for #80 --- applications/email.nix | 190 +++++++++++++++++++++-------------------- 1 file changed, 98 insertions(+), 92 deletions(-) diff --git a/applications/email.nix b/applications/email.nix index e988b0d..8b74703 100644 --- a/applications/email.nix +++ b/applications/email.nix @@ -267,103 +267,109 @@ in { }; # set up dns record for it - services.skynet.dns.records = [ - # core record - { - record = "@"; - r_type = "MX"; - # the number is the priority in teh case of multiple mailservers - value = "10 mail.${cfg.domain}."; - } + services.skynet.dns.records = + [ + # core record + { + record = "@"; + r_type = "MX"; + # the number is the priority in teh case of multiple mailservers + value = "10 mail.${cfg.domain}."; + } - # basic one - { - record = "mail"; - r_type = "A"; - value = config.services.skynet.host.ip; - } - #DNS config for K-9 Mail - { - record = "imap"; - r_type = "CNAME"; - value = "mail"; - } - { - record = "pop3"; - r_type = "CNAME"; - value = "mail"; - } - { - record = "smtp"; - r_type = "CNAME"; - value = "mail"; - } + # basic one + { + record = "mail"; + r_type = "A"; + value = config.services.skynet.host.ip; + } + #DNS config for K-9 Mail + { + record = "imap"; + r_type = "CNAME"; + value = "mail"; + } + { + record = "pop3"; + r_type = "CNAME"; + value = "mail"; + } + { + record = "smtp"; + r_type = "CNAME"; + value = "mail"; + } - # TXT records, all tehse are inside escaped strings to allow using "" + # TXT records, all tehse are inside escaped strings to allow using "" + + # reverse pointer + { + record = config.services.skynet.host.ip; + r_type = "PTR"; + value = "${cfg.sub}.${cfg.domain}."; + } + + # SRV records to help gmail on android etc find the correct mail.skynet.ie domain for config rather than just defaulting to skynet.ie + # https://serverfault.com/questions/935192/how-to-setup-auto-configure-email-for-android-mail-app-on-your-server/1018406#1018406 + # response should be: + # _imap._tcp SRV 0 1 143 imap.example.com. + { + record = "_imaps._tcp"; + r_type = "SRV"; + value = "0 1 993 ${cfg.sub}.${cfg.domain}."; + } + { + record = "_imap._tcp"; + r_type = "SRV"; + value = "0 1 143 ${cfg.sub}.${cfg.domain}."; + } + { + record = "_submissions._tcp"; + r_type = "SRV"; + value = "0 1 465 ${cfg.sub}.${cfg.domain}."; + } + { + record = "_submission._tcp"; + r_type = "SRV"; + value = "0 1 587 ${cfg.sub}.${cfg.domain}."; + } + ] # SPF record - { - record = "${cfg.domain}."; - r_type = "TXT"; - value = ''"v=spf1 a:${cfg.sub}.${cfg.domain} ip4:${config.services.skynet.host.ip} -all"''; - } - + ++ [ + { + record = "${cfg.domain}."; + r_type = "TXT"; + value = ''"v=spf1 a:${cfg.sub}.${cfg.domain} ip4:${config.services.skynet.host.ip} -all"''; + } + ] # DKIM keys - { - record = "mail._domainkey.skynet.ie."; - r_type = "TXT"; - value = ''"v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxju1Ie60BdHwyFVPNQKovL/cX9IFPzBKgjnHZf+WBzDCFKSBpf7NvnfXajtFDQN0poaN/Qfifid+V55ZCNDBn8Y3qZa4Y69iNiLw2DdvYf0HdnxX6+pLpbmj7tikGGLJ62xnhkJhoELnz5gCOhpyoiv0tSQVaJpaGZmoll861/QIDAQAB"''; - } - { - record = "mail._domainkey.ulcompsoc.ie."; - r_type = "TXT"; - value = ''"v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDl8ptSASx37t5sfmU2d2Y6yi9AVrsNFBZDmJ2uaLa4NuvAjxGQCw4wx+1Jui/HOuKYLpntLsjN851wgPR+3i51g4OblqBDvcHn9NYgWRZfHj9AASANQjdsaAbkXuyKuO46hZqeWlpESAcD6a4Evam4fkm+kiZC0+rccb4cWgsuLwIDAQAB"''; - } - + ++ [ + { + record = "mail._domainkey.skynet.ie."; + r_type = "TXT"; + value = ''"v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCxju1Ie60BdHwyFVPNQKovL/cX9IFPzBKgjnHZf+WBzDCFKSBpf7NvnfXajtFDQN0poaN/Qfifid+V55ZCNDBn8Y3qZa4Y69iNiLw2DdvYf0HdnxX6+pLpbmj7tikGGLJ62xnhkJhoELnz5gCOhpyoiv0tSQVaJpaGZmoll861/QIDAQAB"''; + } + { + domain = "ulcompsoc.ie"; + record = "mail._domainkey.ulcompsoc.ie."; + r_type = "TXT"; + value = ''"v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDl8ptSASx37t5sfmU2d2Y6yi9AVrsNFBZDmJ2uaLa4NuvAjxGQCw4wx+1Jui/HOuKYLpntLsjN851wgPR+3i51g4OblqBDvcHn9NYgWRZfHj9AASANQjdsaAbkXuyKuO46hZqeWlpESAcD6a4Evam4fkm+kiZC0+rccb4cWgsuLwIDAQAB"''; + } + ] # DMARC - { - record = "_dmarc.${cfg.domain}."; - r_type = "TXT"; - # p : quarantine => sends to spam, reject => never sent - # rua : mail that receives reports about DMARC activity - # pct : percentage of unathenticated messages that DMARC stops - # adkim : alignment policy for DKIM, s => Strict, subdomains arent allowed, r => relaxed, subdomains allowed - # aspf : alignment policy for SPF, s => Strict, subdomains arent allowed, r => relaxed, subdomains allowed - # sp : DMARC policy for subdomains, none => no action, reports to rua, quarantine => spam, reject => never sent - value = ''"v=DMARC1; p=quarantine; rua=mailto:mailman@skynet.ie; pct=100; adkim=s; aspf=s; sp=quarantine"''; - } - - # reverse pointer - { - record = config.services.skynet.host.ip; - r_type = "PTR"; - value = "${cfg.sub}.${cfg.domain}."; - } - - # SRV records to help gmail on android etc find the correct mail.skynet.ie domain for config rather than just defaulting to skynet.ie - # https://serverfault.com/questions/935192/how-to-setup-auto-configure-email-for-android-mail-app-on-your-server/1018406#1018406 - # response should be: - # _imap._tcp SRV 0 1 143 imap.example.com. - { - record = "_imaps._tcp"; - r_type = "SRV"; - value = "0 1 993 ${cfg.sub}.${cfg.domain}."; - } - { - record = "_imap._tcp"; - r_type = "SRV"; - value = "0 1 143 ${cfg.sub}.${cfg.domain}."; - } - { - record = "_submissions._tcp"; - r_type = "SRV"; - value = "0 1 465 ${cfg.sub}.${cfg.domain}."; - } - { - record = "_submission._tcp"; - r_type = "SRV"; - value = "0 1 587 ${cfg.sub}.${cfg.domain}."; - } - ]; + ++ [ + { + record = "_dmarc.${cfg.domain}."; + r_type = "TXT"; + # p : quarantine => sends to spam, reject => never sent + # rua : mail that receives reports about DMARC activity + # pct : percentage of unathenticated messages that DMARC stops + # adkim : alignment policy for DKIM, s => Strict, subdomains arent allowed, r => relaxed, subdomains allowed + # aspf : alignment policy for SPF, s => Strict, subdomains arent allowed, r => relaxed, subdomains allowed + # sp : DMARC policy for subdomains, none => no action, reports to rua, quarantine => spam, reject => never sent + value = ''"v=DMARC1; p=quarantine; rua=mailto:mailman@skynet.ie; pct=100; adkim=s; aspf=s; sp=quarantine"''; + } + ]; #https://nixos-mailserver.readthedocs.io/en/latest/add-roundcube.html users.groups.nginx = {};