diff --git a/lib.nix b/lib.nix index e4b26c84..355428a9 100644 --- a/lib.nix +++ b/lib.nix @@ -38,6 +38,7 @@ in { Std = inputs.std-fl.lib; lib = { inherit mkWinPath userIs eui64 toHexStringLower hexCharToInt; + inherit (inputs.arcexprs.lib) unmerged; }; generate = import ./generate.nix { inherit inputs tree; }; } diff --git a/modules/nixos/access.nix b/modules/nixos/access.nix index a1116458..c5b8dc4f 100644 --- a/modules/nixos/access.nix +++ b/modules/nixos/access.nix @@ -51,6 +51,14 @@ in { type = path; default = "/var/lib/localaddrs"; }; + reloadScript = mkOption { + type = path; + readOnly = true; + }; + nftablesInclude = mkOption { + type = lines; + readOnly = true; + }; }; }; @@ -95,20 +103,30 @@ in { ]; }; }; + localaddrs = { + nftablesInclude = mkBefore ('' + define localrange6 = 2001:568::/29 + '' + optionalString cfg.localaddrs.enable '' + include "${cfg.localaddrs.stateDir}/*.nft" + ''); + reloadScript = let + localaddrs-reload = pkgs.writeShellScript "localaddrs-reload" '' + ${config.systemd.package}/bin/systemctl reload localaddrs 2>/dev/null || + ${config.systemd.package}/bin/systemctl restart localaddrs || + true + ''; + in "${localaddrs-reload}"; + }; }; config.networking = { - nftables.ruleset = mkBefore ('' - define localrange6 = 2001:568::/29 - '' + optionalString cfg.localaddrs.enable '' - include "${cfg.localaddrs.stateDir}/*.nft" - ''); + nftables.ruleset = mkBefore cfg.localaddrs.nftablesInclude; firewall = { interfaces.local = { nftables.conditions = [ - "ip saddr { ${concatStringsSep ", " networking.access.cidrForNetwork.local.v4} }" + "ip saddr { ${concatStringsSep ", " cfg.cidrForNetwork.local.v4} }" (mkIf networking.enableIPv6 - "ip6 saddr { $localrange6, ${concatStringsSep ", " networking.access.cidrForNetwork.local.v6} }" + "ip6 saddr { $localrange6, ${concatStringsSep ", " cfg.cidrForNetwork.local.v6} }" ) ]; }; @@ -162,11 +180,6 @@ in { printf 'allow %s;\n' "$LOCALADDR4" >> ${cfg.localaddrs.stateDir}/allow.nginx.conf fi ''; - localaddrs-reload = pkgs.writeShellScript "localaddrs-reload" '' - ${config.systemd.package}/bin/systemctl reload localaddrs 2>/dev/null || - ${config.systemd.package}/bin/systemctl restart localaddrs || - true - ''; in { localaddrs = mkIf cfg.localaddrs.enable { unitConfig = { @@ -192,7 +205,7 @@ in { wants = [ "localaddrs.service" ]; serviceConfig = { ExecReload = mkBefore [ - "+${localaddrs-reload}" + "+${cfg.localaddrs.reloadScript}" ]; }; }; @@ -201,7 +214,7 @@ in { after = wants; serviceConfig = { ExecReload = mkBefore [ - "+${localaddrs-reload}" + "+${cfg.localaddrs.reloadScript}" ]; }; }; @@ -211,6 +224,7 @@ in { systemFor = hostName: inputs.self.nixosConfigurations.${hostName}.config; systemForOrNull = hostName: inputs.self.nixosConfigurations.${hostName}.config or null; in { + inherit (cfg) hostnameForNetwork cidrForNetwork localaddrs; systemFor = hostName: if hostName == networking.hostName then config else systemFor hostName; diff --git a/modules/nixos/github-runner.nix b/modules/nixos/github-runner.nix new file mode 100644 index 00000000..aafd4cbf --- /dev/null +++ b/modules/nixos/github-runner.nix @@ -0,0 +1,48 @@ +{ + inputs, + config, + lib, + ... +}: let + inherit (lib.options) mkOption; + inherit (lib.modules) mkIf mkDefault; + inherit (lib.attrsets) filterAttrs mapAttrs' nameValuePair; + inherit (inputs.self.lib.lib) unmerged; + cfg = config.services.github-runners; + nixosConfig = config; + enabledRunners = filterAttrs (_: runner: runner.enable) cfg; + runnerModule = { config, ... }: { + options = with lib.types; { + networkNamespace.name = mkOption { + type = nullOr str; + default = null; + }; + serviceSettings = mkOption { + type = unmerged.type; + default = { }; + }; + }; + config = { + serviceSettings = mkIf (config.networkNamespace.name != null) { + networkNamespace = { + name = mkDefault config.networkNamespace.name; + afterOnline = mkDefault true; + }; + }; + serviceOverrides = mkIf (config.user != null && nixosConfig.users.users ? ${config.user}) { + DynamicUser = false; + }; + }; + }; +in { + options = with lib.types; { + services.github-runners = mkOption { + type = attrsOf (submodule runnerModule); + }; + }; + config = { + systemd.services = mapAttrs' (name: runner: nameValuePair "github-runner-${name}" ( + unmerged.merge runner.serviceSettings + )) enabledRunners; + }; +} diff --git a/modules/nixos/network/deploy.nix b/modules/nixos/network/deploy.nix new file mode 100644 index 00000000..a5217b8d --- /dev/null +++ b/modules/nixos/network/deploy.nix @@ -0,0 +1,17 @@ +{ + config, + lib, + ... +}: let + inherit (lib.options) mkOption; +in { + options = with lib.types; { + deploy.system = mkOption { + type = unspecified; + readOnly = true; + }; + }; + config = { + deploy.system = config.system.build.toplevel; + }; +} diff --git a/modules/nixos/network/namespace.nix b/modules/nixos/network/namespace.nix new file mode 100644 index 00000000..7e0e3169 --- /dev/null +++ b/modules/nixos/network/namespace.nix @@ -0,0 +1,493 @@ +{ + inputs, + config, + pkgs, + lib, + utils, + ... +}: let + inherit (lib.options) mkOption mkEnableOption; + inherit (lib.modules) mkIf mkMerge mkBefore mkAfter mkDefault mkOptionDefault; + inherit (lib.attrsets) mapAttrs' mapAttrsToList listToAttrs nameValuePair attrValues; + inherit (lib.lists) singleton optional optionals filter concatMap; + inherit (lib.strings) concatStringsSep escapeShellArg; + inherit (utils) escapeSystemdExecArg; + inherit (inputs.self.lib.lib) unmerged; + inherit (config.services) tailscale; + inherit (config) networking; + inherit (networking) access; + enabledNamespaces = filter (ns: ns.enable) (attrValues networking.namespaces); + ip = "${pkgs.iproute2}/bin/ip"; + ip-n = namespace: "${ip} -n ${escapeShellArg namespace.name}"; + namespaceInterfaceModule = { config, namespace, name, ... }: { + options = with lib.types; { + name = mkOption { + type = str; + default = name; + }; + setupScript = mkOption { + type = lines; + }; + stopScript = mkOption { + type = lines; + }; + serviceName = mkOption { + type = str; + default = "${namespace.unitName}-interface-${config.name}"; + }; + serviceSettings = mkOption { + type = unmerged.type; + }; + }; + config = { + serviceSettings = rec { + bindsTo = [ "${namespace.unitName}.service" ]; + partOf = [ "${namespace.unitName}.target" ]; + after = bindsTo; + stopIfChanged = false; + restartIfChanged = false; + restartTriggers = [ + config.name + namespace.name + ]; + serviceConfig = { + RemainAfterExit = mkDefault true; + ExecStart = [ + ''${ip} link set dev ${escapeSystemdExecArg config.name} netns ${escapeSystemdExecArg namespace.name}'' + ]; + ExecStop = [ + ''-${ip-n namespace} link set dev ${escapeSystemdExecArg config.name} down'' + ''${ip-n namespace} link set dev ${escapeSystemdExecArg config.name} netns 1'' + ]; + }; + }; + }; + }; + groupModule = { config, namespace, ... }: { + options = with lib.types; { + id = mkOption { + type = int; + }; + serviceName = mkOption { + type = str; + default = "${namespace.unitName}-group-${toString config.id}"; + }; + serviceSettings = mkOption { + type = unmerged.type; + }; + }; + config = { + serviceSettings = rec { + bindsTo = [ "${namespace.unitName}.service" ]; + partOf = [ "${namespace.unitName}.target" ]; + after = bindsTo; + stopIfChanged = false; + restartIfChanged = false; + restartTriggers = [ + config.id + namespace.name + ]; + serviceConfig = { + RemainAfterExit = mkDefault true; + ExecStart = [ + ''${ip} link set group ${toString config.id} netns ${escapeSystemdExecArg namespace.name}'' + ]; + ExecStop = [ + ''-${ip-n namespace} link set group ${toString config.id} down'' + ''${ip-n namespace} link set group ${toString config.id} netns 1'' + ]; + }; + }; + }; + }; + namespaceModule = { config, name, ... }: let + linkGroupServices = optional (config.linkGroup != null) "${config.linkGroup.serviceName}.service"; + interfaceServices = mapAttrsToList (_: interface: "${interface.serviceName}.service") config.interfaces; + submoduleArgs = { ... }: { + config._module.args.namespace = config; + }; + in { + options = with lib.types; { + enable = mkEnableOption "network namespace" // { + default = true; + }; + resolvConf = mkOption { + type = lines; + default = '' + nameserver 1.1.1.1 + ''; + }; + nftables = { + enable = mkEnableOption "nftables"; + rejectLocaladdrs = mkEnableOption "localaddrs"; + ruleset = mkOption { + type = lines; + }; + serviceName = mkOption { + type = str; + default = "${config.unitName}-nftables"; + }; + serviceSettings = mkOption { + type = unmerged.type; + }; + extraInput = mkOption { + type = lines; + default = ""; + }; + extraOutput = mkOption { + type = lines; + default = ""; + }; + extraForward = mkOption { + type = lines; + default = ""; + }; + inputPolicy = mkOption { + type = str; + default = "drop"; + }; + outputPolicy = mkOption { + type = str; + default = "accept"; + }; + forwardPolicy = mkOption { + type = str; + default = "accept"; + }; + }; + dhcpcd = { + enable = mkEnableOption "DHCP"; + package = mkOption { + type = package; + default = pkgs.dhcpcd; + }; + configText = mkOption { + type = lines; + }; + extraConfig = mkOption { + type = lines; + default = ""; + }; + serviceName = mkOption { + type = str; + default = "${config.unitName}-dhcpcd"; + }; + serviceSettings = mkOption { + type = unmerged.type; + }; + }; + name = mkOption { + type = str; + default = name; + }; + linkGroup = mkOption { + type = let + module = submodule [ + groupModule + submoduleArgs + ]; + idOrModule = coercedTo int (id: { inherit id; }) module; + in nullOr idOrModule; + default = null; + }; + interfaces = mkOption { + type = attrsOf (submodule [ + namespaceInterfaceModule + submoduleArgs + ]); + default = { }; + }; + path = mkOption { + type = path; + default = "/run/netns/${config.name}"; + }; + configDir = mkOption { + type = str; + default = "netns/${config.name}"; + }; + configPath = mkOption { + type = path; + readOnly = true; + default = "/etc/${config.configDir}"; + }; + unitName = mkOption { + type = str; + default = "netns-${config.name}"; + }; + serviceSettings = mkOption { + type = unmerged.type; + }; + targetSettings = mkOption { + type = unmerged.type; + }; + configFiles = mkOption { + type = attrsOf unmerged.type; + }; + }; + config = { + serviceSettings = { + wants = [ "network.target" ]; + after = [ "network.target" ]; + stopIfChanged = false; + restartIfChanged = false; + serviceConfig = { + RemainAfterExit = mkDefault true; + ConfigurationDirectory = mkDefault config.configDir; + ExecStart = [ + ''${ip} netns add ${escapeSystemdExecArg config.name}'' + ]; + ExecStop = [ + ''${ip} netns delete ${escapeSystemdExecArg config.name}'' + ]; + }; + }; + targetSettings = { + wantedBy = [ "multi-user.target" ]; + bindsTo = [ "${config.unitName}.service" ]; + requires = linkGroupServices ++ interfaceServices; + wants = mkMerge [ + (mkIf config.dhcpcd.enable [ "${config.dhcpcd.serviceName}.service" ]) + (mkIf config.nftables.enable [ "${config.nftables.serviceName}.service" ]) + ]; + }; + configFiles = { + "resolv.conf".text = mkDefault config.resolvConf; + "dhcpcd.conf" = mkIf config.dhcpcd.enable { + text = mkDefault config.dhcpcd.configText; + }; + "rules.nft" = mkIf config.nftables.enable { + text = mkDefault config.nftables.ruleset; + }; + }; + nftables = { + ruleset = mkMerge [ + (mkIf config.nftables.rejectLocaladdrs ( + assert access.localaddrs.enable; mkBefore access.localaddrs.nftablesInclude + )) + '' + table inet filter { + chain input { + type filter hook input priority filter + policy ${config.nftables.inputPolicy} + + icmpv6 type { echo-request, echo-reply, mld-listener-query, mld-listener-report, mld-listener-done, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, packet-too-big } accept + icmp type echo-request accept + + ct state invalid drop + ct state established,related accept + + iifname lo accept + + # DHCPv6 + ip6 daddr fe80::/64 udp dport 546 accept + + ${config.nftables.extraInput} + + counter + } + chain output { + type filter hook output priority filter + policy ${config.nftables.outputPolicy} + + ${config.nftables.extraOutput} + + counter + } + chain forward { + type filter hook forward priority filter + policy ${config.nftables.forwardPolicy} + + ${config.nftables.extraForward} + + counter + } + } + '' + ]; + extraOutput = let + addrs4 = access.cidrForNetwork.local.v4 ++ optionals tailscale.enable access.cidrForNetwork.tail.v4; + addrs6 = access.cidrForNetwork.local.v6 ++ optionals tailscale.enable access.cidrForNetwork.tail.v6; + daddr4 = ''{ ${concatStringsSep ", " addrs4} }''; + daddr6 = ''{ ${concatStringsSep ", " addrs6} }''; + in mkIf config.nftables.rejectLocaladdrs (mkMerge [ + ''ct state { established, related } accept'' + '' + ip daddr ${daddr4} ip protocol tcp reject with tcp reset + ip daddr ${daddr4} drop + '' + (mkIf networking.enableIPv6 '' + ip6 daddr ${daddr6} ip6 nexthdr tcp reject with tcp reset + ip6 daddr ${daddr6} drop + '') + ]); + serviceSettings = rec { + bindsTo = [ "${config.unitName}.service" ]; + partOf = [ "${config.unitName}.target" ]; + wants = mkIf config.nftables.rejectLocaladdrs [ "localaddrs.service" ]; + after = mkMerge [ + bindsTo + wants + ]; + restartIfChanged = false; + reloadTriggers = [ + config.nftables.ruleset + ]; + serviceConfig = { + NetworkNamespacePath = mkOptionDefault config.path; + + Type = mkOptionDefault "oneshot"; + RemainAfterExit = mkOptionDefault true; + StateDirectory = mkOptionDefault config.nftables.serviceName; + + ExecStart = [ + "${pkgs.nftables}/bin/nft -f ${config.configPath}/rules.nft" + ]; + ExecReload = mkMerge [ + (mkIf config.nftables.rejectLocaladdrs [ "+${access.localaddrs.reloadScript}" ]) + [ + "${pkgs.nftables}/bin/nft flush ruleset" + "${pkgs.nftables}/bin/nft -f ${config.configPath}/rules.nft" + ] + ]; + ExecStop = [ + "${pkgs.nftables}/bin/nft flush ruleset" + ]; + }; + }; + }; + dhcpcd = { + serviceSettings = rec { + bindsTo = [ "${config.unitName}.service" ]; + partOf = [ "${config.unitName}.target" ]; + wants = linkGroupServices ++ interfaceServices; + after = bindsTo ++ wants ++ [ + (mkIf config.nftables.enable "${config.nftables.serviceName}.service") + ]; + stopIfChanged = false; + unitConfig.ConditionCapability = "CAP_NET_ADMIN"; + serviceConfig = { + NetworkNamespacePath = mkOptionDefault config.path; + BindReadOnlyPaths = [ + "${config.configPath}/resolv.conf:/etc/resolv.conf" + ]; + BindPaths = [ + "/run/${config.dhcpcd.serviceName}/:/run/dhcpcd" + "/var/lib/${config.dhcpcd.serviceName}/:/var/lib/dhcpcd" + "${config.configPath}/dhcpcd.conf:/etc/dhcpcd.conf" + ]; + + Type = mkOptionDefault "forking"; + Restart = mkOptionDefault "always"; + PIDFile = mkOptionDefault "/run/${config.dhcpcd.serviceName}/pid"; + RuntimeDirectory = mkOptionDefault config.dhcpcd.serviceName; + StateDirectory = mkOptionDefault config.dhcpcd.serviceName; + + ExecStart = [ + "@${config.dhcpcd.package}/sbin/dhcpcd dhcpcd --quiet --config ${config.configPath}/dhcpcd.conf" + ]; + ExecReload = [ + "${config.dhcpcd.package}/sbin/dhcpcd --rebind" + ]; + }; + }; + configText = mkMerge [ + '' + hostname + option domain_name_servers, domain_name, domain_search, host_name + option classless_static_routes, ntp_servers, interface_mtu + nohook lookup-hostname + slaac hwaddr + waitip + '' + (mkAfter config.dhcpcd.extraConfig) + ]; + }; + }; + }; + serviceModule = { config, name, ... }: let + cfg = config.networkNamespace; + hasNs = cfg.name != null; + ns = networking.namespaces.${cfg.name}; + in { + options.networkNamespace = with lib.types; { + enable = mkEnableOption "netns" // { + default = cfg.name != null; + }; + bindResolvConf = mkOption { + type = nullOr path; + }; + afterOnline = mkOption { + type = bool; + default = false; + }; + name = mkOption { + type = nullOr str; + default = null; + }; + path = mkOption { + type = nullOr path; + }; + }; + config = mkMerge [ + { + networkNamespace = mkMerge [ + { + path = mkOptionDefault null; + bindResolvConf = mkOptionDefault null; + } + (mkIf hasNs { + path = mkDefault ( + ns.path + ); + bindResolvConf = mkDefault ( + "${ns.configPath}/resolv.conf" + ); + }) + ]; + } + (mkIf cfg.enable rec { + wants = mkIf hasNs [ "${ns.unitName}.target" ]; + bindsTo = mkIf hasNs [ "${ns.unitName}.service" ]; + after = mkMerge [ + bindsTo + (mkIf (hasNs && cfg.afterOnline) [ + "${ns.unitName}.target" + ]) + ]; + serviceConfig = { + NetworkNamespacePath = mkOptionDefault cfg.path; + BindReadOnlyPaths = mkIf (cfg.bindResolvConf != null) [ + "${cfg.bindResolvConf}:/etc/resolv.conf" + ]; + }; + }) + ]; + }; +in { + options = with lib.types; { + networking.namespaces = mkOption { + type = attrsOf (submodule namespaceModule); + default = { }; + }; + systemd.services = mkOption { + type = attrsOf (submodule serviceModule); + }; + }; + config = { + systemd = { + services = listToAttrs (concatMap (ns: + singleton (nameValuePair ns.unitName (unmerged.merge ns.serviceSettings)) + ++ optional (ns.linkGroup != null) (nameValuePair ns.linkGroup.serviceName (unmerged.merge ns.linkGroup.serviceSettings)) + ++ mapAttrsToList (_: interface: nameValuePair interface.serviceName (unmerged.merge interface.serviceSettings)) ns.interfaces + ++ optional ns.dhcpcd.enable (nameValuePair ns.dhcpcd.serviceName (unmerged.merge ns.dhcpcd.serviceSettings)) + ++ optional ns.nftables.enable (nameValuePair ns.nftables.serviceName (unmerged.merge ns.nftables.serviceSettings)) + ) enabledNamespaces); + targets = listToAttrs (map (ns: nameValuePair ns.unitName ( + unmerged.merge ns.targetSettings + )) enabledNamespaces); + }; + environment.etc = mkMerge (map (ns: + mapAttrs' (name: file: nameValuePair "${ns.configDir}/${name}" (unmerged.merge file)) ns.configFiles + ) enabledNamespaces); + }; +} diff --git a/modules/nixos/network.nix b/modules/nixos/network/networks.nix similarity index 80% rename from modules/nixos/network.nix rename to modules/nixos/network/networks.nix index e52d7b13..5975b95f 100644 --- a/modules/nixos/network.nix +++ b/modules/nixos/network/networks.nix @@ -42,14 +42,9 @@ }; }; in { - options.deploy.system = mkOption { - type = lib.types.unspecified; - readOnly = true; - }; - options.systemd.network.networks = mkOption { - type = with lib.types; attrsOf (submodule networkModule); - }; - config = { - deploy.system = config.system.build.toplevel; + options = with lib.types; { + systemd.network.networks = mkOption { + type = attrsOf (submodule networkModule); + }; }; } diff --git a/nixos/github-runner/zone.nix b/nixos/github-runner/zone.nix new file mode 100644 index 00000000..4fa8bf0c --- /dev/null +++ b/nixos/github-runner/zone.nix @@ -0,0 +1,67 @@ +{ + config, + lib, + inputs, + ... +}: let + inherit (lib.options) mkOption mkEnableOption; + inherit (lib.modules) mkIf mkMerge mkDefault; + inherit (lib.attrsets) listToAttrs nameValuePair; + inherit (lib.lists) genList; + inherit (inputs.self.lib.lib) unmerged; + cfg = config.services.github-runner-zone; +in { + options.services.github-runner-zone = with lib.types; { + enable = mkEnableOption "github-runners.zone" // { + default = true; + }; + count = mkOption { + type = int; + default = 4; + }; + user = mkOption { + type = nullOr str; + default = "github-runner-zone"; + }; + runnerSettings = mkOption { + type = unmerged.type; + }; + }; + + config = { + services.github-runner-zone = { + runnerSettings = { + enable = mkDefault true; + extraLabels = [ "ubuntu-latest" ]; + tokenFile = mkDefault config.sops.secrets.github-runner-gensokyo-zone-token.path; + url = mkDefault "https://github.com/gensokyo-zone"; + user = mkDefault cfg.user; + extraEnvironment = { + GIT_TEXTDOMAINDIR = "${config.programs.git.package}/share/locale"; + }; + }; + }; + + services.github-runners = listToAttrs (genList (i: nameValuePair "zone-${toString i}" (mkMerge [ + (unmerged.merge cfg.runnerSettings) + { + name = mkDefault "${config.networking.hostName}-${toString i}"; + } + ])) cfg.count); + + users = mkIf (cfg.enable && cfg.user != null) { + users.${cfg.user} = { + group = cfg.user; + isSystemUser = true; + }; + groups.${cfg.user} = { }; + }; + + sops.secrets = { + github-runner-gensokyo-zone-token = mkIf cfg.enable { + sopsFile = mkDefault ../secrets/github-runner.yaml; + owner = mkIf (cfg.user != null) cfg.user; + }; + }; + }; +} diff --git a/nixos/secrets/github-runner.yaml b/nixos/secrets/github-runner.yaml new file mode 100644 index 00000000..fded6c35 --- /dev/null +++ b/nixos/secrets/github-runner.yaml @@ -0,0 +1,93 @@ +github-runner-gensokyo-zone-token: ENC[AES256_GCM,data:FbOUFltX1sfyYrP1KQfLr4zt/pMmdfWa4Kb9yRM=,iv:63Wr1pVE1hwlxKQibkH/mmPKWQTT7bkQID2B0C+InZw=,tag:ldSrm8+UAQVjFliDktmTqA==,type:str] +sops: + shamir_threshold: 1 + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age12ze362pu5mza6ef9akrptr7hfe4auaqul4rkta7kyy2tnrstqensgmujeq + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwV05jclI5SkpYcFZPN2lG + OEF1b1M2SjhwTmdQV2hCV3lwa1JrdlFDTm53CnM4UnVjczB4NWhvSWJZVHVkMWE3 + bEdOKzg0UG1xUE1WN2FmZ1NIQ1NYV3MKLS0tIEprYnBocGdZQXNtUDJOUHoyZkZk + SHpoanpielFuNnlLdW1tYlQ1RlFodlkKoLd3UweAWiNu99x/R/yf3GpbMoH4AZA0 + hSy8XKzeiJhLudk9lU4qZg/mHVq/XUAg3jWCOy5X/SyA5ZCUyF/Isw== + -----END AGE ENCRYPTED FILE----- + - recipient: age176uyyyk7veqnzmm8xzwfhf0u23m6hm02cldlfkldunqe6std0gcq6lg057 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRdzl4S0NiTytEdXVmNkRl + T3lNa0JtVk9IZkI2YVVWam00TjFiT3BkNFJBCklFM2dsOUFYVnJENlVFanVYVjdE + TDBVZ0twc1NNUzhJMFhFSzhpYUxUSTQKLS0tIDdPWFdhSDNIdG9CQzdOalJEK25Y + SDVFOXRvai9BMVVkNWdCeEYzT2ZQOUUKwhY5M5sjXj4At9b5DgC06sX0DozF6Nbr + gfXYsHURIWqmPU1FDyQqV2eYypjQv2jyPJviL9VbN71wPMvFtTsz+A== + -----END AGE ENCRYPTED FILE----- + - recipient: age10t6kc5069cyky929vvxk8aznqyxpkx3k5h5rmlyz83xtjmr22ahqe8mzes + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmK3Q3Y3lqSUY4a3liVmVD + ZnhnOUFRN2dQS2tmNDRMVU1CNW90SjZWSTBNCk5JQnVCMDE0T2k5UHArSnBEWUJE + L0xvMWZZZmRqbXlnZGFBQkw5NFRpMlkKLS0tIGVFdVA4M2NueWVqVC9TZXhIdHZM + aWRNSTBZc2ZxTTVMVkxnK1ljbzZQUWsKN3w3p1f8LDocZQVK/0Y1LoT+Cgwv5dwU + 3HPnlgBHVG/vHEnU2OVhNrx/QTQRrFi6K+WCKHZXqyvlr+5EfNJ2gA== + -----END AGE ENCRYPTED FILE----- + - recipient: age1a2quf2ekkj94ygu7wgvhrvh44fwn32c0l2cwvgvjh23wst90s54szdsvgr + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYV0pUNU83SU1NU3hiVzhq + NkMxeDFKaWw0ZUsxVlc1S3N3YUpycjdwUTNrCldNUmovelRXY2xBYVMvSU9UanI3 + T29KL2RkeFRDbVdkSWllZ21ybG1CYVEKLS0tIGNLeXJwdENFeitBbnhnL0RVektM + VklBV2hYcDluZ0xoaGFhYnNDMCtDM2sK5gHRBsp9TXhMJZwNuOBJpsoX1i1qFqqf + TLGwxqAOLCQdC/U9X5oNTHmDGSZbEGUTZ4LCboNdLjq/XSXxMI1btg== + -----END AGE ENCRYPTED FILE----- + - recipient: age16klpkaut5759dut8mdm3jn0rnp8w6kxyvs9n6ntqrdsayjtd7upqlvw489 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQNXFGZGdGMUZaOVdoL3N5 + REhEZmI0MHhmSExUVVlhV2ZNMkpkZ2x6T1FVCkpMQjZoZ3JXNzRJbjZxR0JGYkJu + R3NVUWJEWFM5eXZTbnBHY0xHZjNMNVUKLS0tIFhFelhDYjU2bHA2UzV1N1JvN2Uw + OFFicTNyNi9NYWNrejNQMzJDdXI3amcKwDnLGpKuq+dVRxTy8YRuqOCDu0RyTjHF + 6vp6MRH+7W7wL+1bsgvcmAx64gFBoiRVkg4rlVq1jHGT3Pv524FRIA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-02-18T19:35:22Z" + mac: ENC[AES256_GCM,data:Ow58/0zQTj4OP+rnRUupXsUEqD1YiT8iVcoGVbKYYTg8UJGiGaS5c5XjlwAKJsZZZw+g0V5hbnlLpz1oWPdqBdE+AShED9BuGsJkzULzx5wBdwlOgZ7iLDy4xWcrVHZBNL+k+TINLgoHwjxEAc6Z8QkPYqIK6MSAvblcNOViqIc=,iv:2822rfae+KVpfwOL7wck1GFIQCi7ZLNzaSyCT9kH5Uc=,tag:l29EJPG3ENBRPY/9odZQDQ==,type:str] + pgp: + - created_at: "2024-02-12T21:16:54Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hQIMA82M54yws73UAQ/7Bn8epjFDvldOZudmQqaFbPfFVf9rezBWV9PCcwaJTPL8 + oD0iS/xOe2iIuL2WVjjlQaspgyB1lS9hn0tCh1S6gSgrMuDPutUKMGClfZGabvQz + QsEQ7oT4/5R4fJChIGLH3Q+s85fbW4TP12fVGlBEhWsJvmlVCBjpSYIBXkAeOCTA + 8/hQvpQAhmTRWuPbpaTGsc2j07m1yJL4m4X4GL9GJVyEALabvIuhg+DjCao3jhea + njGOG1oyACJUN8mvem0CEz73y0I+4hk3x4E0xRh28Kbq5tJevA0e9+qyr7BDlnHN + lLh9aGX+23JxlxciydHo8JCaTIvarOmaiCF7zWK3S4lwY15NprY+X7cqm6YvMm8l + 9GkBudIrOObGfpz4mz5bFHBqyVQIdzGGO/j9AdM7Cv8U0cork0dYpXLq6RZvjJpp + xjd5AwqDWIbOlzPEeFy8Zqx0szZ/Ez43XVco/ZKlu7mOubBtf+RF1jqgnaBC3vo8 + RyWZ9zTHzVAH3rLJk53mMPCB2irvEd7hxSarwfYJWXWXalRte0ot0GJrx4laNcEc + qhFvLrT7jKqPV+2JdskbRlINDcclXiWarnydTCFvrXuEd5GP0SWZ7ufhOIVZr7W8 + WUP30GLJexpwQo4JogI4gBTOkXWAETCyCSyTUgvIGYqqhW7x9H/IwTJHkxp5J7jS + XgGg4EymlYKHd7htA5oxpDeuB/RuiPlkgGm2TwEkLoIK/ZajpaQVm5nCwn0snqGF + 5FaqovA/IGAdiAmxPs8Y1JrnhI2nqkB0lEDstG9JYGk59xo/mia0xgp8+dado7w= + =hbNW + -----END PGP MESSAGE----- + fp: CD8CE78CB0B3BDD4 + - created_at: "2024-02-12T21:16:54Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hQEMA2W9MER3HLb7AQgAypEPlI1ui5QeDVIP0l3DnBHF8zBqFx1/Jcd2Vj9l6ajw + eAQI4Ao02QLa1fJJGCY5noZajuqnoQxM0i191rp8n2EFtexmx5vjCWEi3SoGvG51 + QiuzpjgXNqUsQ/eaJNuvrXbNg/CpzlIbzmUPQ23lWr+bajsZ+DXVK50vJBylZeKo + Xt0k0xNYod2iIfYe3v85nL5/TyW00wY2xH34cnNhypJe41+Q3B6gZfXNMA+1bwof + aKCy06eOKpWMueWsY4X/m2SfQNLNeWdYwoKooyIV41aGh80I5RzJ681BIjy37vOn + FBpNAEe1SLGDhj9bX/mshRYefrF7fx31i/kIka5mHNJeAbRlvrBJ0ydRVPeNFsiw + 2Ozlc/i63ia/ZtW0ImlF4EQKTVyxWIXzAb7A2vcdHZKBPA+lXQ+7+yzBe8CA/uuZ + 3bljUY8U84ez6f7MRTZ+TRLd4Hh3ZHl2laMm3qQo1Q== + =9WtK + -----END PGP MESSAGE----- + fp: 65BD3044771CB6FB + unencrypted_suffix: _unencrypted + version: 3.8.1 diff --git a/systems/aya/nixos.nix b/systems/aya/nixos.nix index ec9d5196..6be17472 100644 --- a/systems/aya/nixos.nix +++ b/systems/aya/nixos.nix @@ -1,8 +1,5 @@ { - config, meta, - lib, - access, ... }: { imports = let @@ -12,8 +9,31 @@ nixos.base nixos.reisen-ct nixos.tailscale + nixos.github-runner.zone ]; + nix.gc = { + dates = "monthly"; + options = "--delete-older-than 30d"; + }; + + services.github-runner-zone = { + count = 16; + runnerSettings.networkNamespace.name = "ns1"; + }; + + networking.namespaces.ns1 = { + dhcpcd.enable = true; + nftables = { + enable = true; + rejectLocaladdrs = true; + serviceSettings = rec { + wants = [ "localaddrs.service" ]; + after = wants; + }; + }; + interfaces.eth1 = { }; + }; systemd.network.networks.eth0 = { name = "eth0"; matchConfig = { @@ -24,6 +44,16 @@ gateway = ["10.1.1.1"]; DHCP = "no"; }; + systemd.network.networks.eth1 = { + name = "eth1"; + matchConfig = { + MACAddress = "BC:24:11:C4:66:AA"; + Type = "ether"; + }; + DHCP = "no"; + slaac.enable = false; + mdns.enable = false; + }; sops.defaultSopsFile = ./secrets.yaml; diff --git a/tf/proxmox_vms.tf b/tf/proxmox_vms.tf index 6d3b9085..b8c455ea 100644 --- a/tf/proxmox_vms.tf +++ b/tf/proxmox_vms.tf @@ -144,12 +144,6 @@ resource "proxmox_virtual_environment_container" "aya" { } } ip_config { - ipv6 { - address = "auto" - } - ipv4 { - address = "dhcp" - } } } diff --git a/tree.nix b/tree.nix index 7c6c1812..eca3a87f 100644 --- a/tree.nix +++ b/tree.nix @@ -55,6 +55,7 @@ ]; }; }; + "modules/nixos/network".functor.enable = true; "modules/nixos/steam".functor.enable = true; "modules/meta".functor.enable = true; "modules/system".functor.enable = true;