diff --git a/.sops.yaml b/.sops.yaml index 539f2db..b7205e4 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -79,3 +79,9 @@ creation_rules: - *admin_cow - *host_framework16 path_regex: secrets/aerc-accounts.raw$ +- key_groups: + - age: + - *admin_cow + - *host_highlandcow + - *host_vps3 + path_regex: secrets/dnssec.yaml$ diff --git a/flake.lock b/flake.lock index 0ea8b95..d78608b 100644 --- a/flake.lock +++ b/flake.lock @@ -1211,11 +1211,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1776169885, - "narHash": "sha256-l/iNYDZ4bGOAFQY2q8y5OAfBBtrDAaPuRQqWaFHVRXM=", + "lastModified": 1776877367, + "narHash": "sha256-EHq1/OX139R1RvBzOJ0aMRT3xnWyqtHBRUBuO1gFzjI=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "4bd9165a9165d7b5e33ae57f3eecbcb28fb231c9", + "rev": "0726a0ecb6d4e08f6adced58726b95db924cef57", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 48ce54b..cb23fdc 100644 --- a/flake.nix +++ b/flake.nix @@ -117,28 +117,13 @@ imports = [ ./hosts inputs.nix-topology.flakeModule + ./flake ]; flake = { overlays = { colmena = inputs.colmena.overlay; }; - nixosConfigurations.iso = inputs.nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - modules = [ - ( - { pkgs, modulesPath, ... }: - { - imports = [ (modulesPath + "/installer/cd-dvd/installation-cd-minimal.nix") ]; - systemd.services.sshd.wantedBy = pkgs.lib.mkForce [ "multi-user.target" ]; - users.users.root.openssh.authorizedKeys.keys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMOOCOWlEwmemgf5+tKkdQm5J/HApiywXkaiSwG97r1O" - ]; - } - ) - ]; - }; - nixosModules = { }; }; @@ -152,108 +137,11 @@ ... }: { - packages.internalZonefile = - let - myHosts = ( - builtins.mapAttrs ( - n: f: - ( - let - interfaces = lib.filter (x: !lib.hasInfix "*" x) ( - builtins.attrNames f.config.networking.interfaces - ); - hostName = f.config.networking.hostName; - in - (lib.mkIf (interfaces != [ ]) ( - let - k = ( - lib.findFirst ( - interface: - ( - ((builtins.length f.config.networking.interfaces.${interface}.ipv4.addresses) > 0) - || ((builtins.length f.config.networking.interfaces.${interface}.ipv6.addresses) > 0) - ) - ) null interfaces - ); - v4A = - if k != null && ((builtins.length f.config.networking.interfaces.${k}.ipv4.addresses) > 0) then - (builtins.elemAt (f.config.networking.interfaces.${k}.ipv4.addresses) 0).address - else - null; - v6A = - if k != null && ((builtins.length f.config.networking.interfaces.${k}.ipv6.addresses) > 0) then - (builtins.elemAt (f.config.networking.interfaces.${k}.ipv6.addresses) 0).address - else - null; - - in - (inputs.dns.lib.combinators.host v4A v6A) - // { - subdomains = { - "*" = inputs.dns.lib.combinators.host v4A v6A; - }; - } - )) - ) - - ) inputs.self.nixosConfigurations - ); - in - (pkgs.writeTextFile { - name = "internal.zone"; - text = ( - inputs.dns.lib.toString "internal" ( - (import ./zones/internal.nix { - inherit (inputs) dns; - subdomains = myHosts; - }) - ) - ); - }); - topology = { modules = [ ./topology.nix ]; }; - devShells.default = pkgs.mkShellNoCC { - buildInputs = [ - inputs'.colmena.packages.colmena - pkgs.sops - pkgs.age - pkgs.ssh-to-age - (pkgs.python3.withPackages ( - python-pkgs: with python-pkgs; [ - cryptography - pyyaml - (buildPythonPackage rec { - name = "pyrage"; - version = "1.3.0"; - src = fetchPypi { - inherit version; - pname = name; - sha256 = "sha256-soOi49aIy/aMcH9X2T/aszBP9Xx+LmtxDAtLyQlq2do="; - }; - - cargoDeps = pkgs.rustPlatform.fetchCargoVendor { - inherit src; - hash = "sha256-/dpxp+m/QakSxIP8t2dOtUK4Irac9C+ow5Jq1FlSTZE="; - }; - - nativeBuildInputs = with pkgs.rustPlatform; [ - cargoSetupHook - maturinBuildHook - ]; - - pyproject = true; - build-system = [ - pkgs.maturin - ]; - }) - ] - )) - ]; - }; }; }; diff --git a/flake/default.nix b/flake/default.nix new file mode 100644 index 0000000..d7c0e88 --- /dev/null +++ b/flake/default.nix @@ -0,0 +1,8 @@ +{ ... }: +{ + imports = [ + ./iso.nix + ./shell.nix + ./zonefiles.nix + ]; +} diff --git a/flake/iso.nix b/flake/iso.nix new file mode 100644 index 0000000..a57343f --- /dev/null +++ b/flake/iso.nix @@ -0,0 +1,20 @@ +{ inputs, ... }: +{ + flake = { + nixosConfigurations.iso = inputs.nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + ( + { pkgs, modulesPath, ... }: + { + imports = [ (modulesPath + "/installer/cd-dvd/installation-cd-minimal.nix") ]; + systemd.services.sshd.wantedBy = pkgs.lib.mkForce [ "multi-user.target" ]; + users.users.root.openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMOOCOWlEwmemgf5+tKkdQm5J/HApiywXkaiSwG97r1O" + ]; + } + ) + ]; + }; + }; +} diff --git a/flake/shell.nix b/flake/shell.nix new file mode 100644 index 0000000..a801104 --- /dev/null +++ b/flake/shell.nix @@ -0,0 +1,74 @@ +{ inputs, ... }: +{ + perSystem = + { + self', + pkgs, + inputs', + system, + lib, + ... + }: + { + packages.dnst = pkgs.rustPlatform.buildRustPackage (finalAttrs: { + name = "dnst"; + + src = pkgs.fetchFromGitHub { + owner = "NLnetLabs"; + repo = "dnst"; + rev = "737a020d55f91c3f9896783c9611ea43ef7d98d1"; + hash = "sha256-kxW4LsZh/ffsU0J0C+KTv9EJgkWZsMOWHPFCkrnDyPU="; + }; + + cargoHash = "sha256-jaqv9TVe7R6kPAIcGLxitrLrob1opI1wwL9FzMH66Bg="; + buildInputs = [ + pkgs.openssl + ]; + nativeBuildInputs = [ + pkgs.pkg-config + ]; + + PKG_CONFIG_PATH = "${pkgs.openssl.dev}/lib/pkgconfig"; + }); + + devShells.default = pkgs.mkShellNoCC { + buildInputs = [ + inputs'.colmena.packages.colmena + self'.packages.dnst + pkgs.sops + pkgs.age + pkgs.ssh-to-age + (pkgs.python3.withPackages ( + python-pkgs: with python-pkgs; [ + cryptography + pyyaml + (buildPythonPackage rec { + name = "pyrage"; + version = "1.3.0"; + src = fetchPypi { + inherit version; + pname = name; + sha256 = "sha256-soOi49aIy/aMcH9X2T/aszBP9Xx+LmtxDAtLyQlq2do="; + }; + + cargoDeps = pkgs.rustPlatform.fetchCargoVendor { + inherit src; + hash = "sha256-/dpxp+m/QakSxIP8t2dOtUK4Irac9C+ow5Jq1FlSTZE="; + }; + + nativeBuildInputs = with pkgs.rustPlatform; [ + cargoSetupHook + maturinBuildHook + ]; + + pyproject = true; + build-system = [ + pkgs.maturin + ]; + }) + ] + )) + ]; + }; + }; +} diff --git a/flake/zonefiles.nix b/flake/zonefiles.nix new file mode 100644 index 0000000..fdc47b5 --- /dev/null +++ b/flake/zonefiles.nix @@ -0,0 +1,105 @@ +{ inputs, ... }: +{ + perSystem = + { + self', + pkgs, + inputs', + system, + lib, + ... + }: + { + + packages = + let + ips = { + vps2.v4 = "40.160.241.166"; + vps2.v6 = "2604:2dc0:309::4:0:c"; + vps3.v4 = "15.204.57.157"; + vps3.v6 = "2604:2dc0:202:300::250"; + highlandcow.v4 = "94.72.121.33"; + highlandcow.v6 = "2605:a141:2311:5499::1"; + home1.v4 = "50.191.146.97"; + home1.v6 = "2603:3004:115:8300::97"; + mtvps.v4 = "15.204.249.146"; + mtvps.v6 = "2604:2dc0:101:200::51ee"; + }; + in + { + cow_computerZonefile = ( + pkgs.writeTextFile { + name = "cow.computer.zone"; + text = ( + inputs.dns.lib.toString "cow.computer" ( + (import ../zones/cow.computer.nix { + inherit (inputs) dns; + inherit ips; + }) + ) + ); + } + ); + + internalZonefile = + let + myHosts = ( + builtins.mapAttrs ( + n: f: + ( + let + interfaces = lib.filter (x: !lib.hasInfix "*" x) ( + builtins.attrNames f.config.networking.interfaces + ); + hostName = f.config.networking.hostName; + in + (lib.mkIf (interfaces != [ ]) ( + let + k = ( + lib.findFirst ( + interface: + ( + ((builtins.length f.config.networking.interfaces.${interface}.ipv4.addresses) > 0) + || ((builtins.length f.config.networking.interfaces.${interface}.ipv6.addresses) > 0) + ) + ) null interfaces + ); + v4A = + if k != null && ((builtins.length f.config.networking.interfaces.${k}.ipv4.addresses) > 0) then + (builtins.elemAt (f.config.networking.interfaces.${k}.ipv4.addresses) 0).address + else + null; + v6A = + if k != null && ((builtins.length f.config.networking.interfaces.${k}.ipv6.addresses) > 0) then + (builtins.elemAt (f.config.networking.interfaces.${k}.ipv6.addresses) 0).address + else + null; + + in + (inputs.dns.lib.combinators.host v4A v6A) + // { + subdomains = { + "*" = inputs.dns.lib.combinators.host v4A v6A; + }; + } + )) + ) + + ) inputs.self.nixosConfigurations + ); + in + (pkgs.writeTextFile { + name = "internal.zone"; + text = ( + inputs.dns.lib.toString "internal" ( + (import ../zones/internal.nix { + inherit (inputs) dns; + subdomains = myHosts; + }) + ) + ); + }); + }; + + }; +} diff --git a/hosts/angus/default.nix b/hosts/angus/default.nix index 4cac08a..01e8357 100644 --- a/hosts/angus/default.nix +++ b/hosts/angus/default.nix @@ -144,6 +144,7 @@ networking.useDHCP = false; nix.distributedBuilds = true; + nix.nixPath = [ "nixpkgs=${inputs.nixpkgs}" ]; services.tailscale.enable = true; diff --git a/hosts/highlandcow/default.nix b/hosts/highlandcow/default.nix index 3fb5a1d..a2df0ed 100644 --- a/hosts/highlandcow/default.nix +++ b/hosts/highlandcow/default.nix @@ -20,6 +20,7 @@ tags = [ "server" "cloud-server" + "dns" ]; privilegeEscalationCommand = [ "sudo" @@ -78,6 +79,8 @@ hardware.facter.reportPath = ./facter.json; networking.hostName = "highlandcow"; + l.dns-server.enable = true; + boot.loader.grub = { efiSupport = true; efiInstallAsRemovable = true; diff --git a/hosts/vps3/default.nix b/hosts/vps3/default.nix index c65490b..6efc528 100644 --- a/hosts/vps3/default.nix +++ b/hosts/vps3/default.nix @@ -19,6 +19,7 @@ tags = [ "server" "cloud-server" + "dns" ]; privilegeEscalationCommand = [ "sudo" @@ -26,6 +27,9 @@ ]; }; + virtualisation.docker.enable = true; + users.users.user.extraGroups = [ "docker" ]; + boot.loader.grub = { efiSupport = true; efiInstallAsRemovable = true; @@ -55,6 +59,8 @@ "149.112.112.112" ]; + l.dns-server.enable = true; + networking.useDHCP = true; system.stateVersion = "25.11"; } diff --git a/modules/default.nix b/modules/default.nix index af81be8..bc7f892 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -16,5 +16,6 @@ ./tailscale.nix ./senpai.nix ./aerc.nix + ./dns-server.nix ]; } diff --git a/modules/dns-server.nix b/modules/dns-server.nix new file mode 100644 index 0000000..3f3cafb --- /dev/null +++ b/modules/dns-server.nix @@ -0,0 +1,117 @@ +{ + lib, + config, + inputs, + pkgs, + ... +}: + +let + cfg = config.l.dns-server; + + dnst = inputs.self.packages.${pkgs.system}.dnst; + + domains = [ + "cow.computer" + ]; + + sopsSecrets = lib.mergeAttrsList ( + lib.forEach domains ( + name: + let + name2 = builtins.replaceStrings [ "." ] [ "_" ] name; + in + { + sops.secrets = lib.mergeAttrsList ( + map + (a: { + "${name2}-${a}" = { + sopsFile = ../secrets/dnssec.yaml; + key = "${name2}/${a}"; + }; + }) + [ + "ds" + "zsk_private" + "zsk_key" + "zsk_filename" + "ksk_private" + "ksk_key" + "ksk_filename" + ] + ); + } + ) + ); + nsdConfig = lib.concatStringsSep "\n" ( + lib.forEach domains (name: '' + zone: + name: "${name}" + zonefile: "/var/lib/nsd/zones/${name}.zone" + '') + ); +in +{ + options.l.dns-server.enable = lib.mkEnableOption "nsd authoritative dns server"; + config = lib.mkIf cfg.enable ( + { + networking.firewall.allowedTCPPorts = [ 53 ]; + networking.firewall.allowedUDPPorts = [ 53 ]; + + systemd.services.nsd.serviceConfig.ExecStartPre = "${pkgs.writeShellScript "nsd-dnssec" '' + tmpdir=$(mktemp -d) + cd "$tmpdir" + + mkdir -p /var/lib/nsd/zones/ + + ${lib.concatStringsSep "\n" ( + lib.forEach domains ( + name: + let + name2 = builtins.replaceStrings [ "." ] [ "_" ] name; + in + '' + fname=$(cat ${config.sops.secrets."${name2}-zsk_filename".path}) + cp ${config.sops.secrets."${name2}-zsk_private".path} "$fname".private + cp ${config.sops.secrets."${name2}-zsk_key".path} "$fname".key + fname_ksk=$(cat ${config.sops.secrets."${name2}-ksk_filename".path}) + cp ${config.sops.secrets."${name2}-ksk_private".path} "$fname_ksk".private + cp ${config.sops.secrets."${name2}-ksk_key".path} "$fname_ksk".key + + ${lib.getExe dnst} signzone -f - -o ${name} ${ + inputs.self.packages.${pkgs.system}."${name2}Zonefile" + } $fname $fname_ksk > /var/lib/nsd/zones/${name}.zone + '' + ) + )} + + chown -R nsd:nsd /var/lib/nsd/zones/ + cd /tmp + rm -r "$tmpdir" + ''}"; + services.nsd = { + enable = true; + interfaces = [ + "::" + "0.0.0.0" + ]; + remoteControl = { + enable = true; + interfaces = [ "/var/run/nsd.sock" ]; + }; + + zones."nonexistent.".data = '' + nonexistent. 3600 IN SOA ns1.nonexistent. admin.nonexistent. ( + 0000000000 + 1800 + 3600 + 86400 + 3600) + ''; + + extraConfig = nsdConfig; + }; + } + // sopsSecrets + ); +} diff --git a/secrets/dnssec.yaml b/secrets/dnssec.yaml new file mode 100644 index 0000000..58b96a3 --- /dev/null +++ b/secrets/dnssec.yaml @@ -0,0 +1,41 @@ +cow_computer: + ds: ENC[AES256_GCM,data:weLqYmt7xTTEy9VwyWla+x2a4aYhqhuGsLvJB/NVTNU/u3wmMmaVEBJcBPfz3aXsNA3KGMFTBgDbH8cx4y3LrNLQZaBli2rjx7WcCE18A2VkONH+M9fO3veryiGgz3SnRe8apbSufDKZzCi4fV5twowXIKLNme2uLm9OWwjgHg==,iv:XPqPC3n3XImXj5HJrhKAZeeJRinR9h4fHWwzUATL1fw=,tag:7Vmd2y32ndbf6gJGBqaSDQ==,type:str] + zsk_filename: ENC[AES256_GCM,data:on/+/yxGuCd5hgSOsRw1wqZIRh8Nt4i6,iv:7ueoNgQ6h80saFTRnwgOGifHpTJnhVw7SwBL//PsvLc=,tag:HT1IPXqLGPXlovxcvMwObQ==,type:str] + zsk_private: ENC[AES256_GCM,data:2w0pOEtGQojeBpTCWaXe54x2EnEPLywFsahO0DmmugQ9nVxtrE5SwE1eUXegSOJacwMHW+YHbqB3435318amtwTtHiXGY8XI3u4h0d+wCOclF2dE3oPd+5gSfrEcgtiI7DOakQyOrxGEdTYdeRhvzfBJ98Q6CFugI/uK6+0SO3vixS7ZVho=,iv:rYnia8OFuk/4x7XZoXnyluBQV2gI6A1mXiFomAf5sjg=,tag:SWEYHLaMO8Pp+kwTFLNnVQ==,type:str] + zsk_key: ENC[AES256_GCM,data:5AtTWiXtZOTIXiKpPESzkBhIjPHS3l4Xc9Fu/DD5LXrHltyDDgiSLFiRVUUYaVHR6Pn0WEKJO/XZCaFm9eYGlcKpu4+0n54m2QtXvws6wEQQDurK3N2N4J97qboYyxWIyyK1bL/yUQ+DoQQm6xUfA+B1Uq6omjcRFJHH1bm2pLuNaIQewPfPRVZo/qd2NCOPybbu5tpTWyjoNsIuU0+VvDem,iv:GO1mqIaHjW/lJMKqTZlMYFLXpLtfn44Jkt2eSrtJobM=,tag:IeWzGQEEaEvUlNgO3SsNMw==,type:str] + ksk_filename: ENC[AES256_GCM,data:ZDI8enqkkCR6qHN3jCMKB8BFbLnj/tMa,iv:LLoRihWTYVP0/1d0LtX5zmsuQAVtZCn+sKSt2kcDVFs=,tag:qMiAzLwdcajvBGgdyTfdMA==,type:str] + ksk_private: ENC[AES256_GCM,data:NWezoQWUcWMLpJawu+mc78bnJ8hDZYs7CmjYublnVryskMe4PC5YrqTG/ilv1AuB8R/hJ0tTYvFTx8VobxkhReYoPsbGG9KQUIJi7iNWZYDLfeTGURU5fsTVUvRlPhpC4yBOtqQLWkcumga92W3TcGUGkXiVSZVkT33rj79ckCSL65pnISM=,iv:mHKwtSUj+JPZgzs5BeRhiEQzoLgLb6ncqk7UCFcZeKA=,tag:mYf+oMsop73otjAf/swcmg==,type:str] + ksk_key: ENC[AES256_GCM,data:L5CqiFMBH4LKGiyDeoNs/s3UlmJqvi4j604DFoRz/FGH1SAphh5RT4qhOv6X+GTDxYQn8QW9dngMUT2XgxUOZyLdmOYYQw1hBjLpKPNub8n5exhSPa3m3MoxUD+TiUPQL/ZuNQf00whWOux6qWVI3/JKLFJQZtHv5eo+B53rpSBhoDRJ0okbDLQrbyMbcodskPiLQAERWAt5OL53DRa1R5BB,iv:S0I5lvVrPqk8S/BDhYctjHF3rm5XSAMLeugW9FncO4U=,tag:jEoBthYvY11Z7hWD9SAo6A==,type:str] +sops: + age: + - recipient: age1ns8t9fgkrzg7htv7x25gam3gqpjathlk5p5zr6k4cas27y0c8ypqntq8c3 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5cjJKVko5RkQ1eUpmOWxq + Qzk2Mzc0aVFicmVKWTZrWXVvd3BUUFR1UW1FCllkSVMweC93eHMwSzV1UVdFaGRI + azBYK3U0cklnbFk3TzJlREJUUXQ1bnMKLS0tIFBra2NFL0U4dXRlWTkzNytEZk5C + blAzeG16M25jRXlmcTZZN0c5Ykk4V2sKH21nevlEMfrZw+st2zctIfKON3HEfH50 + NK372M34j17baeuAaIzIjQsHW4ttbwlOZjzVVnZ9iQO8Fm0Ve6Velw== + -----END AGE ENCRYPTED FILE----- + - recipient: age14gc722cqkmlvm8xg2mmxpypzp88yg6077ndlzearcdhcnqyzav9qs5j2s8 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6WXd1RTQ5YS9vNEVJN3FF + aEVTWEN6NmhyaTZjNWpWaklyV01mcWhXR0dVCko0YktzaXU4MldqNk5FbXpGS2VS + RXVvS05IeEQ5dmdWWm5JdnkvdzhhNTAKLS0tIFdRVG9valY0N2NzenBYclhFajk2 + MEtIV1FPYU9PeTVNeENuQ3pDaWd4THcKLbQiCNjZdDeqe9RY+8WxKsQpCy2B8X6o + xAltXvip07ZoOaYYh86zPPTR096rK0PKDBMynwH5EerJP8ij/LcjpQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age1tdkra3v6kcutcdg4nm8039v6en4u9535kcgkuhd39a7s9uv6gf0svtp02a + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzaVh2QzZvbkpzTkYxcFZo + MlVyN2k0dkt3K1hZaGs1SkgrcHFzLzVkOWtjClBGQ3NJMEJqR3JPQTk0elFhdXhs + b21OSTd0MmRwQlgySmtqNzdBdDZ2QTQKLS0tIFNEMTBkNFQ4WGNmS0w3dGFaajJ1 + NG9YZlUxWG1laGdUb3pCL0JhYmY5SU0K66B8lNdrxUNYUe3Hk5PUG9oimjBdCUpt + FnqqOxqMUoNJ4xth1u4RCwYEI0+YncE3+AYWhUzLhB7UelEQcpUp6Q== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-04-25T21:25:34Z" + mac: ENC[AES256_GCM,data:DYQss0zmegppOlcjPstLCYMVi/hdBtpPPk45uQBdW3IOVRu7acOGDri8Ce5NVHyYuo2bFPfcru+SeUUuCAoZuzlv8dUB0jNQ2POBSnWKYShOlFUMDolbcRZnSld1AXq1U0ReFZ3OpCxlCyA+GQ1KsHLsJ1EFmBkjbSDz9DROfxo=,iv:Rgn4mB90Sx1DakZJY+z6vnFG7WFtIAB4rDi4rlduf+0=,tag:wlNKSsz1oFmK8vXvV8eh0A==,type:str] + unencrypted_suffix: _unencrypted + version: 3.12.2 diff --git a/zones/cow.computer.nix b/zones/cow.computer.nix index 1ff1637..7dab43f 100644 --- a/zones/cow.computer.nix +++ b/zones/cow.computer.nix @@ -1,20 +1,64 @@ -{ dns, subdomains, ... }: +{ dns, ips, ... }: with dns.lib.combinators; { SOA = { adminEmail = "cow@cowingtonpost.com"; - serial = 2026040200; + serial = 2026042500; nameServer = "ns1.cow.computer."; }; + TTL = 3600; + NS = [ "ns1.cow.computer." "ns2.cow.computer." ]; + A = [ + (a ips.home1.v4) + ]; + AAAA = [ + (aaaa ips.home1.v6) + ]; + + TXT = [ + "hosted-email-verify=tpnmsuj7" + "v=spf1 include:spf.migadu.com -all" + ]; + + MX = [ + (mx.mx 10 "aspmx1.migadu.com.") + (mx.mx 20 "aspmx2.migadu.com.") + ]; + subdomains = { ns1 = host "94.72.121.33" "2605:a141:2311:5499:0000:0000:0000:0001"; - ns2 = host "40.160.241.166" "2604:2dc0:309::4:0:c"; + ns2 = host "15.204.57.157" "2604:2dc0:202:300::250"; + + _domainkey.subdomains.key3.CNAME = [ (cname "key3.cow.computer._domainkey.migadu.com.") ]; + _domainkey.subdomains.key2.CNAME = [ (cname "key2.cow.computer._domainkey.migadu.com.") ]; + _domainkey.subdomains.key1.CNAME = [ (cname "key1.cow.computer._domainkey.migadu.com.") ]; + _dmarc.TXT = [ "v=DMARC1; p=quarantine;" ]; + + vps3 = host ips.vps3.v4 ips.vps3.v6; + vps2 = host ips.vps2.v4 ips.vps2.v6; + mtvps = host ips.vps2.v4 ips.vps2.v6; + ftp-home.CNAME = [ (cname "home1.cow.computer.") ]; + writeups.CNAME = [ (cname "home1.cow.computer.") ]; + soc.CNAME = [ (cname "home1.cow.computer.") ]; + meet.CNAME = [ (cname "home1.cow.computer.") ]; + tctc.CNAME = [ (cname "home1.cow.computer.") ]; + element.CNAME = [ (cname "home1.cow.computer.") ]; + irc.CNAME = [ (cname "home1.cow.computer.") ]; + git.CNAME = [ (cname "home1.cow.computer.") ]; + + matrixrtc.CNAME = [ (cname "vps2.cow.computer.") ]; + turn.CNAME = [ (cname "vps2.cow.computer.") ]; + chat.CNAME = [ (cname "vps2.cow.computer.") ]; + + node.CNAME = [ (cname "mtvps.cow.computer.") ]; + hedgedoc.CNAME = [ (cname "mtvps.cow.computer.") ]; + taiga.CNAME = [ (cname "mtvps.cow.computer.") ]; }; }