diff --git a/clan.nix b/clan.nix index bab2560..0223b45 100644 --- a/clan.nix +++ b/clan.nix @@ -4,9 +4,9 @@ meta.domain = "cnx-network.internal"; inventory.machines = { - control = {}; - ns1 = {}; - ns2 = {}; + control = { }; + ns1 = { }; + ns2 = { }; }; inventory.instances = { @@ -15,7 +15,8 @@ roles.default.tags.all = { }; roles.default.settings.allowedKeys = { "berwn" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIENAjhGQGraQoAjJzsomKP8GAmQPeGL1rNRNHgRcLqtT"; - "kurogeek" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEcZ/p1Ofa9liwIzPWzNtONhJ7+FUWd2lCz33r81t8+w kurogeek@kurogeek"; + "kurogeek" = + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEcZ/p1Ofa9liwIzPWzNtONhJ7+FUWd2lCz33r81t8+w kurogeek@kurogeek"; }; }; diff --git a/flake.nix b/flake.nix index 59c4da5..8775a14 100644 --- a/flake.nix +++ b/flake.nix @@ -28,10 +28,10 @@ # }; # overlays = []; # }; - secrets.age.plugins = [ - "age-plugin-yubikey" - "age-plugin-fido2-hmac" - ]; + secrets.age.plugins = [ + "age-plugin-yubikey" + "age-plugin-fido2-hmac" + ]; }; systems = [ diff --git a/machines/control/disko.nix b/machines/control/disko.nix index acad590..19f5c41 100644 --- a/machines/control/disko.nix +++ b/machines/control/disko.nix @@ -1,7 +1,7 @@ # --- # schema = "single-disk" # [placeholders] -# mainDisk = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_120729781" +# mainDisk = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_120729781" # --- # This file was automatically generated! # CHANGING this configuration requires wiping and reinstalling the machine diff --git a/machines/ns1/configuration.nix b/machines/ns1/configuration.nix index 23148bd..b653d96 100644 --- a/machines/ns1/configuration.nix +++ b/machines/ns1/configuration.nix @@ -70,6 +70,9 @@ in "dnssec-signing" = true; "dnssec-policy" = "cnx"; notify = [ "ns2" ]; - acl = [ "acl_ns2" "acl_acme" ]; # ns2 transfers; acme_ddns key does DNS-01 updates + acl = [ + "acl_ns2" + "acl_acme" + ]; # ns2 transfers; acme_ddns key does DNS-01 updates }) domains; } diff --git a/machines/ns1/disko.nix b/machines/ns1/disko.nix index f344d79..7ab8bc2 100644 --- a/machines/ns1/disko.nix +++ b/machines/ns1/disko.nix @@ -1,7 +1,7 @@ # --- # schema = "single-disk" # [placeholders] -# mainDisk = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_120730960" +# mainDisk = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_120730960" # --- # This file was automatically generated! # CHANGING this configuration requires wiping and reinstalling the machine diff --git a/machines/ns2/disko.nix b/machines/ns2/disko.nix index fee63c5..a70bc8b 100644 --- a/machines/ns2/disko.nix +++ b/machines/ns2/disko.nix @@ -1,7 +1,7 @@ # --- # schema = "single-disk" # [placeholders] -# mainDisk = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_120731321" +# mainDisk = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_120731321" # --- # This file was automatically generated! # CHANGING this configuration requires wiping and reinstalling the machine diff --git a/modules/dns/authoritative.nix b/modules/dns/authoritative.nix index b0cbb8b..2c95f9f 100644 --- a/modules/dns/authoritative.nix +++ b/modules/dns/authoritative.nix @@ -33,17 +33,49 @@ in # Including the key via keyFiles keeps the secret out of the Nix store. keyFiles = [ config.clan.core.vars.generators.dns-tsig.files."tsig.conf".path ]; settings = { - server.listen = [ "0.0.0.0@53" "::@53" ]; - log = [ { target = "syslog"; any = "info"; } ]; + server.listen = [ + "0.0.0.0@53" + "::@53" + ]; + log = [ + { + target = "syslog"; + any = "info"; + } + ]; remote = [ - { id = "ns1"; address = [ ns1zt ]; key = "cnx_xfr"; } - { id = "ns2"; address = [ ns2zt ]; key = "cnx_xfr"; } + { + id = "ns1"; + address = [ ns1zt ]; + key = "cnx_xfr"; + } + { + id = "ns2"; + address = [ ns2zt ]; + key = "cnx_xfr"; + } ]; acl = [ - { id = "acl_ns1"; address = [ ns1zt ]; key = "cnx_xfr"; action = [ "transfer" "notify" ]; } - { id = "acl_ns2"; address = [ ns2zt ]; key = "cnx_xfr"; action = [ "transfer" "notify" ]; } + { + id = "acl_ns1"; + address = [ ns1zt ]; + key = "cnx_xfr"; + action = [ + "transfer" + "notify" + ]; + } + { + id = "acl_ns2"; + address = [ ns2zt ]; + key = "cnx_xfr"; + action = [ + "transfer" + "notify" + ]; + } ]; }; }; diff --git a/modules/hetzner-firewall-rules.nix b/modules/hetzner-firewall-rules.nix index b157881..4fbbdad 100644 --- a/modules/hetzner-firewall-rules.nix +++ b/modules/hetzner-firewall-rules.nix @@ -4,7 +4,10 @@ # Public SSH (22) is intentionally absent: admin access rides the ZeroTier mesh # (inside UDP 9993), with emergency-access as the console fallback. let - world = [ "0.0.0.0/0" "::/0" ]; + world = [ + "0.0.0.0/0" + "::/0" + ]; zerotier = { direction = "in"; @@ -22,14 +25,29 @@ let }; dnsRules = [ - { direction = "in"; protocol = "udp"; port = "53"; source_ips = world; description = "DNS (UDP)"; } - { direction = "in"; protocol = "tcp"; port = "53"; source_ips = world; description = "DNS (TCP)"; } + { + direction = "in"; + protocol = "udp"; + port = "53"; + source_ips = world; + description = "DNS (UDP)"; + } + { + direction = "in"; + protocol = "tcp"; + port = "53"; + source_ips = world; + description = "DNS (TCP)"; + } zerotier ping ]; in { - "clan-control" = [ zerotier ping ]; + "clan-control" = [ + zerotier + ping + ]; "clan-ns1" = dnsRules; "clan-ns2" = dnsRules; } diff --git a/modules/hetzner-firewall.nix b/modules/hetzner-firewall.nix index 2a8e995..ad168de 100644 --- a/modules/hetzner-firewall.nix +++ b/modules/hetzner-firewall.nix @@ -1,4 +1,9 @@ -{ config, lib, pkgs, ... }: +{ + config, + lib, + pkgs, + ... +}: let cfg = config.cnx.hetznerFirewall; in @@ -29,8 +34,7 @@ in tokenFile = lib.mkOption { type = lib.types.path; default = config.clan.core.vars.generators.hetzner-firewall.files.token.path; - defaultText = lib.literalExpression - "config.clan.core.vars.generators.hetzner-firewall.files.token.path"; + defaultText = lib.literalExpression "config.clan.core.vars.generators.hetzner-firewall.files.token.path"; description = "File holding the Hetzner Cloud API token (Read & Write)."; }; }; @@ -48,7 +52,11 @@ in description = "Sync Hetzner Cloud firewall rules from Nix config"; after = [ "network-online.target" ]; wants = [ "network-online.target" ]; - path = [ pkgs.curl pkgs.jq pkgs.coreutils ]; + path = [ + pkgs.curl + pkgs.jq + pkgs.coreutils + ]; environment.SSL_CERT_FILE = "/etc/ssl/certs/ca-certificates.crt"; serviceConfig = { Type = "oneshot"; @@ -71,20 +79,22 @@ in curl -fsS -H @"$hdr" -H "Content-Type: application/json" "$@" } - ${lib.concatStringsSep "\n" (lib.mapAttrsToList (fwName: rules: '' - name=${lib.escapeShellArg fwName} - rules=${lib.escapeShellArg (builtins.toJSON rules)} - id="$(hapi "$api/firewalls?name=$name" | jq -r '.firewalls[0].id // empty')" - if [ -z "$id" ]; then - echo "hetzner-firewall: creating $name" - jq -n --arg name "$name" --argjson rules "$rules" '{name: $name, rules: $rules}' \ - | hapi -X POST --data-binary @- "$api/firewalls" > /dev/null - else - echo "hetzner-firewall: setting rules on $name (id $id)" - jq -n --argjson rules "$rules" '{rules: $rules}' \ - | hapi -X POST --data-binary @- "$api/firewalls/$id/actions/set_rules" > /dev/null - fi - '') cfg.firewalls)} + ${lib.concatStringsSep "\n" ( + lib.mapAttrsToList (fwName: rules: '' + name=${lib.escapeShellArg fwName} + rules=${lib.escapeShellArg (builtins.toJSON rules)} + id="$(hapi "$api/firewalls?name=$name" | jq -r '.firewalls[0].id // empty')" + if [ -z "$id" ]; then + echo "hetzner-firewall: creating $name" + jq -n --arg name "$name" --argjson rules "$rules" '{name: $name, rules: $rules}' \ + | hapi -X POST --data-binary @- "$api/firewalls" > /dev/null + else + echo "hetzner-firewall: setting rules on $name (id $id)" + jq -n --argjson rules "$rules" '{rules: $rules}' \ + | hapi -X POST --data-binary @- "$api/firewalls/$id/actions/set_rules" > /dev/null + fi + '') cfg.firewalls + )} ''; };