From 0a6085cb49ebfb3f7db40a3fc1863c47e0d0cc85 Mon Sep 17 00:00:00 2001 From: kat Date: Sun, 18 Sep 2022 10:09:32 -0700 Subject: [PATCH] feat: abstractions rework --- hardware/local.nix | 10 + hardware/manual.nix | 12 + hardware/oracle/common.nix | 47 ++- home/shell/ssh.nix | 3 +- meta.nix | 56 ++-- modules/home/network.nix | 77 ----- modules/meta/network.nix | 1 + modules/nixos/firewall.nix | 82 ------ modules/nixos/network.nix | 257 ---------------- modules/nixos/yggdrasil.nix | 145 --------- nixos/base/network.nix | 9 - nixos/base/ssh.nix | 22 +- nixos/network.nix | 410 ++++++++++++++++++++------ nixos/systems/chen.nix | 20 +- nixos/systems/daiyousei.nix | 6 - nixos/systems/koishi.nix | 90 ++---- nixos/systems/marisa.nix | 45 +-- nixos/systems/ran.nix | 34 +-- nixos/systems/rinnosuke.nix | 8 - nixos/systems/tewi/home-assistant.nix | 119 ++++++-- nixos/systems/tewi/mosquitto.nix | 7 + nixos/systems/tewi/nginx.nix | 32 +- nixos/systems/tewi/nixos.nix | 30 +- nixos/systems/tewi/zigbee2mqtt.nix | 54 ++-- nixos/systems/yukari.nix | 23 +- outputs.nix | 1 - services/access.nix | 129 ++++---- services/ha.nix | 3 +- services/irlmail.nix | 8 +- services/kattv-ingest.nix | 2 +- services/kattv2-ingest.nix | 2 +- services/keycloak.nix | 11 +- services/knot/default.nix | 8 +- services/knot/knot.yaml | 12 +- services/murmur.nix | 36 +-- services/nextcloud.nix | 52 ++-- services/nfs.nix | 5 +- services/nginx.nix | 12 +- services/openldap/default.nix | 2 +- services/plex.nix | 27 +- services/prosody.nix | 62 ++-- services/syncplay.nix | 8 +- services/tvheadend.nix | 15 +- services/website.nix | 2 - services/znc.nix | 3 +- targets/home.nix | 14 +- tf | 2 +- tf.nix | 2 +- 48 files changed, 798 insertions(+), 1219 deletions(-) create mode 100644 hardware/local.nix create mode 100644 hardware/manual.nix delete mode 100644 modules/home/network.nix delete mode 100644 modules/nixos/firewall.nix delete mode 100644 modules/nixos/network.nix delete mode 100644 modules/nixos/yggdrasil.nix diff --git a/hardware/local.nix b/hardware/local.nix new file mode 100644 index 00000000..bd57271b --- /dev/null +++ b/hardware/local.nix @@ -0,0 +1,10 @@ +{ config, lib, ... }: { + deploy.tf.resources.${config.networking.hostName} = { + provider = "null"; + type = "resource"; + connection = { + port = lib.head config.services.openssh.ports; + host = config.networks.gensokyo.ipv4 or config.networks.chitei.ipv4; + }; + }; +} diff --git a/hardware/manual.nix b/hardware/manual.nix new file mode 100644 index 00000000..b16ea784 --- /dev/null +++ b/hardware/manual.nix @@ -0,0 +1,12 @@ +{ config, lib, ... }: { + deploy.tf = { + resources.${config.networking.hostName} = { + provider = "null"; + type = "resource"; + connection = { + port = lib.head config.services.openssh.ports; + host = config.networks.internet.ipv4; + }; + }; + }; +} diff --git a/hardware/oracle/common.nix b/hardware/oracle/common.nix index f5c1bdb0..8ee8352f 100644 --- a/hardware/oracle/common.nix +++ b/hardware/oracle/common.nix @@ -68,8 +68,8 @@ in ${interface} = { useDHCP = true; ipv6 = { - addresses = lib.mkIf (config.network.addresses.public.nixos.ipv6.enable) [{ - address = config.network.addresses.public.nixos.ipv6.address; + addresses = lib.mkIf (config.networks.internet.ipv6_defined) [{ + address = config.networks.internet.ipv6; prefixLength = 64; }]; routes = [{ @@ -80,29 +80,29 @@ in }; }; - network = { - addresses = { - public = - let - addr_ipv6_nix = - let + networks = { + internet = { + interfaces = lib.singleton interface; + ipv4 = lib.mkOrder 1000 (tf.resources.${config.networking.hostName}.getAttr "public_ip"); + ipv6 = let + prefix = lib.head (lib.splitString "/" (oci-root.resources.oci_kw_subnet.importAttr "ipv6cidr_block")); + in assert lib.hasSuffix "::" prefix; prefix + toString config.kw.oci.network.publicV6; + ip = hostname: class: if hostname != config.networking.hostName then + if class == 6 then let prefix = lib.head (lib.splitString "/" (oci-root.resources.oci_kw_subnet.importAttr "ipv6cidr_block")); - in - assert lib.hasSuffix "::" prefix; prefix + toString config.kw.oci.network.publicV6; - in - { - enable = true; - nixos.ipv6.address = lib.mkIf tf.state.enable addr_ipv6_nix; - nixos.ipv6.selfaddress = lib.mkIf tf.state.enable addr_ipv6_nix; - tf.ipv6.address = tf.resources."${config.networking.hostName}_ipv6".refAttr "ip_address"; - }; + in assert lib.hasSuffix "::" prefix; prefix + toString config.kw.oci.network.publicV6 + else if class == 4 then + tf.resources.${config.networking.hostName}.importAttr "public_ip" + else throw "${config.networking.hostName}: IP for ${hostname} of ${toString class} is invalid." + else + if class == 6 then let + prefix = lib.head (lib.splitString "/" (oci-root.resources.oci_kw_subnet.importAttr "ipv6cidr_block")); + in assert lib.hasSuffix "::" prefix; prefix + toString config.kw.oci.network.publicV6 + else if class == 4 then + tf.resources.${config.networking.hostName}.getAttr "public_ip" + else throw "${config.networking.hostName}: IP for ${hostname} of ${toString class} is invalid."; + }; }; - firewall.public.interfaces = lib.singleton interface; - tf = { - enable = true; - ipv4_attr = "public_ip"; - }; - }; deploy.tf = let @@ -116,7 +116,6 @@ in connection = tf.resources."${config.networking.hostName}".connection.set; }; connection = { - port = lib.head config.services.openssh.ports; }; }; diff --git a/home/shell/ssh.nix b/home/shell/ssh.nix index 03ac9ca4..8bf84e93 100644 --- a/home/shell/ssh.nix +++ b/home/shell/ssh.nix @@ -7,6 +7,7 @@ controlPersist = "10m"; hashKnownHosts = true; compression = true; + /*TODO: revisit this matchBlocks = let common = { @@ -21,6 +22,6 @@ (lib.foldAttrList (map (network: lib.mapAttrs (_: v: { hostname = v.domain; } // common) (lib.filterAttrs (_: v: v.enable) (lib.mapAttrs (_: v: v.network.addresses.${network}) meta.network.nodes.nixos)) - ) [ "private" "public" ])); + ) [ "private" "public" ]));*/ }; } diff --git a/meta.nix b/meta.nix index 064a0585..26a5c1d0 100644 --- a/meta.nix +++ b/meta.nix @@ -2,19 +2,38 @@ home = config.deploy.targets.home.tf; in { options = { + networks = let + meta = config; + in mkOption{ + type = with types; attrsOf (submodule ({ name, config, ... }: { + options = { + member_configs = mkOption { + type = unspecified; + }; + members = mkOption { + type = unspecified; + }; + };})); + }; tailnet_uri = mkOption { type = types.str; }; tailnet = mkOption { - type = types.attrsOf (types.submodule ({ name, ... }: { + type = types.attrsOf (types.submodule ({ name, config, ... }: { options = { - addresses = { - ipv4 = mkOption { - type = types.str; - }; - ipv6 = mkOption { - type = types.str; - }; + ipv4 = mkOption { + type = types.str; + }; + ipv6 = mkOption { + type = types.str; + }; + pp = mkOption { + type = types.unspecified; + default = family: port: "http://${config."ipv${toString family}"}:${toString port}"; + }; + ppp = mkOption { + type = types.unspecified; + default = family: port: path: "http://${config."ipv${toString family}"}/${path}:${toString port}"; }; tags = mkOption { type = types.listOf types.str; @@ -25,20 +44,23 @@ in { }; config = { + networks = let + names = [ "gensokyo" "chitei" "internet" "tailscale" ]; + network_filter = network: rec { + member_configs = filterAttrs (_: nodeConfig: nodeConfig.networks.${network}.interfaces != []) config.network.nodes.nixos; + members = mapAttrs (_: nodeConfig: nodeConfig.networks.${network}) member_configs; + }; + networks' = genAttrs names network_filter; + in networks'; + tailnet_uri = "inskip.me"; tailnet = let raw = home.resources.tailnet_devices.importAttr "devices"; - devices = mapListToAttrs (elet: nameValuePair (removeSuffix ".${config.tailnet_uri}" elet.name) { + in mapListToAttrs (elet: nameValuePair (removeSuffix ".${config.tailnet_uri}" elet.name) { tags = elet.tags; - addresses = let - addresses = elet.addresses; - ipv4 = head (filter (e: hasInfix "." e) addresses); - ipv6 = head (filter (e: hasInfix ":" e) addresses); - in { - inherit ipv4 ipv6; - }; + ipv4 = head (filter (e: hasInfix "." e) elet.addresses); + ipv6 = head (filter (e: hasInfix ":" e) elet.addresses); }) raw; - in devices; runners = { lazy = { diff --git a/modules/home/network.nix b/modules/home/network.nix deleted file mode 100644 index 59288112..00000000 --- a/modules/home/network.nix +++ /dev/null @@ -1,77 +0,0 @@ -{ config, nixos, lib, ... }: - -with lib; - -{ - options.network = { - enable = mkEnableOption "Use kat's network module?"; - addresses = mkOption { - type = with types; attrsOf (submodule ({ name, ... }: { - options = { - enable = mkEnableOption "Is the system a part of the ${name} network?"; - ipv4 = { - enable = mkOption { - type = types.bool; - }; - address = mkOption { - type = types.str; - }; - }; - ipv6 = { - enable = mkOption { - type = types.bool; - }; - address = mkOption { - type = types.str; - }; - }; - prefix = mkOption { - type = types.nullOr types.str; - }; - domain = mkOption { - type = types.nullOr types.str; - }; - out = { - identifierList = mkOption { - type = types.listOf types.str; - default = if config.enable then singleton config.domain ++ config.out.addressList else [ ]; - }; - addressList = mkOption { - type = types.listOf types.str; - default = if config.enable then concatMap (i: optional i.enable i.address) [ config.ipv4 config.ipv6 ] else [ ]; - }; - }; - }; - })); - }; - tf = { - enable = mkEnableOption "Was the system provisioned by terraform?"; - ipv4_attr = mkOption { - type = types.str; - }; - ipv6_attr = mkOption { - type = types.str; - }; - }; - dns = { - enable = mkEnableOption "Do you want DNS to be semi-managed through this module?"; - isRoot = mkEnableOption "Is this system supposed to be the @ for the domain?"; - email = mkOption { - type = types.nullOr types.str; - }; - zone = mkOption { - type = types.nullOr types.str; - }; - domain = mkOption { - type = types.nullOr types.str; - }; - dynamic = mkEnableOption "Enable Glauca Dynamic DNS Updater"; - }; - }; - - config = { - network.addresses = nixos.network.addresses or {}; - network.tf = nixos.network.tf or {}; - network.dns = nixos.network.dns or {}; - }; -} diff --git a/modules/meta/network.nix b/modules/meta/network.nix index 9c26f389..389c918a 100644 --- a/modules/meta/network.nix +++ b/modules/meta/network.nix @@ -135,6 +135,7 @@ with lib; inputs.home-manager.nixosModules.home-manager meta.modules.nixos meta.modules.system + meta.nixos.network meta.system ]; specialArgs = { diff --git a/modules/nixos/firewall.nix b/modules/nixos/firewall.nix deleted file mode 100644 index 76479aa4..00000000 --- a/modules/nixos/firewall.nix +++ /dev/null @@ -1,82 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; - -let - cfg = config.network.firewall; -in -{ - options.network.firewall = { - public.tcp.ports = mkOption { - type = types.listOf types.port; - default = [ ]; - }; - public.udp.ports = mkOption { - type = types.listOf types.port; - default = [ ]; - }; - private.tcp.ports = mkOption { - type = types.listOf types.port; - default = [ ]; - }; - private.udp.ports = mkOption { - type = types.listOf types.port; - default = [ ]; - }; - - public.tcp.ranges = mkOption { - type = types.listOf (types.attrsOf types.port); - default = [ ]; - }; - public.udp.ranges = mkOption { - type = types.listOf (types.attrsOf types.port); - default = [ ]; - }; - private.tcp.ranges = mkOption { - type = types.listOf (types.attrsOf types.port); - default = [ ]; - }; - private.udp.ranges = mkOption { - type = types.listOf (types.attrsOf types.port); - default = [ ]; - }; - - public.interfaces = mkOption { - type = types.listOf types.str; - description = "Public firewall interfaces"; - default = [ ]; - }; - private.interfaces = mkOption { - type = types.listOf types.str; - description = "Private firewall interfaces"; - default = [ ]; - }; - }; - - config = { - network.firewall = mkMerge (mapAttrsToList (_: user: user.network.firewall) config.home-manager.users); - networking.firewall.interfaces = - let - fwTypes = { - ports = "Ports"; - ranges = "PortRanges"; - }; - - interfaceDef = visibility: - listToAttrs (flatten (mapAttrsToList - (type: typeString: - map - (proto: { - name = "allowed${toUpper proto}${typeString}"; - value = cfg.${visibility}.${proto}.${type}; - }) [ "tcp" "udp" ]) - fwTypes)); - - interfaces = visibility: - listToAttrs - (map (interface: nameValuePair interface (interfaceDef visibility)) - cfg.${visibility}.interfaces); - in - mkMerge (map (visibility: interfaces visibility) [ "public" "private" ]); - }; -} diff --git a/modules/nixos/network.nix b/modules/nixos/network.nix deleted file mode 100644 index 8fc59a52..00000000 --- a/modules/nixos/network.nix +++ /dev/null @@ -1,257 +0,0 @@ -{ config, lib, tf, pkgs, ... }: - -with lib; - -let - cfg = config.network; -in -{ - options.network = { - enable = mkEnableOption "Use kat's network module?"; - addresses = mkOption { - type = with types; attrsOf (submodule ({ name, options, config, ... }: { - options = { - enable = mkEnableOption "Is it a member of the ${name} network?"; - nixos = { - ipv4 = { - enable = mkOption { - type = types.bool; - default = options.nixos.ipv4.address.isDefined; - }; - selfaddress = mkOption { - type = types.str; - }; - address = mkOption { - type = types.str; - }; - }; - ipv6 = { - enable = mkOption { - type = types.bool; - default = options.nixos.ipv6.address.isDefined; - }; - selfaddress = mkOption { - type = types.str; - }; - address = mkOption { - type = types.str; - }; - }; - }; - tf = { - ipv4 = { - enable = mkOption { - type = types.bool; - default = options.tf.ipv4.address.isDefined; - }; - address = mkOption { - type = types.str; - }; - }; - ipv6 = { - enable = mkOption { - type = types.bool; - default = options.tf.ipv6.address.isDefined; - }; - address = mkOption { - type = types.str; - }; - }; - }; - prefix = mkOption { - type = types.nullOr types.str; - }; - subdomain = mkOption { - type = types.nullOr types.str; - }; - domain = mkOption { - type = types.nullOr types.str; - default = "${config.subdomain}.${cfg.dns.domain}"; - }; - target = mkOption { - type = types.nullOr types.str; - default = "${config.domain}."; - }; - out = { - identifierList = mkOption { - type = types.listOf types.str; - default = optionals config.enable (singleton config.domain ++ config.out.addressList); - }; - addressList = mkOption { - type = types.listOf types.str; - default = optionals config.enable (concatMap (i: optional i.enable i.address) [ config.nixos.ipv4 config.nixos.ipv6 ]); - }; - }; - }; - })); - }; - extraCerts = mkOption { - type = types.attrsOf types.str; - default = { }; - }; - tf = { - enable = mkEnableOption "Was the system provisioned by terraform?"; - ipv4_attr = mkOption { - type = types.nullOr types.str; - default = null; - }; - ipv6_attr = mkOption { - type = types.nullOr types.str; - default = null; - }; - }; - dns = { - enable = mkEnableOption "Do you want DNS to be semi-managed through this module?"; - isRoot = mkEnableOption "Is this system supposed to be the @ for the domain?"; - email = mkOption { - type = types.nullOr types.str; - }; - zone = mkOption { - type = types.nullOr types.str; - }; - domain = mkOption { - type = types.nullOr types.str; - }; - }; - }; - - config = - let - networks = cfg.addresses; - networksWithDomains = filterAttrs (_: v: v.enable) networks; - in - mkIf cfg.enable { - network = { - dns = { - domain = builtins.substring 0 ((builtins.stringLength cfg.dns.zone) - 1) cfg.dns.zone; - }; - addresses = lib.mkMerge [ - (mkIf (!cfg.tf.enable) (genAttrs [ "private" "public" "yggdrasil" ] (network: { - tf = { - ipv4.address = mkIf (cfg.addresses.${network}.nixos.ipv4.enable) cfg.addresses.${network}.nixos.ipv4.address; - ipv6.address = mkIf (cfg.addresses.${network}.nixos.ipv6.enable) cfg.addresses.${network}.nixos.ipv6.address; - }; - }))) - (mkIf cfg.tf.enable (genAttrs ["yggdrasil" ] (network: { - tf = { - ipv4.address = mkIf (cfg.addresses.${network}.nixos.ipv4.enable) cfg.addresses.${network}.nixos.ipv4.address; - ipv6.address = mkIf (cfg.addresses.${network}.nixos.ipv6.enable) cfg.addresses.${network}.nixos.ipv6.address; - }; - }))) - (mkIf cfg.tf.enable { - public = { - tf = { - ipv4.address = mkIf (cfg.tf.ipv4_attr != null) (tf.resources.${config.networking.hostName}.refAttr cfg.tf.ipv4_attr); - ipv6.address = mkIf (cfg.tf.ipv6_attr != null) (tf.resources.${config.networking.hostName}.refAttr cfg.tf.ipv6_attr); - }; - nixos = { - ipv4.selfaddress = mkIf (tf.state.enable && cfg.tf.ipv4_attr != null) (tf.resources.${config.networking.hostName}.getAttr cfg.tf.ipv4_attr); - ipv6.selfaddress = mkIf (tf.state.enable && cfg.tf.ipv6_attr != null) (tf.resources.${config.networking.hostName}.getAttr cfg.tf.ipv6_attr); - ipv4.address = mkIf (tf.state.resources ? ${tf.resources.${config.networking.hostName}.out.reference} && cfg.tf.ipv4_attr != null) (tf.resources.${config.networking.hostName}.importAttr cfg.tf.ipv4_attr); - ipv6.address = mkIf (tf.state.resources ? ${tf.resources.${config.networking.hostName}.out.reference} && cfg.tf.ipv6_attr != null) (tf.resources.${config.networking.hostName}.importAttr cfg.tf.ipv6_attr); - }; - }; - }) - ({ - private = { - prefix = "int"; - subdomain = "${config.networking.hostName}.${cfg.addresses.private.prefix}"; - }; - yggdrasil = { - enable = cfg.yggdrasil.enable; - prefix = "ygg"; - subdomain = "${config.networking.hostName}.${cfg.addresses.yggdrasil.prefix}"; - }; - public = { - subdomain = config.networking.hostName; - }; - }) - (mkIf cfg.yggdrasil.enable { - yggdrasil.nixos.ipv6.address = cfg.yggdrasil.address; - }) - ]; - }; - - - networking.domain = mkDefault (if cfg.addresses.public.enable then cfg.dns.domain - else if cfg.addresses.private.enable then "${cfg.addresses.private.prefix}.${cfg.dns.domain}" else ""); - - deploy.tf.dns.records = - let - recordsV4 = mapAttrs' - (n: v: - nameValuePair "node_${n}_${config.networking.hostName}_v4" { - inherit (v.tf.ipv4) enable; - inherit (cfg.dns) zone; - domain = v.subdomain; - a = { inherit (v.tf.ipv4) address; }; - }) - networksWithDomains; - recordsV6 = mapAttrs' - (n: v: - nameValuePair "node_${n}_${config.networking.hostName}_v6" { - inherit (v.tf.ipv6) enable; - inherit (cfg.dns) zone; - domain = v.subdomain; - aaaa = { inherit (v.tf.ipv6) address; }; - }) - networksWithDomains; - in - mkMerge (map (record: mkIf cfg.dns.enable record) [ - recordsV4 - recordsV6 - (mkIf cfg.dns.isRoot { - "node_root_${config.networking.hostName}_v4" = { - inherit (cfg.addresses.public) enable; - inherit (cfg.dns) zone; - a = { inherit (cfg.addresses.public.tf.ipv4) address; }; - }; - "node_root_${config.networking.hostName}_v6" = { - inherit (cfg.addresses.public) enable; - inherit (cfg.dns) zone; - aaaa = { inherit (cfg.addresses.public.tf.ipv6) address; }; - }; - }) - ]); - - security.acme.certs = mkMerge (map (cert: mkIf cfg.dns.enable cert) [ - (mkIf config.services.nginx.enable (mapAttrs' - (n: v: - nameValuePair "${n}_${config.networking.hostName}" { - inherit (v) domain; - dnsProvider = "rfc2136"; - credentialsFile = config.secrets.files.dns_creds.path; - group = mkDefault "nginx"; - }) - networksWithDomains)) - (mapAttrs' - (n: v: - nameValuePair "${n}" { - domain = v; - dnsProvider = "rfc2136"; - credentialsFile = config.secrets.files.dns_creds.path; - group = mkDefault "nginx"; - }) - cfg.extraCerts) - ]); - - services.nginx.virtualHosts = mkMerge (map (host: mkIf cfg.dns.enable host) [ - (mkIf config.services.nginx.enable (mapAttrs' - (n: v: - nameValuePair v.domain { - useACMEHost = "${n}_${config.networking.hostName}"; - forceSSL = true; - }) - networksWithDomains)) - (mapAttrs' - (n: v: - nameValuePair v { - useACMEHost = "${n}"; - forceSSL = true; - }) - cfg.extraCerts) - ]); - - _module.args = { inherit (config.lib) kw; }; - }; -} diff --git a/modules/nixos/yggdrasil.nix b/modules/nixos/yggdrasil.nix deleted file mode 100644 index 24774e5e..00000000 --- a/modules/nixos/yggdrasil.nix +++ /dev/null @@ -1,145 +0,0 @@ -{ config, meta, lib, pkgs, ... }: - -with lib; - -let - cfg = config.network.yggdrasil; - calcAddr = pubkey: lib.readFile (pkgs.runCommandNoCC "calcaddr-${pubkey}" { } '' - echo '{ SigningPublicKey: "${pubkey}" }' | ${config.services.yggdrasil.package}/bin/yggdrasil -useconf -address | tr -d '\n' > $out - '').outPath; -in -{ - options.network.yggdrasil = { - enable = mkEnableOption "Enable the yggdrasil-based private hexnet"; - pubkey = mkOption { - type = types.str; - description = "Public key of this node"; - }; - address = mkOption { - type = types.str; - #description = "Main Yggdrasil address. Set automatically"; - #default = calcAddr cfg.signingPubkey; - default = ""; - }; - trust = mkOption { - type = types.bool; - description = "Open Firewall completely for the network"; - default = false; - }; - listen = { - enable = mkOption { - type = types.bool; - description = "Allow other hosts in the network to connect directly"; - default = false; - }; - endpoints = mkOption { - type = types.listOf types.str; - description = "Endpoints to listen on"; - default = [ ]; - }; - }; - tunnel = { - localV6 = mkOption { - type = types.listOf types.str; - description = "v6 subnets to expose"; - default = [ ]; - }; - localV4 = mkOption { - type = types.listOf types.str; - description = "v4 subnets to expose"; - default = [ ]; - }; - remoteV6 = mkOption { - type = types.attrsOf types.str; - description = "Extra v6 subnets to route"; - default = { }; - }; - remoteV4 = mkOption { - type = types.attrsOf types.str; - description = "Extra v4 subnets to route"; - default = { }; - }; - }; - extra = { - pubkeys = mkOption { - type = types.attrsOf types.str; - description = "Additional hosts to allow into the network. Keys won't be added to definition host."; - default = { }; - example = { host = "0000000000000000000000000000000000000000000000000000000000000000"; }; - }; - addresses = mkOption { - type = types.attrsOf types.str; - internal = true; - default = mapAttrs (_: c: calcAddr c) cfg.extra.pubkeys; - }; - localV6 = mkOption { - type = types.listOf types.str; - description = "v6 subnets to expose, but not route"; - default = [ ]; - }; - localV4 = mkOption { - type = types.listOf types.str; - description = "v4 subnets to expose, but not route"; - default = [ ]; - }; - }; - extern = { - pubkeys = mkOption { - type = types.attrsOf types.str; - description = "Additional hosts to allow into the network. Keys won't be added to definition host."; - default = { }; - example = { host = "0000000000000000000000000000000000000000000000000000000000000000"; }; - }; - endpoints = mkOption { - type = types.listOf types.str; - description = "Endpoints to listen on"; - default = [ ]; - }; - }; - }; - - config = mkIf cfg.enable ( - let - yggConfigs = filter - ( - c: c.enable && (cfg.pubkey != c.pubkey) - ) - ( - mapAttrsToList (_: node: node.network.yggdrasil or { enable = false; pubkey = null; }) meta.network.nodes.nixos - ); - pubkeys = flatten ((filter (n: n != "0000000000000000000000000000000000000000000000000000000000000000") (attrValues cfg.extern.pubkeys)) ++ (map (c: [ c.pubkey ] ++ (attrValues c.extra.pubkeys)) yggConfigs)); - in - { - assertions = [ - { - assertion = !(cfg.listen.enable && (cfg.listen.endpoints == [ ])); - message = "Specify network.yggdrasil.listen.endpoints"; - } - ]; - - networking.firewall.trustedInterfaces = mkIf cfg.trust [ "yggdrasil" ]; - - services.yggdrasil = { - enable = true; - persistentKeys = true; - config = { - AllowedPublicKeys = pubkeys; - IfName = "yggdrasil"; - Listen = cfg.listen.endpoints; - Peers = lib.flatten (cfg.extern.endpoints ++ (map (c: c.listen.endpoints) (filter (c: c.listen.enable) yggConfigs))); - }; - }; - - system.build.yggdrasilTemplate = - let - json = builtins.toJSON { - inherit (config.services.yggdrasil.config) Peers SessionFirewall TunnelRouting; - PublicKey = ""; - PrivateKey = ""; - }; - in - pkgs.runCommandNoCC "yggdrasil-template.json" { } - "echo '${json}' | ${config.services.yggdrasil.package}/bin/yggdrasil -useconf -normaliseconf > $out"; - } - ); -} diff --git a/nixos/base/network.nix b/nixos/base/network.nix index d29ec4dd..6ee40b54 100644 --- a/nixos/base/network.nix +++ b/nixos/base/network.nix @@ -2,13 +2,4 @@ { networking.nftables.enable = true; - - network = { - enable = true; - dns = { - enable = mkDefault true; - email = "acme@kittywit.ch"; - zone = "kittywit.ch."; - }; - }; } diff --git a/nixos/base/ssh.nix b/nixos/base/ssh.nix index 4635e52a..81a6862a 100644 --- a/nixos/base/ssh.nix +++ b/nixos/base/ssh.nix @@ -3,22 +3,11 @@ with lib; { - network.firewall = { - public = { - tcp.ports = singleton 62954; - udp.ranges = [{ - from = 60000; - to = 61000; - }]; - }; - private = { - tcp.ports = singleton 62954; - udp.ranges = [{ - from = 60000; - to = 61000; - }]; - }; - }; + networks = genAttrs [ "chitei" "gensokyo" ] (_: { + # Mosh + tcp = [62954]; + udp = [ [60000 61000] ]; + }); /* security.pam.services.sshd.text = mkDefault (mkAfter '' @@ -39,5 +28,6 @@ with lib; LogLevel VERBOSE ''; }; + programs.mosh.enable = true; } diff --git a/nixos/network.nix b/nixos/network.nix index 1e90dc08..d3e32ae5 100644 --- a/nixos/network.nix +++ b/nixos/network.nix @@ -1,96 +1,334 @@ -{ config, lib, tf, pkgs, meta, ... }: with lib; let -in { - options = with lib; { - network = { - routeDefault = mkOption { - default = true; - type = types.bool; - }; +{ config, lib, tf, pkgs, meta, ... }: with lib; { + options = let + nixos = config; + in { + domains = mkOption { + default = {}; + type = with types; attrsOf (submodule ({ name, config, ... }: { + options = { + host = mkOption { + type = nullOr str; + default = nixos.networking.hostName; + }; + network = mkOption { + type = nullOr str; + default = "internet"; + }; + type = mkOption { + type = types.enum [ + "ipv4" + "ipv6" + "both" + "cname" + ]; + }; + domain = mkOption { + type = nullOr str; + default = "${nixos.networking.hostName}${if config.prefix != null then ".${config.prefix}" else ""}"; + }; + dn = mkOption { + type = nullOr str; + default = lib.removeSuffix "." config.domain; + }; + prefix = mkOption { + type = nullOr str; + default = null; + }; + zone = mkOption { + type = nullOr str; + default = "kittywit.ch."; + }; + target = mkOption { + type = nullOr str; + default = if (config.type == "cname" && config.host != nixos.networking.hostName) then + meta.network.nodes.nixos.${config.host}.networks.${config.network}.target + else "${config.domain}.${config.zone}"; + }; + }; + })); + }; + networks = let + nixos = config; + in mkOption { + default = { }; + type = with types; attrsOf (submodule ({ name, config, options, ... }: let + portRangeModule = { config, ... }: { + options = { + from = mkOption { + type = types.port; + }; + to = mkOption { + type = types.port; + default = config.from; + }; + /*isRange = mkOption { + type = types.bool; + default = assert config.to >= config.from; config.from != config.to; + readOnly = true; + };*/ + }; + }; + portRangeType = types.submodule portRangeModule; + convToPort = value: if isInt value + then { from = value; } + else assert length value == 2; { from = elemAt value 0; to = elemAt value 1; }; + portType = coercedTo (oneOf [ int (listOf int) ]) convToPort portRangeType; + in { + options = with types; { + interfaces = mkOption { + description = "Interfaces this network operates upon."; + type = listOf str; + default = []; + }; + tcp = mkOption { + description = "Port numbers or ranges to allow TCP traffic outbound."; + type = listOf portType; + default = []; + }; + udp = mkOption { + description = "Port numbers or ranges to allow UDP traffic outbound."; + type = listOf portType; + default = []; + }; + ip = mkOption { + description = "The machine's IPv4 address on the network, if it has one."; + type = unspecified; + default = hostname: class: if hostname != nixos.networking.hostName then + if class == 6 then + config.ipv6 + else if class == 4 then + config.ipv4 + else throw "${nixos.networking.hostName}: IP for ${hostname} of ${class} is invalid." + else + if class == 6 then + config.ipv6 + else if class == 4 then + config.ipv4 + else throw "${nixos.networking.hostName}: IP for ${hostname} of ${class} is invalid."; + }; + ipv4 = mkOption { + description = "The machine's IPv4 address on the network, if it has one."; + type = nullOr str; + }; + ipv6 = mkOption { + description = "The machine's IPv6 address on the network, if it has one."; + type = nullOr str; + }; + ipv4_defined = mkOption { + type = types.bool; + default = options.ipv4.isDefined; + }; + ipv6_defined = mkOption { + type = types.bool; + default = options.ipv6.isDefined; + }; + create_domain = mkOption { + type = bool; + default = false; + }; + domain = mkOption { + type = nullOr str; + default = "${nixos.networking.hostName}${if config.prefix != null then ".${config.prefix}" else ""}"; + }; + prefix = mkOption { + type = nullOr str; + default = null; + }; + zone = mkOption { + type = nullOr str; + default = "kittywit.ch."; + }; + target = mkOption { + type = nullOr str; + default = "${config.domain}.${config.zone}"; + }; + }; + })); }; }; - config = { - network.yggdrasil.extern = let - in { - pubkeys = { - satorin = - "cbadeaa973b051cf66e23dcb014ab5be59e55a1c98ef541345520868e3bcf9f7"; - shanghai = - "5aba9ba2ac7a54ffef19dea9e39881bd977f76032db81a2c82c4674ed475c95b"; - grimoire = - "2a1567a2848540070328c9e938c58d40f2b1a3f08982c15c7edc5dcabfde3330"; - boline = - "89684441745467da0d1bf7f47dc74ec3ca65e05c72f752298ef3c22a22024d43"; - okami = - "f8fd12c6ed924048e93a7bd7dd63c2464813c9edddfef7415c4574518ecd4757"; - amaterasu = - "ab9a4a78df124a8413c3a6576332d7739a44c036e14b7b0b4ea4558373ddda97"; - duck-powerduck = - "9475274dcd43f0f3f397d56168efd436b0db58e58f4c068f75ab93ba3f51e405"; - duck-nagoya = - "0000001a24b38f4341e356e7efc98dd31e259669242e0a82ba86971317b94954"; + networks = { + internet = { + create_domain = true; + }; + chitei = { + create_domain = true; + }; + gensokyo = { + zone = mkDefault "gensokyo.zone."; + create_domain = true; + }; + tailscale = { + interfaces = singleton "tailscale0"; + ipv4 = meta.tailnet.${config.networking.hostName}.ipv4 or null; + ipv6 = meta.tailnet.${config.networking.hostName}.ipv6 or null; + zone = "inskip.me."; + create_domain = true; + }; + }; + + networking.domain = "inskip.me"; + + deploy.tf = { + dns.records = let + # Families of address to create domains for + address_families = [ "ipv4" "ipv6" ]; + domains = config.domains; + # Merge the result of a map upon address_families to mapAttrs' + domains' = map (family: mapAttrs' (name: settings: let + network = if settings.host != config.networking.hostName then + meta.network.nodes.nixos.${settings.host}.networks.${settings.network} + else config.networks.${settings.network}; + in nameValuePair "${settings.network}-${if settings.type == "both" || settings.type == family then family else settings.type}-${settings.domain}-${settings.zone}" ({ + inherit (settings) domain zone; + enable = mkDefault false; + } // (optionalAttrs (settings.type == "cname" && family == "ipv4") { + cname = { inherit (network) target; }; + enable = mkForce true; + }) // (optionalAttrs (network.ipv6_defined && family == "ipv6" && (settings.type == "both" || settings.type == family)) { + aaaa.address = network.ipv6; + enable = mkForce network.ipv6_defined; + }) + // (optionalAttrs (!network.ipv4_defined && !network.ipv6_defined) { + a.address = "127.0.0.1"; + enable = mkForce false; + }) // (optionalAttrs (network.ipv4_defined && family == "ipv4" && (settings.type == "both" || settings.type == family)) { + a.address = network.ipv4; + enable = mkForce network.ipv4_defined; + }))) domains) address_families; + networks = config.networks; + # Networks to actually create domains for + networks' = filterAttrs (_: settings: settings.create_domain) networks; + # Merge the result of a map upon address_families to mapAttrs' + networks'' = map (family: mapAttrs' (network: settings: + nameValuePair "${network}-${family}-${settings.domain}-${settings.zone}" ({ + inherit (settings) domain zone; + } // (if family == "ipv6" then { + aaaa.address = settings.ipv6; + enable = mkForce settings.ipv6_defined; + } else { + enable = mkForce settings.ipv4_defined; + #a.address = if settings.ipv4_defined then settings.ipv4 else "127.0.0.1"; + a.address = settings.ipv4; + }) + )) networks') address_families; + in mkMerge (networks'' ++ domains'); + + acme = let + home = meta.deploy.targets.home.tf; + in { + enable = true; + account = { + emailAddress = "kat@inskip.me"; + accountKeyPem = home.resources.acme_private_key.importAttr "private_key_pem"; + }; + challenge = { + defaultProvider = "rfc2136"; + configs.rfc2136 = { + RFC2136_NAMESERVER = tf.variables.katdns-address.ref; + RFC2136_TSIG_KEY = tf.variables.katdns-name.ref; + RFC2136_TSIG_SECRET = tf.variables.katdns-key.ref; + RFC2136_TSIG_ALGORITHM = "hmac-sha512"; + }; + }; + certs = let + hostnames = (attrValues (mapAttrs (network: settings: removeSuffix "." settings.target) config.networks)) + ++ (attrValues (mapAttrs (network: settings: removeSuffix "." settings.target) config.domains)); + in listToAttrs (map (hostname: + nameValuePair hostname { + keyType = "4096"; + dnsNames = singleton hostname; + }) hostnames); + }; + + variables = { + tailscale-authkey.export = true; + tailscale-apikey = { + value.shellCommand = "${meta.kw.secrets.command} secrets/tailscale -f api_key"; + sensitive = true; + export = true; + }; + }; + providers.tailscale = { + inputs = { + api_key = tf.variables.tailscale-apikey.ref; + tailnet = "inskip.me"; + }; + }; + resources.tailnet_key = { + provider = "tailscale"; + type = "tailnet_key"; + inputs = { + reusable = false; + ephemeral = false; + preauthorized = true; + }; }; }; - deploy.tf = { - variables.tailscale-apikey = { - value.shellCommand = "${meta.kw.secrets.command} secrets/tailscale -f api_key"; - sensitive = true; - export = true; - }; - providers.tailscale = { - inputs = { - api_key = tf.variables.tailscale-apikey.ref; - tailnet = "inskip.me"; - }; + secrets.files = let + hostnames = (attrValues (mapAttrs (network: settings: removeSuffix "." settings.target) config.networks)) + ++ (attrValues (mapAttrs (network: settings: removeSuffix "." settings.target) config.domains)); + in listToAttrs (map (hostname: + nameValuePair "${hostname}-cert" { + text = tf.acme.certs.${hostname}.out.refFullchainPem; + owner = "nginx"; + group = "nginx"; + }) hostnames) // listToAttrs (map (hostname: + nameValuePair "${hostname}-key" { + text = tf.acme.certs.${hostname}.out.refPrivateKeyPem; + owner = "nginx"; + group = "nginx"; + }) hostnames); + + services.nginx.virtualHosts = let + hostnames = (attrValues (mapAttrs (network: settings: removeSuffix "." settings.target) config.networks)) + ++ (attrValues (mapAttrs (network: settings: removeSuffix "." settings.target) config.domains)); + in listToAttrs (map (hostname: + nameValuePair hostname { + forceSSL = true; + sslCertificate = config.secrets.files."${hostname}-cert".path; + sslCertificateKey = config.secrets.files."${hostname}-key".path; + }) hostnames); + + networking.firewall = { + interfaces = mkMerge (mapAttrsToList (network: settings: + genAttrs settings.interfaces (_: { allowedTCPPortRanges = settings.tcp; allowedUDPPortRanges = settings.udp; }) + ) (removeAttrs config.networks ["tailscale"])); + trustedInterfaces = [ "tailscale0" ]; + allowedTCPPorts = [ 5200 ]; + allowedUDPPorts = [ config.services.tailscale.port ]; }; - variables.tailscale-authkey.export = true; - resources.tailnet_key = { - provider = "tailscale"; - type = "tailnet_key"; - inputs = { - reusable = false; - ephemeral = false; - preauthorized = true; - }; + + + services.tailscale.enable = true; + + systemd.services.tailscale-autoconnect = mkIf (builtins.getEnv "TF_IN_AUTOMATION" != "" || tf.state.enable) { + description = "Automatic connection to Tailscale"; + +# make sure tailscale is running before trying to connect to tailscale + after = [ "network-pre.target" "tailscale.service" ]; + wants = [ "network-pre.target" "tailscale.service" ]; + wantedBy = [ "multi-user.target" ]; + +# set this service as a oneshot job + serviceConfig.Type = "oneshot"; + +# have the job run this shell script + script = with pkgs; '' +# wait for tailscaled to settle + sleep 2 + +# check if we are already authenticated to tailscale + status="$(${tailscale}/bin/tailscale status -json | ${jq}/bin/jq -r .BackendState)" + if [ $status = "Running" ]; then # if so, then do nothing + exit 0 + fi + +# otherwise authenticate with tailscale +# to-do: --advertise-exit-node + ${tailscale}/bin/tailscale up -authkey ${tf.resources.tailnet_key.getAttr "key"} + ''; }; }; - - networking.firewall = { - trustedInterfaces = [ "tailscale0" ]; - - # allow the Tailscale UDP port through the firewall - allowedTCPPorts = [ 5200 ]; - allowedUDPPorts = [ config.services.tailscale.port ]; - }; - - services.tailscale.enable = true; - - systemd.services.tailscale-autoconnect = mkIf (builtins.getEnv "TF_IN_AUTOMATION" != "" || tf.state.enable) { - description = "Automatic connection to Tailscale"; - - # make sure tailscale is running before trying to connect to tailscale - after = [ "network-pre.target" "tailscale.service" ]; - wants = [ "network-pre.target" "tailscale.service" ]; - wantedBy = [ "multi-user.target" ]; - - # set this service as a oneshot job - serviceConfig.Type = "oneshot"; - - # have the job run this shell script - script = with pkgs; '' - # wait for tailscaled to settle - sleep 2 - - # check if we are already authenticated to tailscale - status="$(${tailscale}/bin/tailscale status -json | ${jq}/bin/jq -r .BackendState)" - if [ $status = "Running" ]; then # if so, then do nothing - exit 0 - fi - - # otherwise authenticate with tailscale - ${tailscale}/bin/tailscale up -authkey ${tf.resources.tailnet_key.getAttr "key"} - ''; - }; -}; } diff --git a/nixos/systems/chen.nix b/nixos/systems/chen.nix index 932401d5..536de76f 100644 --- a/nixos/systems/chen.nix +++ b/nixos/systems/chen.nix @@ -73,23 +73,9 @@ with lib; }; }; - network = { - addresses = { - private = { - enable = true; - nixos = { - ipv4.address = "192.168.1.196"; - }; - }; - }; - }; - - # Firewall - - network.firewall = { - public = { - interfaces = singleton "enp0s20u1"; - }; + networks.chitei = { + interfaces = [ "enp0s20u1" "wlp1s0" ]; + ipv4 = "192.168.1.196"; }; # State diff --git a/nixos/systems/daiyousei.nix b/nixos/systems/daiyousei.nix index e24f6d30..6ca3a3f5 100644 --- a/nixos/systems/daiyousei.nix +++ b/nixos/systems/daiyousei.nix @@ -37,11 +37,5 @@ }; }; - network.yggdrasil = { - enable = true; - pubkey = "edb7de263e6924b8c9446123979782420e5196317bffc75e9a6ca546551252da"; - address = "206:d807:a98:309f:3bc0:de7a:411d:9d95"; - }; - system.stateVersion = "21.11"; } diff --git a/nixos/systems/koishi.nix b/nixos/systems/koishi.nix index f8b956e5..91cb3f57 100644 --- a/nixos/systems/koishi.nix +++ b/nixos/systems/koishi.nix @@ -19,8 +19,8 @@ }; }; - programs.ssh.extraConfig = '' -Host daiyousei-build + programs.ssh.extraConfig = '' + Host daiyousei-build HostName daiyousei.kittywit.ch Port 62954 User root @@ -51,42 +51,36 @@ Host daiyousei-build }; }; - swapDevices = - [ { device = "/dev/disk/by-uuid/0d846453-95b4-46e1-8eaf-b910b4321ef0"; } + swapDevices = [ + { device = "/dev/disk/by-uuid/0d846453-95b4-46e1-8eaf-b910b4321ef0"; } ]; powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; + boot = { supportedFilesystems = [ "xfs" "zfs" ]; initrd.luks.devices."cryptroot".device = "/dev/disk/by-uuid/f0ea08b4-6af7-4d90-a2ad-edd5672a2105"; loader = { - efi = { - canTouchEfiVariables = true; - # assuming /boot is the mount point of the EFI partition in NixOS (as the installation section recommends). - efiSysMountPoint = "/boot"; - }; - grub = { - # despite what the configuration.nix manpage seems to indicate, - # as of release 17.09, setting device to "nodev" will still call - # `grub-install` if efiSupport is true - # (the devices list is not used by the EFI grub install, - # but must be set to some value in order to pass an assert in grub.nix) - devices = [ "nodev" ]; - efiSupport = true; - enable = true; - # set $FS_UUID to the UUID of the EFI partition - extraEntries = '' - menuentry "Windows" { - insmod part_gpt - insmod fat - insmod search_fs_uuid - insmod chain - search --fs-uuid --set=root DEBC-8F03 - chainloader /EFI/Microsoft/Boot/bootmgfw.efi - } - ''; - version = 2; - }; + efi = { + canTouchEfiVariables = true; + efiSysMountPoint = "/boot"; + }; + grub = { + devices = [ "nodev" ]; + efiSupport = true; + enable = true; + extraEntries = '' + menuentry "Windows" { + insmod part_gpt + insmod fat + insmod search_fs_uuid + insmod chain + search --fs-uuid --set=root DEBC-8F03 + chainloader /EFI/Microsoft/Boot/bootmgfw.efi + } + ''; + version = 2; + }; }; }; @@ -100,40 +94,14 @@ Host daiyousei-build networking = { hostId = "dddbb888"; useDHCP = false; - /* wireless = { - enable = true; - userControlled.enable = true; - interfaces = singleton "wlp3s0"; - }; - interfaces = { - wlp3s0.ipv4.addresses = singleton { - inherit (config.network.addresses.private.nixos.ipv4) address; - prefixLength = 24; - }; - }; */ }; services.fstrim.enable = true; - network = { - addresses = { - private = { - enable = true; - nixos = { - ipv4.address = "192.168.1.121"; - }; - }; - }; - yggdrasil = { - enable = true; - pubkey = "f94d49458822a73d70306b249a39d4de8a292b13e12339b21010001133417be7"; - address = "200:d65:6d74:efba:b185:1f9f:29b6:cb8c"; - listen.enable = false; - listen.endpoints = [ "tcp://0.0.0.0:0" ]; - }; - firewall = { - public.interfaces = [ "enp1s0" "wlp3s0" ]; - private.interfaces = singleton "yggdrasil"; + networks = { + gensokyo = { + interfaces = [ "enp1s0" "wlp3s0" ]; + ipv4 = "10.1.1.65"; }; }; diff --git a/nixos/systems/marisa.nix b/nixos/systems/marisa.nix index b18e0f06..2e4e34f9 100644 --- a/nixos/systems/marisa.nix +++ b/nixos/systems/marisa.nix @@ -1,24 +1,13 @@ { config, lib, pkgs, modulesPath, tf, meta, ... }: with lib; { imports = with meta; [ (modulesPath + "/profiles/qemu-guest.nix") + hardware.manual nixos.network services.nginx services.access services.irlsite ]; - - deploy.tf = { - resources.marisa = { - provider = "null"; - type = "resource"; - connection = { - port = head config.services.openssh.ports; - host = config.network.addresses.public.nixos.ipv4.address; - }; - }; - }; - boot = { loader.grub = { enable = true; @@ -45,43 +34,29 @@ interfaces.ens3 = { ipv4.addresses = [ { - inherit (config.network.addresses.public.nixos.ipv4) address; + address = config.networks.internet.ipv4; prefixLength = 24; } ]; ipv6.addresses = [ { - inherit (config.network.addresses.public.nixos.ipv6) address; + address = config.networks.internet.ipv6; prefixLength = 48; } ]; }; }; - network = { - addresses.public = { - enable = true; - nixos.ipv4.address = "104.244.72.5"; - nixos.ipv6.address = "2605:6400:30:eed1:6cf7:bbfc:b4e:15c0"; - }; - yggdrasil = { - enable = true; - pubkey = "2134779f3e19e7df46113a814e9a87097839b9d557ebe3856423e148abcfe582"; - address = "202:f65c:4306:f30:c105:cf76:2bf5:8b2b"; - listen.enable = true; - listen.endpoints = [ "tcp://${config.network.addresses.public.nixos.ipv4.address}:52969" "tcp://[${config.network.addresses.public.nixos.ipv6.address}]:52969" ]; - }; - firewall = { - public = { - interfaces = singleton "ens3"; - tcp.ports = [ 1935 52969 ]; - }; - private.interfaces = singleton "yggdrasil"; + networks = { + internet = { + ipv4 = "104.244.72.5"; + ipv6 = "2605:6400:30:eed1:6cf7:bbfc:b4e:15c0"; + interfaces = singleton "ens3"; + tcp = [ 1935 52969 ]; }; }; - - fileSystems."/" ={ + fileSystems."/" = { device = "/dev/disk/by-uuid/6ed3e886-d390-433f-90ac-2b37aed9f15f"; fsType = "ext4"; }; diff --git a/nixos/systems/ran.nix b/nixos/systems/ran.nix index 714e21b3..017748d3 100644 --- a/nixos/systems/ran.nix +++ b/nixos/systems/ran.nix @@ -7,25 +7,13 @@ with lib; imports = with meta; [ hardware.eeepc-1015pem + hardware.local nixos.network nixos.arc services.kattv services.dnscrypt-proxy ]; - # Terraform - - deploy.tf = { - resources.ran = { - provider = "null"; - type = "resource"; - connection = { - port = head config.services.openssh.ports; - host = config.network.addresses.private.nixos.ipv4.address; - }; - }; - }; - # File Systems and Swap fileSystems = { @@ -57,23 +45,9 @@ with lib; interfaces.enp1s0.useDHCP = true; }; - network = { - addresses = { - private = { - enable = true; - nixos = { - ipv4.address = "192.168.1.215"; - }; - }; - }; - }; - - # Firewall - - network.firewall = { - public = { - interfaces = singleton "enp1s0"; - }; + networks.chitei = { + interfaces = [ "enp1s0" ]; + ipv4 = "192.168.1.215"; }; # State diff --git a/nixos/systems/rinnosuke.nix b/nixos/systems/rinnosuke.nix index ab5f8d6e..e43e4227 100644 --- a/nixos/systems/rinnosuke.nix +++ b/nixos/systems/rinnosuke.nix @@ -20,13 +20,5 @@ }; }; - network = { - yggdrasil = { - enable = true; - pubkey = "fc64ee574072ef7420ff98bc53856f881025de252081e661a78e04ebcf7c6b35"; - address = "200:736:2351:7f1a:2117:be00:ce87:58f5"; - }; - }; - system.stateVersion = "21.11"; } diff --git a/nixos/systems/tewi/home-assistant.nix b/nixos/systems/tewi/home-assistant.nix index edbdd679..8030987d 100644 --- a/nixos/systems/tewi/home-assistant.nix +++ b/nixos/systems/tewi/home-assistant.nix @@ -1,4 +1,22 @@ { config, lib, tf, ... }: { + # MDNS + services.avahi.enable = true; + + networks.gensokyo = { + tcp = [ + # Home Assistant + 8123 + # Tewi Homekit + 21063 + ]; + udp = [ + # Chromecast + [ 32768 60999 ] + # MDNS + 5353 + ]; + }; + kw.secrets.variables.ha-integration = { path = "secrets/home-assistant"; field = "notes"; @@ -14,31 +32,12 @@ preStart = lib.mkBefore '' rm ${config.services.home-assistant.configDir}/integration.json cp --no-preserve=mode ${config.secrets.files.ha-integration.path} ${config.services.home-assistant.configDir}/integration.json - ''; + ''; }; services.home-assistant = { enable = true; config = { - default_config = {}; - google_assistant = { - project_id = "gensokyo-5cfaf"; - service_account = "!include integration.json"; - }; - http = { - cors_allowed_origins = [ - "https://google.com" - "https://www.home-assistant.io" - ]; - use_x_forwarded_for = "true"; - trusted_proxies = [ - "127.0.0.0/24" - "200::/7" - "100.64.0.0/10" - "fd7a:115c:a1e0:ab12::/64" - ]; - }; - homeassistant = { name = "Gensokyo"; unit_system = "metric"; @@ -47,18 +46,94 @@ logger = { default = "info"; }; + http = { + cors_allowed_origins = [ + "https://google.com" + "https://www.home-assistant.io" + ]; + use_x_forwarded_for = "true"; + trusted_proxies = [ + "127.0.0.0/24" + "200::/7" + "100.64.0.0/10" + "fd7a:115c:a1e0:ab12::/64" + ]; + }; recorder = { db_url = "postgresql://@/hass"; - + auto_purge = true; + purge_keep_days = 14; + commit_interval = 1; + exclude = { + domains = [ + "automation" + "updater" + ]; + entity_globs = [ + "sensor.weather_*" + "sensor.date_*" + ]; + entities = [ + "sun.sun" + "sensor.last_boot" + "sensor.date" + "sensor.time" + ]; + event_types = [ + "call_service" + ]; + }; + }; + google_assistant = { + project_id = "gensokyo-5cfaf"; + service_account = "!include integration.json"; }; homekit = { name = "Tewi"; port = 21063; ip_address = "10.1.1.38"; }; + tts = [{ + platform = "google_translate"; + service_name = "google_say"; + }]; + automation = {}; + counter = {}; + device_tracker = {}; + energy = {}; + frontend = {}; + group = {}; + history = {}; + image = {}; + input_boolean = {}; + input_datetime = {}; + input_number = {}; + input_select = {}; + input_text = {}; + logbook = {}; + map = {}; + media_source = {}; + mobile_app = {}; + my = {}; + person = {}; + scene = {}; + script = {}; + ssdp = {}; + switch = {}; + stream = {}; + sun = {}; + system_health = {}; + tag = {}; + template = {}; + timer = {}; + webhook = {}; + wake_on_lan = {}; + zeroconf = {}; + zone = {}; }; extraPackages = python3Packages: with python3Packages; [ psycopg2 + aiohomekit securetar ]; extraComponents = [ @@ -80,4 +155,4 @@ "zeroconf" ]; }; - } +} diff --git a/nixos/systems/tewi/mosquitto.nix b/nixos/systems/tewi/mosquitto.nix index 207b1d7a..62454c55 100644 --- a/nixos/systems/tewi/mosquitto.nix +++ b/nixos/systems/tewi/mosquitto.nix @@ -1,4 +1,11 @@ { config, lib, tf, ... }: { + networks.gensokyo = { + tcp = [ + # Mosquitto + 1883 + ]; + }; + kw.secrets.variables.z2m-pass = { path = "secrets/mosquitto"; field = "z2m"; diff --git a/nixos/systems/tewi/nginx.nix b/nixos/systems/tewi/nginx.nix index cf5532cd..5002364d 100644 --- a/nixos/systems/tewi/nginx.nix +++ b/nixos/systems/tewi/nginx.nix @@ -12,9 +12,11 @@ with lib; ''; }; - network.firewall = { - public.tcp.ports = [ 443 80 ]; - private.tcp.ports = [ 443 80 ]; + networks.gensokyo = { + tcp = [ + 443 + 80 + ]; }; services.nginx = { @@ -36,34 +38,12 @@ with lib; #proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict"; ''; clientMaxBodySize = "512m"; - virtualHosts = { - "gensokyo.zone" = { - forceSSL = true; - enableACME = true; - locations."/" = { - root = pkgs.gensokyoZone; - }; - }; - "home.${config.network.dns.domain}" = { - forceSSL = true; - enableACME = true; - locations = { - "/" = { - proxyPass = "http://127.0.0.1:8123"; - extraConfig = '' - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_http_version 1.1; - ''; - }; - }; - }; + virtualHosts = { }; }; security.acme = { defaults.email = config.network.dns.email; - #email = config.network.dns.email; acceptTerms = true; }; } diff --git a/nixos/systems/tewi/nixos.nix b/nixos/systems/tewi/nixos.nix index b9f5c733..d9c67875 100644 --- a/nixos/systems/tewi/nixos.nix +++ b/nixos/systems/tewi/nixos.nix @@ -3,21 +3,21 @@ { imports = with meta; [ (modulesPath + "/installer/scan/not-detected.nix") + hardware.local nixos.network ./home-assistant.nix ./zigbee2mqtt.nix ./mosquitto.nix ./postgres.nix + ./nginx.nix ]; - deploy.tf = { - resources.tewi = { - provider = "null"; - type = "resource"; - connection = { - port = lib.head config.services.openssh.ports; - host = config.network.addresses.private.nixos.ipv4.address; - }; + networks = { + gensokyo = { + interfaces = [ + "eno1" + ]; + ipv4 = "10.1.1.38"; }; }; @@ -30,20 +30,6 @@ }; }; - network = { - firewall = { - public.interfaces = lib.singleton "eno1"; - }; - addresses = { - private = { - enable = true; - nixos = { - ipv4.address = "10.1.1.38"; - }; - }; - }; - }; - boot = { loader = { systemd-boot = { diff --git a/nixos/systems/tewi/zigbee2mqtt.nix b/nixos/systems/tewi/zigbee2mqtt.nix index a13af876..c6f6b7b9 100644 --- a/nixos/systems/tewi/zigbee2mqtt.nix +++ b/nixos/systems/tewi/zigbee2mqtt.nix @@ -1,4 +1,33 @@ { config, lib, tf, ... }: { + networks.gensokyo = { + tcp = [ + # Zigbee2MQTT Frontend + 8072 + ]; + }; + + kw.secrets.variables.z2m-mqtt-password = { + path = "secrets/mosquitto"; + field = "z2m"; + }; + + kw.secrets.variables.z2m-network-key = { + path = "secrets/zigbee2mqtt"; + field = "password"; + }; + + secrets.files.zigbee2mqtt-config = { + text = builtins.toJSON config.services.zigbee2mqtt.settings; + owner = "zigbee2mqtt"; + group = "zigbee2mqtt"; + }; + + secrets.files.zigbee2mqtt-secret = { + text = "network_key: ${tf.variables.z2m-network-key.ref}"; + owner = "zigbee2mqtt"; + group = "zigbee2mqtt"; + }; + services.zigbee2mqtt = { enable = true; settings = { @@ -23,33 +52,8 @@ }; }; -kw.secrets.variables.z2m-mqtt-password = { - path = "secrets/mosquitto"; - field = "z2m"; -}; - - kw.secrets.variables.z2m-network-key = { - path = "secrets/zigbee2mqtt"; - field = "password"; - }; - - secrets.files.zigbee2mqtt-config = { - text = builtins.toJSON config.services.zigbee2mqtt.settings; - owner = "zigbee2mqtt"; - group = "zigbee2mqtt"; - }; - - secrets.files.zigbee2mqtt-secret = { - text = "network_key: ${tf.variables.z2m-network-key.ref}"; - owner = "zigbee2mqtt"; - group = "zigbee2mqtt"; - }; - systemd.services.zigbee2mqtt.preStart = let cfg = config.services.zigbee2mqtt; in lib.mkForce '' cp --no-preserve=mode ${config.secrets.files.zigbee2mqtt-config.path} "${cfg.dataDir}/configuration.yaml" cp --no-preserve=mode ${config.secrets.files.zigbee2mqtt-secret.path} "${cfg.dataDir}/secret.yaml" ''; - - network.firewall.public.tcp.ports = [ 8123 8072 1883 21064 21063 ]; - network.firewall.private.tcp.ports = [ 8123 ]; } diff --git a/nixos/systems/yukari.nix b/nixos/systems/yukari.nix index c3f6e097..acf251d9 100644 --- a/nixos/systems/yukari.nix +++ b/nixos/systems/yukari.nix @@ -93,26 +93,9 @@ }; }; - network = { - addresses = { - private = { - enable = true; - nixos = { - ipv4.address = "100.98.152.108"; - }; - }; - }; - yggdrasil = { - enable = true; - pubkey = "4f8fb0817afcd6211fb6a2cac2893df7d3f12c5c99eed106718d7223468473b2"; - address = "201:c1c1:3dfa:140c:a77b:8125:74d4:f5db"; - listen.enable = false; - listen.endpoints = [ "tcp://0.0.0.0:0" ]; - }; - firewall = { - private.interfaces = singleton "yggdrasil"; - public.interfaces = singleton "eno1"; - }; + networks.chitei = { + interfaces = [ "eno1" ]; + ipv4 = "100.98.152.108"; }; system.stateVersion = "21.05"; diff --git a/outputs.nix b/outputs.nix index 1c76d126..f0e4c278 100644 --- a/outputs.nix +++ b/outputs.nix @@ -51,7 +51,6 @@ pulseaudio wireplumber alsa - yggdrasil bindings matrix-appservices matrix-synapse-appservices diff --git a/services/access.nix b/services/access.nix index f22fbd24..27cb3cc1 100644 --- a/services/access.nix +++ b/services/access.nix @@ -1,53 +1,50 @@ { config, lib, meta, pkgs, ... }: with lib; { - deploy.tf.dns.records.services_plex = { - inherit (config.network.dns) zone; - domain = "plex"; - cname = { inherit (config.network.addresses.public) target; }; - }; - - deploy.tf.dns.records.services_cloud = { - inherit (config.network.dns) zone; - domain = "cloud"; - cname = { inherit (config.network.addresses.public) target; }; - }; - - deploy.tf.dns.records.services_home = { - inherit (config.network.dns) zone; - domain = "home"; - cname = { inherit (config.network.addresses.public) target; }; - }; - - deploy.tf.dns.records.gensokyo_home = { - zone = "gensokyo.zone."; - domain = "home"; - cname = { inherit (config.network.addresses.public) target; }; - }; - - deploy.tf.dns.records.gensokyo_root_v4 = { - zone = "gensokyo.zone."; - a = { inherit (config.network.addresses.public.tf.ipv4) address; }; - }; - - deploy.tf.dns.records.gensokyo_root_v6 = { - zone = "gensokyo.zone."; - aaaa = { inherit (config.network.addresses.public.tf.ipv6) address; }; + domains = { + kittywitch-plex = { + network = "internet"; + type = "cname"; + domain = "plex"; + }; + kittywitch-home = { + network = "internet"; + type = "cname"; + domain = "home"; + }; + kittywitch-cloud = { + network = "internet"; + type = "cname"; + domain = "cloud"; + }; + gensokyo-root = { + network = "internet"; + type = "both"; + zone = "gensokyo.zone."; + }; + gensokyo-home = { + network = "internet"; + type = "cname"; + domain = "home"; + zone = "gensokyo.zone."; + }; + gensokyo-z2m = { + network = "internet"; + type = "cname"; + domain = "z2m"; + zone = "gensokyo.zone."; + }; }; services.nginx.virtualHosts = mkMerge [ { "gensokyo.zone" = { - forceSSL = true; - enableACME = true; locations."/" = { root = pkgs.gensokyoZone; }; }; "home.gensokyo.zone" = { - forceSSL = true; - enableACME = true; locations = { "/" = { - proxyPass = "http://${meta.tailnet.tewi.addresses.ipv4}:8123"; + proxyPass = meta.tailnet.tewi.pp 4 8123; extraConfig = '' proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; @@ -56,52 +53,46 @@ }; }; }; - "home.${config.network.dns.domain}" = { - forceSSL = true; - enableACME = true; + "home.${config.networking.domain}" = { locations = { "/" = { - proxyPass = "http://yukari.ygg.kittywit.ch:8123"; + proxyPass = meta.tailnet.yukari.pp 4 8123; extraConfig = '' proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; - proxy_http_version 1.1; + proxy_http_version 1.1; ''; }; }; }; - "cloud.${config.network.dns.domain}" = { - forceSSL = true; - enableACME = true; + "cloud.${config.networking.domain}" = { locations = { - "/".proxyPass = "http://cloud.int.kittywit.ch/"; + "/".proxyPass = meta.tailnet.yukari.ppp 4 80 "nextcloud/"; }; }; - "plex.${config.network.dns.domain}" = { - forceSSL = true; - enableACME = true; + "plex.${config.networking.domain}" = { locations = { "/" = { - proxyPass = "http://[${meta.network.nodes.nixos.yukari.network.addresses.yggdrasil.nixos.ipv6.address}]"; - extraConfig = '' - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_redirect off; - proxy_buffering off; - proxy_set_header X-Plex-Client-Identifier $http_x_plex_client_identifier; - proxy_set_header X-Plex-Device $http_x_plex_device; - proxy_set_header X-Plex-Device-Name $http_x_plex_device_name; - proxy_set_header X-Plex-Platform $http_x_plex_platform; - proxy_set_header X-Plex-Platform-Version $http_x_plex_platform_version; - proxy_set_header X-Plex-Product $http_x_plex_product; - proxy_set_header X-Plex-Token $http_x_plex_token; - proxy_set_header X-Plex-Version $http_x_plex_version; - proxy_set_header X-Plex-Nocache $http_x_plex_nocache; - proxy_set_header X-Plex-Provides $http_x_plex_provides; - proxy_set_header X-Plex-Device-Vendor $http_x_plex_device_vendor; - proxy_set_header X-Plex-Model $http_x_plex_model; - ''; - }; + proxyPass = meta.tailnet.yukari.pp 4 32400; + extraConfig = '' + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_redirect off; + proxy_buffering off; + proxy_set_header X-Plex-Client-Identifier $http_x_plex_client_identifier; + proxy_set_header X-Plex-Device $http_x_plex_device; + proxy_set_header X-Plex-Device-Name $http_x_plex_device_name; + proxy_set_header X-Plex-Platform $http_x_plex_platform; + proxy_set_header X-Plex-Platform-Version $http_x_plex_platform_version; + proxy_set_header X-Plex-Product $http_x_plex_product; + proxy_set_header X-Plex-Token $http_x_plex_token; + proxy_set_header X-Plex-Version $http_x_plex_version; + proxy_set_header X-Plex-Nocache $http_x_plex_nocache; + proxy_set_header X-Plex-Provides $http_x_plex_provides; + proxy_set_header X-Plex-Device-Vendor $http_x_plex_device_vendor; + proxy_set_header X-Plex-Model $http_x_plex_model; + ''; + }; }; }; } diff --git a/services/ha.nix b/services/ha.nix index 97e0fac9..85a59d1a 100644 --- a/services/ha.nix +++ b/services/ha.nix @@ -77,6 +77,5 @@ cp --no-preserve=mode ${config.secrets.files.zigbee2mqtt-secret.path} "${cfg.dataDir}/secret.yaml" ''; - network.firewall.public.tcp.ports = [ 8123 8072 1883 ]; - network.firewall.private.tcp.ports = [ 8123 ]; + networks.chitei.tcp = [ 8123 8072 1883 ]; } diff --git a/services/irlmail.nix b/services/irlmail.nix index 2f768df4..6a1e5ce2 100644 --- a/services/irlmail.nix +++ b/services/irlmail.nix @@ -1,8 +1,4 @@ { config, tf, meta, lib, ... }: with lib; { - dns.zones."inskip.me." = { - provider = "dns.katdns"; - }; - resources.gmail-mx = let zone = config.dns.zones."inskip.me."; in with zone; { @@ -25,11 +21,11 @@ dns.records = { services_inskip_a = { zone = "inskip.me."; - a.address = meta.network.nodes.nixos.marisa.network.addresses.public.nixos.ipv4.address; + a.address = meta.networks.internet.members.marisa.ipv4; }; services_inskip_aaaa = { zone = "inskip.me."; - aaaa.address = meta.network.nodes.nixos.marisa.network.addresses.public.nixos.ipv6.address; + aaaa.address = meta.networks.internet.members.marisa.ipv6; }; services_gmail_spf = { zone = "inskip.me."; diff --git a/services/kattv-ingest.nix b/services/kattv-ingest.nix index ad221fde..09ff1615 100644 --- a/services/kattv-ingest.nix +++ b/services/kattv-ingest.nix @@ -74,7 +74,7 @@ let { element.tcpserversink = { port = 8989; - host = config.network.addresses.yggdrasil.nixos.ipv6.address; + host = config.networks.tailscale.ipv4; }; } ]; diff --git a/services/kattv2-ingest.nix b/services/kattv2-ingest.nix index 2aecec87..1f40e039 100644 --- a/services/kattv2-ingest.nix +++ b/services/kattv2-ingest.nix @@ -74,7 +74,7 @@ let { element.tcpserversink = { port = 8990; - host = config.network.addresses.yggdrasil.nixos.ipv6.address; + host = config.networks.tailscale.ipv4; }; } ]; diff --git a/services/keycloak.nix b/services/keycloak.nix index c446233d..26f3cbfe 100644 --- a/services/keycloak.nix +++ b/services/keycloak.nix @@ -24,16 +24,15 @@ in { }; - network.extraCerts.domain-auth = "auth.${config.network.dns.domain}"; users.groups.domain-auth.members = [ "nginx" "openldap" "keycloak" ]; - security.acme.certs.domain-auth = { + /* security.acme.certs.domain-auth = { group = "domain-auth"; postRun = '' ${pkgs.adoptopenjdk-jre-bin}/bin/keytool -delete -alias auth.kittywit.ch -keypass ${keystore-pass} -storepass ${keystore-pass} -keystore ./trust-store.jks ${pkgs.adoptopenjdk-jre-bin}/bin/keytool -import -alias auth.${config.network.dns.domain} -noprompt -keystore trust-store.jks -keypass ${keystore-pass} -storepass ${keystore-pass} -file cert.pem chown acme:domain-auth ./trust-store.jks ''; - }; + }; */ users.groups.keycloak = { }; users.users.keycloak = { @@ -63,9 +62,9 @@ in { }; }; - deploy.tf.dns.records.services_keycloak = { - inherit (config.network.dns) zone; + domains.kittywitch-keycloak = { + network = "internet"; + type = "cname"; domain = "auth"; - cname = { inherit (config.network.addresses.public) target; }; }; } diff --git a/services/knot/default.nix b/services/knot/default.nix index 196253e9..f955f493 100644 --- a/services/knot/default.nix +++ b/services/knot/default.nix @@ -1,8 +1,6 @@ { config, lib, tf, pkgs, ... }: { - network.dns.enable = false; - kw.secrets.variables = { katdns-key-config = { path = "secrets/katdns"; @@ -10,9 +8,9 @@ }; }; - network.firewall.public = { - tcp.ports = [ 53 ]; - udp.ports = [ 53 ]; + networks.internet = { + tcp = [ 53 ]; + udp = [ 53 ]; }; /* environment.etc."katdns/zones/gensokyo.zone.zone".text = let diff --git a/services/knot/knot.yaml b/services/knot/knot.yaml index 6a1090a6..5fa0ffbd 100644 --- a/services/knot/knot.yaml +++ b/services/knot/knot.yaml @@ -5,8 +5,6 @@ remote: - id: benjojo-1 address: [ 185.230.223.84, 2a0c:2f07:4896:666:216:3eff:fedb:c742 ] - id: benjojo-2 - address: 185.236.240.26 - - id: benjojo-3 address: 185.230.223.7 acl: @@ -14,7 +12,7 @@ acl: key: dnsupdate.kittywit.ch. action: update - id: benjojo - remote: [ benjojo-1, benjojo-2, benjojo-3 ] + remote: [ benjojo-1, benjojo-2 ] action: transfer zone: @@ -24,7 +22,7 @@ zone: file: kittywit.ch.zone dnssec-signing: on module: mod-stats - notify: [ benjojo-1, benjojo-2, benjojo-3 ] + notify: [ benjojo-1, benjojo-2 ] zonefile-load: difference acl: [ benjojo, dnsupdate ] - domain: dork.dev @@ -33,7 +31,7 @@ zone: file: dork.dev.zone dnssec-signing: on module: mod-stats - notify: [ benjojo-1, benjojo-2, benjojo-3 ] + notify: [ benjojo-1, benjojo-2 ] zonefile-load: difference acl: [ benjojo, dnsupdate ] - domain: inskip.me @@ -42,7 +40,7 @@ zone: file: inskip.me.zone dnssec-signing: on module: mod-stats - notify: [ benjojo-1, benjojo-2, benjojo-3 ] + notify: [ benjojo-1, benjojo-2 ] zonefile-load: difference acl: [ benjojo, dnsupdate ] - domain: gensokyo.zone @@ -51,7 +49,7 @@ zone: file: gensokyo.zone.zone dnssec-signing: on module: mod-stats - notify: [ benjojo-1, benjojo-2, benjojo-3 ] + notify: [ benjojo-1, benjojo-2 ] zonefile-load: difference acl: [ benjojo, dnsupdate ] diff --git a/services/murmur.nix b/services/murmur.nix index ebe4edc0..55e80708 100644 --- a/services/murmur.nix +++ b/services/murmur.nix @@ -7,11 +7,9 @@ let forking = (cfg.logFile != null); in { - network.firewall = { - public = { - tcp.ports = singleton 64738; - udp.ports = singleton 64738; - }; + networks.internet = { + tcp = singleton 64738; + udp = singleton 64738; }; kw.secrets.variables = { @@ -107,26 +105,24 @@ in }; # Certs - - network.extraCerts.services_murmur = "voice.${config.network.dns.domain}"; +/* + network.extraCerts.services_murmur = "voice.${config.net"; users.groups."voice-cert".members = [ "nginx" "murmur" ]; security.acme.certs.services_murmur = { group = "voice-cert"; postRun = "systemctl restart murmur"; - extraDomainNames = [ config.network.dns.domain ]; + extraDomainNames = [ config.networks.internet.dn ]; + };*/ + + domains.kittywitch-murmur = { + network = "internet"; + type = "cname"; + domain = "voice"; }; - # DNS - deploy.tf.dns.records = { - services_murmur = { - inherit (config.network.dns) zone; - domain = "voice"; - cname = { inherit (config.network.addresses.public) target; }; - }; - services_murmur_tcp_srv = { - inherit (config.network.dns) zone; + inherit (config.networks.internet) zone; domain = "@"; srv = { service = "mumble"; @@ -134,12 +130,12 @@ in priority = 0; weight = 5; port = 64738; - target = "voice.${config.network.dns.zone}"; + target = kittywitch-murmur.target; }; }; services_murmur_udp_srv = { - inherit (config.network.dns) zone; + inherit (config.networks.internet) zone; domain = "@"; srv = { service = "mumble"; @@ -147,7 +143,7 @@ in priority = 0; weight = 5; port = 64738; - target = "voice.${config.network.dns.zone}"; + target = kittywitch-murmur.target; }; }; }; diff --git a/services/nextcloud.nix b/services/nextcloud.nix index 73d173ee..84c13801 100644 --- a/services/nextcloud.nix +++ b/services/nextcloud.nix @@ -1,12 +1,6 @@ { config, pkgs, lib, tf, kw, ... }: with lib; let cfg = config.services.nextcloud; in { - deploy.tf.dns.records.services_internal_cloud = { - inherit (config.network.dns) zone; - domain = "cloud.int"; - cname = { inherit (config.network.addresses.yggdrasil) target; }; - }; - kw.secrets.variables = mapListToAttrs (field: @@ -53,27 +47,27 @@ in { }; }; - services.nginx.virtualHosts."cloud.kittywit.ch".extraConfig = mkForce '' - index index.php index.html /index.php$request_uri; - add_header X-Content-Type-Options nosniff; - add_header X-XSS-Protection "1; mode=block"; - add_header X-Robots-Tag none; - add_header X-Download-Options noopen; - add_header X-Permitted-Cross-Domain-Policies none; - add_header X-Frame-Options sameorigin; - add_header Referrer-Policy no-referrer; - client_max_body_size ${cfg.maxUploadSize}; - fastcgi_buffers 64 4K; - fastcgi_hide_header X-Powered-By; - gzip on; - gzip_vary on; - gzip_comp_level 4; - gzip_min_length 256; - gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; - gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; - ${optionalString cfg.webfinger '' - rewrite ^/.well-known/host-meta /public.php?service=host-meta last; - rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last; - ''} - ''; + services.nginx.virtualHosts."${config.networks.tailscale.ipv4}".locations."/nextcloud".extraConfig = mkForce '' + index index.php index.html /index.php$request_uri; + add_header X-Content-Type-Options nosniff; + add_header X-XSS-Protection "1; mode=block"; + add_header X-Robots-Tag none; + add_header X-Download-Options noopen; + add_header X-Permitted-Cross-Domain-Policies none; + add_header X-Frame-Options sameorigin; + add_header Referrer-Policy no-referrer; + client_max_body_size ${cfg.maxUploadSize}; + fastcgi_buffers 64 4K; + fastcgi_hide_header X-Powered-By; + gzip on; + gzip_vary on; + gzip_comp_level 4; + gzip_min_length 256; + gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; + gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; + ${optionalString cfg.webfinger '' + rewrite ^/.well-known/host-meta /public.php?service=host-meta last; + rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last; + ''} + ''; } diff --git a/services/nfs.nix b/services/nfs.nix index e11f2684..5b4243c9 100644 --- a/services/nfs.nix +++ b/services/nfs.nix @@ -3,9 +3,8 @@ with lib; { - network.firewall = { - private.tcp.ports = [ 111 2049 ]; - public.tcp.ports = [ 111 2049 ]; + networks.chitei = { + tcp = [ 111 2049 ]; }; services.nfs.server.enable = true; diff --git a/services/nginx.nix b/services/nginx.nix index e946f9b2..39447eae 100644 --- a/services/nginx.nix +++ b/services/nginx.nix @@ -12,10 +12,11 @@ with lib; ''; }; - network.firewall = { - public.tcp.ports = [ 443 80 ]; - private.tcp.ports = [ 443 80 ]; - }; + networks = genAttrs [ "chitei" "gensokyo" "internet" "tailscale" ] (_: { + # NGINX + tcp = [ 80 443 ]; + udp = [ 80 443 ]; + }); services.nginx = { enable = true; @@ -39,8 +40,7 @@ with lib; }; security.acme = { - defaults.email = config.network.dns.email; - #email = config.network.dns.email; + defaults.email = "kat@inskip.me"; acceptTerms = true; }; } diff --git a/services/openldap/default.nix b/services/openldap/default.nix index a9304f69..edc9448c 100644 --- a/services/openldap/default.nix +++ b/services/openldap/default.nix @@ -1,5 +1,5 @@ { config, pkgs, tf, lib, ... }: with lib; { - network.firewall.public.tcp.ports = [ 636 ]; + networks.internet.tcp = [ 636 ]; services.openldap = { enable = true; diff --git a/services/plex.nix b/services/plex.nix index bcb9d993..f7404a7a 100644 --- a/services/plex.nix +++ b/services/plex.nix @@ -1,6 +1,6 @@ { config, kw, pkgs, lib, ... }: { - network.firewall.public.tcp.ports = [ 32400 ]; - services = { + networks.chitei.tcp = [ 32400 ]; + services = { plex = { enable = true; package = pkgs.plex.overrideAttrs (x: let @@ -16,28 +16,5 @@ } ); }; - - - nginx.virtualHosts."plex.kittywit.ch".locations."/" = { - proxyPass = "http://127.0.0.1:32400"; - extraConfig = '' - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_redirect off; - proxy_buffering off; - proxy_set_header X-Plex-Client-Identifier $http_x_plex_client_identifier; - proxy_set_header X-Plex-Device $http_x_plex_device; - proxy_set_header X-Plex-Device-Name $http_x_plex_device_name; - proxy_set_header X-Plex-Platform $http_x_plex_platform; - proxy_set_header X-Plex-Platform-Version $http_x_plex_platform_version; - proxy_set_header X-Plex-Product $http_x_plex_product; - proxy_set_header X-Plex-Token $http_x_plex_token; - proxy_set_header X-Plex-Version $http_x_plex_version; - proxy_set_header X-Plex-Nocache $http_x_plex_nocache; - proxy_set_header X-Plex-Provides $http_x_plex_provides; - proxy_set_header X-Plex-Device-Vendor $http_x_plex_device_vendor; - proxy_set_header X-Plex-Model $http_x_plex_model; - ''; - }; }; } diff --git a/services/prosody.nix b/services/prosody.nix index 94ae1140..7fd5c74a 100644 --- a/services/prosody.nix +++ b/services/prosody.nix @@ -3,7 +3,7 @@ with lib; { - network.firewall.public.tcp.ports = [ + networks.internet.tcp = [ 5000 5222 5223 @@ -65,33 +65,29 @@ with lib; [ config.network.dns.domain "upload.${config.network.dns.domain}" "conference.${config.network.dns.domain}" ]; }; +domains = rec { + kittywitch-prosody = { + network = "internet"; + type = "both"; + domain = "xmpp"; + }; + kittywitch-prosody-upload = { + network = "internet"; + type = "cname"; + domain = "upload"; + cname.target = kittywitch-prosody.target; + }; + kittywitch-prosody-conference = { + network = "internet"; + type = "cname"; + domain = "conference"; + cname.target = kittywitch-prosody.target; + }; +}; + deploy.tf.dns.records = { - services_prosody_xmpp = { - inherit (config.network.dns) zone; - domain = "xmpp"; - a.address = config.network.addresses.public.nixos.ipv4.selfaddress; - }; - - services_prosody_xmpp_v6 = { - inherit (config.network.dns) zone; - domain = "xmpp"; - aaaa.address = config.network.addresses.public.nixos.ipv6.selfaddress; - }; - - services_prosody_upload = { - inherit (config.network.dns) zone; - domain = "upload"; - cname.target = "xmpp.${config.network.dns.zone}"; - }; - - services_prosody_conference = { - inherit (config.network.dns) zone; - domain = "conference"; - cname.target = "xmpp.${config.network.dns.zone}"; - }; - services_prosody_muc = { - inherit (config.network.dns) zone; + inherit (config.domains.kittywitch-prosody) zone; domain = "conference"; srv = { service = "xmpp-server"; @@ -99,12 +95,12 @@ with lib; priority = 0; weight = 5; port = 5269; - target = "xmpp.${config.network.dns.zone}"; + target = config.domains.kittywitch-prosody.target; }; }; services_prosody_client_srv = { - inherit (config.network.dns) zone; + inherit (config.domains.kittywitch-prosody) zone; domain = "@"; srv = { service = "xmpp-client"; @@ -112,12 +108,12 @@ with lib; priority = 0; weight = 5; port = 5222; - target = "xmpp.${config.network.dns.zone}"; + target = config.domains.kittywitch-prosody.target; }; }; services_prosody_secure_client_srv = { - inherit (config.network.dns) zone; + inherit (config.domains.kittywitch-prosody) zone; domain = "@"; srv = { service = "xmpps-client"; @@ -125,12 +121,12 @@ with lib; priority = 0; weight = 5; port = 5223; - target = "xmpp.${config.network.dns.zone}"; + target = config.domains.kittywitch-prosody.target; }; }; services_prosody_server_srv = { - inherit (config.network.dns) zone; + inherit (config.domains.kittywitch-prosody) zone; domain = "@"; srv = { service = "xmpp-server"; @@ -138,7 +134,7 @@ with lib; priority = 0; weight = 5; port = 5269; - target = "xmpp.${config.network.dns.zone}"; + target = config.domains.kittywitch-prosody.target; }; }; }; diff --git a/services/syncplay.nix b/services/syncplay.nix index 970dd19d..f72e9e03 100644 --- a/services/syncplay.nix +++ b/services/syncplay.nix @@ -28,17 +28,17 @@ with lib; }; }; - network.firewall.public.tcp.ports = singleton 8999; + networks.internet.tcp = [ 8999 ]; services.nginx.virtualHosts."sync.${config.network.dns.domain}" = { enableACME = true; forceSSL = true; }; - deploy.tf.dns.records.services_syncplay = { - inherit (config.network.dns) zone; + domains.kittywitch-syncplay = { + network = "internet"; + type = "cname"; domain = "sync"; - cname = { inherit (config.network.addresses.public) target; }; }; secrets.files.syncplay-env = { diff --git a/services/tvheadend.nix b/services/tvheadend.nix index 7e873e2d..8d3bff46 100644 --- a/services/tvheadend.nix +++ b/services/tvheadend.nix @@ -7,14 +7,13 @@ users.users.tvheadend.group = "tvheadend"; users.groups.tvheadend = {}; - network.firewall = { - private = { - tcp.ports = [ 9981 9982 ]; - }; - public = { - tcp.ports = [ 9981 9982 ]; - }; - }; + networks.internet = { + tcp = [ + 9981 + 9982 + 5009 + ]; + }; systemd.services.antennas = { wantedBy = [ "plex.service" ]; diff --git a/services/website.nix b/services/website.nix index a29f5aa5..8eee5471 100644 --- a/services/website.nix +++ b/services/website.nix @@ -1,8 +1,6 @@ { config, lib, pkgs, ... }: { - network.dns.isRoot = true; - services.nginx.virtualHosts = { "${config.network.dns.domain}" = { root = pkgs.gensokyoZone; diff --git a/services/znc.nix b/services/znc.nix index 9f25ba10..d2e2b4b4 100644 --- a/services/znc.nix +++ b/services/znc.nix @@ -48,7 +48,8 @@ let in { - network.firewall.public.tcp.ports = singleton 5001; + # ZNC + networks.internet.tcp = singleton 5001; kw.secrets.variables = let diff --git a/targets/home.nix b/targets/home.nix index 19872eee..2e06111b 100644 --- a/targets/home.nix +++ b/targets/home.nix @@ -10,7 +10,11 @@ sensitive = true; export = true; }; - + acme.account = { + register = false; + emailAddress = "kat@inskip.me"; + accountKeyPem = config.resources.acme_private_key.refAttr "private_key_pem"; + }; providers.tailscale = { inputs = { api_key = config.variables.tailscale-apikey.ref; @@ -18,6 +22,14 @@ }; }; resources = { + acme_private_key = { + provider = "tls"; + type = "private_key"; + inputs = { + algorithm = "RSA"; + rsa_bits = 4096; + }; + }; tailnet_devices = { type = "devices"; provider = "tailscale"; diff --git a/tf b/tf index 58d25138..e4898b63 160000 --- a/tf +++ b/tf @@ -1 +1 @@ -Subproject commit 58d25138fdd294512a311a0fe3c92007f8d55f7a +Subproject commit e4898b63141b7be8bd96c0f91fecc807d732aa58 diff --git a/tf.nix b/tf.nix index d674064b..fa1ad35b 100644 --- a/tf.nix +++ b/tf.nix @@ -29,7 +29,7 @@ }; }; - dns.zones = genAttrs [ "kittywit.ch." "dork.dev." "gensokyo.zone." ] (_: { + dns.zones = genAttrs [ "inskip.me." "kittywit.ch." "dork.dev." "gensokyo.zone." ] (_: { provider = "dns.katdns"; }); }