diff --git a/.github/README.md b/.github/README.md index 99247e8..f59542a 100644 --- a/.github/README.md +++ b/.github/README.md @@ -171,14 +171,13 @@ |๐Ÿ  **treehouse** | NVIDIA DGX Spark | AI Workstation, remote builder, hm-only-reference | |๐Ÿ–ฅ๏ธ **summers** | ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM | Homeserver (microvms), remote builder, data storage | |๐Ÿ–ฅ๏ธ **winters** | ASRock J4105-ITX, 32GB RAM | Homeserver (IoT server in spe) | - |๐Ÿ–ฅ๏ธ **hintbooth** | HUNSN RM02, 8GB RAM | Router, DNS Resolver, home NGINX endpoint | + |๐Ÿ–ฅ๏ธ **hintbooth** | HUNSN RM02, 8GB RAM | Router | |โ˜๏ธ **stoicclub** | Cloud Server: 1 vCPUs, 8GB RAM | Authoritative DNS server | |โ˜๏ธ **liliputsteps** | Cloud Server: 1 vCPUs, 8GB RAM | SSH bastion | |โ˜๏ธ **twothreetunnel**| Cloud Server: 2 vCPUs, 8GB RAM | Service proxy | |โ˜๏ธ **eagleland** | Cloud Server: 2 vCPUs, 8GB RAM | Mailserver | - |โ˜๏ธ **moonside** | Cloud Server: 4 vCPUs, 24GB RAM | Game servers, syncthing + other lightweight services | + |โ˜๏ธ **moonside** | Cloud Server: 4 vCPUs, 24GB RAM | Gaming server, syncthing + lightweight services | |โ˜๏ธ **belchsfactory** | Cloud Server: 4 vCPUs, 24GB RAM | Hydra builder and nix binary cache | - |๐ŸชŸ **chaostheater** | Asus Z97-A, i7-4790k, GTX970, 32GB RAM | Home Game Streaming Server (Windows/AtlasOS, not nix-managed) | |๐Ÿ“ฑ **magicant** | Samsung Galaxy Z Flip 6 | Phone | |๐Ÿ’ฟ **drugstore** | - | NixOS-installer ISO for bootstrapping new hosts | |๐Ÿ’ฟ **brickroad** | - | Kexec tarball for bootstrapping low-memory machines | diff --git a/.sops.yaml b/.sops.yaml index 46194ef..e69d45d 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -19,8 +19,6 @@ keys: - &twothreetunnel age1g7atkxdlt4ymeh7v7aa2yzr2hq2qkvzrc4r49ugttm3n582ymv9qrmpk8d - &winters age1s0vssf9fey2l456hucppzx2x58xep279nsdcglvkqm30sr9ht37s8rvpza - &dgx age1ax5hqk6e2ekgfx5u7pl8ayc3vvhrehyvtvf07llaxhs5azpnny0qpltrns - - &hintbooth-adguardhome age1c2enwel9un28dcs4wg0vcyamx9a4a6g3walkhu8w5lqhmd804paq9d24as - - &hintbooth-nginx age1c2enwel9un28dcs4wg0vcyamx9a4a6g3walkhu8w5lqhmd804paq9d24as creation_rules: - path_regex: secrets/repo/[^/]+\.(yaml|json|env|ini|enc)$ key_groups: @@ -40,8 +38,6 @@ creation_rules: - *pyramid - *moonside - *dgx - - *hintbooth-adguardhome - - *hintbooth-nginx - path_regex: secrets/work/[^/]+\.(yaml|json|env|ini)$ key_groups: @@ -57,7 +53,6 @@ creation_rules: age: - *twothreetunnel - *eagleland - - *hintbooth-nginx - path_regex: hosts/nixos/x86_64-linux/pyramid/secrets/[^/]+\.(yaml|json|env|ini|enc)$ key_groups: @@ -136,22 +131,6 @@ creation_rules: age: - *hintbooth - - path_regex: hosts/nixos/x86_64-linux/hintbooth/secrets/adguardhome/[^/]+\.(yaml|json|env|ini|enc)$ - key_groups: - - pgp: - - *swarsel - age: - - *hintbooth - - *hintbooth-adguardhome - - - path_regex: hosts/nixos/x86_64-linux/hintbooth/secrets/nginx/[^/]+\.(yaml|json|env|ini|enc)$ - key_groups: - - pgp: - - *swarsel - age: - - *hintbooth - - *hintbooth-nginx - - path_regex: hosts/darwin/x86_64-darwin/nbm-imba-166/secrets/[^/]+\.(yaml|json|env|ini|enc)$ key_groups: - pgp: diff --git a/SwarselSystems.org b/SwarselSystems.org index 4942346..b0d8309 100644 --- a/SwarselSystems.org +++ b/SwarselSystems.org @@ -884,14 +884,13 @@ Here I give a brief overview over the host machines that I am using. This is hel |๐Ÿ  **treehouse** | NVIDIA DGX Spark | AI Workstation, remote builder, hm-only-reference | |๐Ÿ–ฅ๏ธ **summers** | ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM | Homeserver (microvms), remote builder, data storage | |๐Ÿ–ฅ๏ธ **winters** | ASRock J4105-ITX, 32GB RAM | Homeserver (IoT server in spe) | - |๐Ÿ–ฅ๏ธ **hintbooth** | HUNSN RM02, 8GB RAM | Router, DNS Resolver, home NGINX endpoint | + |๐Ÿ–ฅ๏ธ **hintbooth** | HUNSN RM02, 8GB RAM | Router | |โ˜๏ธ **stoicclub** | Cloud Server: 1 vCPUs, 8GB RAM | Authoritative DNS server | |โ˜๏ธ **liliputsteps** | Cloud Server: 1 vCPUs, 8GB RAM | SSH bastion | |โ˜๏ธ **twothreetunnel**| Cloud Server: 2 vCPUs, 8GB RAM | Service proxy | |โ˜๏ธ **eagleland** | Cloud Server: 2 vCPUs, 8GB RAM | Mailserver | - |โ˜๏ธ **moonside** | Cloud Server: 4 vCPUs, 24GB RAM | Game servers, syncthing + other lightweight services | + |โ˜๏ธ **moonside** | Cloud Server: 4 vCPUs, 24GB RAM | Gaming server, syncthing + lightweight services | |โ˜๏ธ **belchsfactory** | Cloud Server: 4 vCPUs, 24GB RAM | Hydra builder and nix binary cache | - |๐ŸชŸ **chaostheater** | Asus Z97-A, i7-4790k, GTX970, 32GB RAM | Home Game Streaming Server (Windows/AtlasOS, not nix-managed) | |๐Ÿ“ฑ **magicant** | Samsung Galaxy Z Flip 6 | Phone | |๐Ÿ’ฟ **drugstore** | - | NixOS-installer ISO for bootstrapping new hosts | |๐Ÿ’ฟ **brickroad** | - | Kexec tarball for bootstrapping low-memory machines | @@ -1935,252 +1934,191 @@ Another note concerning [[https://flake.parts/][flake-parts]]: inputs.nix-topology.flakeModule ]; - perSystem = { system, ... }: - let - inherit (self.outputs) lib; - in - { - topology.modules = [ - ({ config, ... }: - let - globals = self.outputs.globals.${system}; - inherit (config.lib.topology) - mkInternet - mkDevice - mkSwitch - mkRouter - mkConnection - ; - in - { - renderer = "elk"; + perSystem.topology.modules = [ + ({ config, ... }: + let + inherit (self.outputs) globals; + inherit (config.lib.topology) + mkInternet + mkDevice + mkSwitch + mkRouter + mkConnection + ; + in + { + renderer = "elk"; - networks = { - fritz-lan = { - name = "Fritz!Box LAN"; - inherit (globals.networks.home-lan) cidrv4 cidrv6; + networks = { + home-lan = { + name = "Home LAN"; + inherit (globals.networks.home-lan) cidrv4; + }; + fritz-wg = { + name = "Wireguard Tunnel for Fritzbox net access"; + inherit (globals.networks.twothreetunnel-wg) cidrv4; + }; + wg = { + name = "Wireguard Tunnel for proxy access"; + inherit (globals.networks.twothreetunnel-wg) cidrv4; + }; + }; + + nodes = { + internet = mkInternet { + connections = [ + (mkConnection "fritzbox" "dsl") + (mkConnection "moonside" "wan") + (mkConnection "belchsfactory" "wan") + (mkConnection "twothreetunnel" "wan") + (mkConnection "stoicclub" "wan") + (mkConnection "liliputsteps" "wan") + (mkConnection "eagleland" "wan") + (mkConnection "magicant" "wifi") + (mkConnection "toto" "bootstrapper") + (mkConnection "hotel" "demo host") + ]; + }; + + + fritzbox = mkRouter "FRITZ!Box" { + info = "FRITZ!Box 7682"; + image = "${self}/files/topology-images/hunsn.png"; + interfaceGroups = [ + [ + "eth1" + "eth2" + "eth3" + "eth-wan" + "wifi" + ] + [ "dsl" ] + ]; + + connections = { + eth1 = mkConnection "winters" "eth1"; + eth2 = mkConnection "switch-bedroom" "eth1"; + eth3 = mkConnection "switch-livingroom" "eth1"; + eth-wan = mkConnection "hintbooth" "eth6"; + wgPyramid = mkConnection "pyramid" "fritz-wg"; + wgMagicant = mkConnection "magicant" "fritz-wg"; + wifiPyramid = mkConnection "pyramid" "wifi"; + wifiMagicant = mkConnection "magicant" "wifi"; + wifiBakery = mkConnection "bakery" "wifi"; + wifiMachpizza = mkConnection "machpizza" "wifi"; + }; + interfaces = { + eth1 = { + addresses = [ globals.networks.home-lan.hosts.fritzbox.ipv4 ]; + network = "home-lan"; }; - services = { - name = "VLAN: Services"; - inherit (globals.networks.home-lan.vlans.services) cidrv4 cidrv6; + eth2 = { + addresses = [ globals.networks.home-lan.hosts.fritzbox.ipv4 ]; + network = "home-lan"; }; - home = { - name = "VLAN: Home"; - inherit (globals.networks.home-lan.vlans.home) cidrv4 cidrv6; + eth3 = { + addresses = [ globals.networks.home-lan.hosts.fritzbox.ipv4 ]; + network = "home-lan"; }; - devices = { - name = "VLAN: Devices"; - inherit (globals.networks.home-lan.vlans.devices) cidrv4 cidrv6; + eth-wan = { + addresses = [ globals.networks.home-lan.hosts.fritzbox.ipv4 ]; + network = "home-lan"; }; - guests = { - name = "VLAN: Guests"; - inherit (globals.networks.home-lan.vlans.guests) cidrv4 cidrv6; + wifi = { + addresses = [ globals.networks.home-lan.hosts.fritzbox.ipv4 ]; + virtual = true; + network = "home-lan"; }; fritz-wg = { - name = "WireGuard: Fritz!Box tunnel"; - inherit (globals.networks.fritz-wg) cidrv4 cidrv6; - }; - wgProxy = { - name = "WireGuard: Web proxy tunnel"; - inherit (globals.networks.twothreetunnel-wgProxy) cidrv4 cidrv6; - }; - wgHome = { - name = "WireGuard: Home proxy tunnel"; - inherit (globals.networks.home-wgHome) cidrv4 cidrv6; + addresses = [ globals.networks.fritz-wg.hosts.fritzbox.ipv4 ]; + network = "wg"; + virtual = true; + type = "wireguard"; }; }; + }; - nodes = { - internet = mkInternet { - connections = [ - (mkConnection "fritzbox" "dsl") - (mkConnection "magicant" "wifi") - (mkConnection "liliputsteps" "lan") - (mkConnection "treehouse" "eth1") - (mkConnection "toto" "bootstrapper") - (mkConnection "hotel" "demo host") - ]; - }; - - - fritzbox = mkRouter "FRITZ!Box" { - info = "FRITZ!Box 7682"; - image = "${self}/files/topology-images/Fritz!Box_7682.png"; - interfaceGroups = [ - [ - "eth1" - "eth2" - "eth3" - "eth-wan" - "wifi" - ] - [ "dsl" ] - ]; - - connections = { - eth1 = mkConnection "winters" "eth1"; - eth-wan = mkConnection "hintbooth" "lan"; - }; - interfaces = { - eth1 = { - addresses = [ globals.networks.home-lan.hosts.fritzbox.ipv4 ]; - network = "fritz-lan"; - }; - eth2 = { }; - eth3 = { }; - eth-wan = { - addresses = [ globals.networks.home-lan.hosts.fritzbox.ipv4 ]; - network = "fritz-lan"; - }; - wifi = { - addresses = [ globals.networks.home-lan.hosts.fritzbox.ipv4 ]; - virtual = true; - renderer.hidePhysicalConnections = true; - network = "fritz-lan"; - physicalConnections = [ - (mkConnection "pyramid" "wifi") - (mkConnection "bakery" "wifi") - (mkConnection "machpizza" "wifi") - ]; - }; - fritz-wg = { - addresses = [ globals.networks.fritz-wg.hosts.fritzbox.ipv4 ]; - network = "fritz-wg"; - virtual = true; - renderer.hidePhysicalConnections = true; - type = "wireguard"; - physicalConnections = [ - (mkConnection "pyramid" "fritz-wg") - (mkConnection "magicant" "fritz-wg") - ]; - }; - }; - }; - - switch-livingroom = mkSwitch "Switch Livingroom" { - info = "TL-SG108E"; - image = "${self}/files/topology-images/TL-SG108E.png"; - interfaceGroups = [ - # trunk - [ "eth1" ] - # devices - [ "eth2" ] - # home - [ "eth3" "eth8" ] - # guests - [ "eth4" "eth5" "eth6" "eth7" ] - ]; - interfaces = { - eth2 = { network = lib.mkForce "devices"; }; - eth3 = { network = lib.mkForce "home"; }; - eth7 = { network = lib.mkForce "guests"; }; - eth8 = { network = lib.mkForce "home"; }; - }; - connections = { - eth2 = mkConnection "nswitch" "eth1"; - eth3 = mkConnection "bakery" "eth1"; - eth7 = mkConnection "pc" "eth1"; - eth8 = mkConnection "pyramid" "eth1"; - }; - }; - - switch-bedroom = mkDevice "Switch Bedroom" { - info = "Cisco SG 200-08"; - image = "${self}/files/topology-images/Cisco_SG_200-08.png"; - interfaceGroups = [ - # trunk - [ "eth1" ] - # devices - [ "eth2" ] - # guests - [ "eth3" "eth4" "eth5" "eth6" "eth7" "eth8" ] - ]; - interfaces = { - eth2 = { network = lib.mkForce "devices"; }; - eth3 = { network = lib.mkForce "guests"; }; - }; - connections = { - eth2 = mkConnection "printer" "eth1"; - eth3 = mkConnection "machpizza" "eth1"; - }; - }; - - nswitch = mkDevice "Nintendo Switch" { - info = "Nintendo Switch"; - image = "${self}/files/topology-images/nintendo-switch.png"; - interfaces.eth1 = { }; - }; - - magicant = mkDevice "magicant" { - icon = "${self}/files/topology-images/phone.png"; - info = "Samsung Z Flip 6"; - image = "${self}/files/topology-images/zflip6.png"; - interfaces = { - wifi = { }; - fritz-wg.network = "fritz-wg"; - }; - }; - - machpizza = mkDevice "machpizza" { - info = "MacBook Pro 2016"; - icon = "devices.laptop"; - deviceIcon = "${self}/files/topology-images/mac.png"; - interfaces = { - eth1.network = "guests"; - wifi = { }; - }; - }; - - treehouse = mkDevice "treehouse" { - info = "NVIDIA DGX Spark"; - icon = "${self}/files/topology-images/home-manager.png"; - deviceIcon = "${self}/files/topology-images/dgxos.png"; - interfaces = { - eth1 = { }; - wifi = { }; - }; - services = { - ollama = { - name = "Ollama"; - icon = "${self}/files/topology-images/ollama.png"; - }; - openwebui = { - name = "Open WebUI"; - icon = "${self}/files/topology-images/openwebui.png"; - }; - comfyui = { - name = "Comfy UI"; - icon = "${self}/files/topology-images/comfyui.png"; - }; - }; - }; - - pc = mkDevice "Chaostheater" { - info = "ASUS Z97-A, i7-4790k, GTX970, 32GB RAM"; - icon = "${self}/files/topology-images/windows.png"; - deviceIcon = "${self}/files/topology-images/atlasos.png"; - services = { - sunshine = { - name = "Sunshine"; - icon = "${self}/files/topology-images/sunshine.png"; - }; - }; - interfaces.eth1.network = "guests"; - }; - - printer = mkDevice "Printer" { - info = "DELL C2665dnf"; - image = "${self}/files/topology-images/DELL-C2665dnf.png"; - interfaces.eth1 = { }; - }; - + switch-livingroom = mkSwitch "Switch Livingroom" { + info = "TL-SG108"; + image = "${self}/files/topology-images/TL-SG108.png"; + interfaceGroups = [ + [ + "eth1" + "eth2" + "eth3" + "eth4" + "eth5" + "eth6" + "eth7" + "eth8" + ] + ]; + connections = { + eth2 = mkConnection "nswitch" "eth1"; + eth7 = mkConnection "pc" "eth1"; + eth8 = mkConnection "pyramid" "eth1"; }; + }; - }) + switch-bedroom = mkSwitch "Switch Bedroom" { + info = "TL-SG1005D"; + image = "${self}/files/topology-images/TL-SG1005D.png"; + interfaceGroups = [ + [ + "eth1" + "eth2" + "eth3" + "eth4" + "eth5" + ] + ]; + connections.eth2 = mkConnection "printer" "eth1"; + connections.eth3 = mkConnection "machpizza" "eth1"; + }; + + nswitch = mkDevice "Nintendo Switch" { + info = "Nintendo Switch"; + image = "${self}/files/topology-images/nintendo-switch.png"; + interfaces.eth1 = { }; + }; + + magicant = mkDevice "magicant" { + icon = "${self}/files/topology-images/phone.png"; + info = "Samsung Z Flip 6"; + image = "${self}/files/topology-images/zflip6.png"; + interfaces = { + wifi = { }; + fritz-wg = { }; + }; + }; + + machpizza = mkDevice "machpizza" { + info = "MacBook Pro 2016"; + icon = "${self}/files/topology-images/mac.png"; + interfaces = { + eth1 = { }; + wifi = { }; + }; + }; + + pc = mkDevice "Windows Gaming Server" { + info = "i7-4790k, GTX970, 32GB RAM"; + image = "${self}/files/topology-images/pc.png"; + interfaces.eth1 = { }; + }; + + printer = mkDevice "Printer" { + info = "DELL C2665dnf"; + image = "${self}/files/topology-images/DELL-C2665dnf.png"; + interfaces.eth1 = { }; + }; + + }; + + }) - ]; - }; + ]; } #+end_src @@ -3015,9 +2953,9 @@ My work machine. Built for more security, this is the gold standard of my config topology.self = { interfaces = { - eth1.network = lib.mkForce "home"; - wifi = { }; - fritz-wg.network = "fritz-wg"; + "eth1" = { }; + "wifi" = { }; + "fritz-wg" = { }; }; }; @@ -3056,7 +2994,7 @@ My work machine. Built for more security, this is the gold standard of my config main = { # name = "BOE 0x0BC9 Unknown"; name = "BOE 0x0BC9"; - mode = "2560x1600"; + mode = "2560x1600"; # TEMPLATE scale = "1"; position = "2560,0"; workspace = "15:L"; @@ -3070,10 +3008,10 @@ My work machine. Built for more security, this is the gold standard of my config personal = true; }; - # networking.nftables = { - # enable = lib.mkForce false; - # firewall.enable = lib.mkForce false; - # }; + networking.nftables = { + enable = lib.mkForce false; + firewall.enable = lib.mkForce false; + }; } #+end_src @@ -3241,7 +3179,7 @@ My work machine. Built for more security, this is the gold standard of my config fileSystems = { "/persist".neededForBoot = true; "/home".neededForBoot = true; - "/".neededForBoot = true; # this is ok because this is not a impermanence host + "/".neededForBoot = true; "/var/log".neededForBoot = true; }; } @@ -3278,8 +3216,8 @@ My personal laptop. Closely follows the =pyramid= config, but leaves out some se ]; topology.self.interfaces = { - eth1.network = lib.mkForce "home"; - wifi = { }; + "eth1" = { }; + "wifi" = { }; }; swarselsystems = { @@ -3953,30 +3891,29 @@ This is my main server that I run at home. It handles most tasks that require bi :CUSTOM_ID: h:624b3c6a-6e31-4734-a6ea-7c5b461a3429 :END: #+begin_src nix-ts :tangle hosts/nixos/x86_64-linux/hintbooth/default.nix - { self, config, lib, minimal, confLib, globals, ... }: + { self, config, lib, minimal, confLib, ... }: { imports = [ ./hardware-configuration.nix ./disk-config.nix - "${self}/modules/nixos/optional/systemd-networkd-server-home.nix" - "${self}/modules/nixos/optional/microvm-host.nix" + "${self}/modules/nixos/optional/systemd-networkd-server.nix" + "${self}/modules/nixos/optional/systemd-networkd-vlan.nix" ]; topology.self = { interfaces = { - lan2.physicalConnections = [ { node = "summers"; interface = "eth1";} ]; - lan3.physicalConnections = [ { node = "summers"; interface = "eth2";} ]; - lan4.physicalConnections = [ { node = "switch-bedroom"; interface = "eth1";} ]; - lan5.physicalConnections = [ { node = "switch-livingroom"; interface = "eth1";} ]; + "eth1" = { }; + "eth2" = { }; + "eth3" = { }; + "eth4" = { }; + "eth5" = { }; + "eth6" = { }; }; }; - globals.general = { - homeProxy = config.node.name; - routerServer = config.node.name; - }; + globals.general.homeProxy = config.node.name; swarselsystems = { info = "HUNSN RM02, 8GB RAM"; @@ -3991,16 +3928,12 @@ This is my main server that I run at home. It handles most tasks that require bi swapSize = "8G"; networkKernelModules = [ "igb" ]; withMicroVMs = true; - localVLANs = map (name: "${name}") (builtins.attrNames globals.networks.home-lan.vlans); - initrdVLAN = "home"; server = { wireguard.interfaces = { wgHome = { isServer = true; peers = [ "winters" - "hintbooth-adguardhome" - "hintbooth-nginx" ]; }; }; @@ -4023,7 +3956,6 @@ This is my main server that I run at home. It handles most tasks that require bi guests = lib.mkIf (!minimal && config.swarselsystems.withMicroVMs) ( { } // confLib.mkMicrovm "adguardhome" - // confLib.mkMicrovm "nginx" ); } @@ -4194,8 +4126,8 @@ This is my main server that I run at home. It handles most tasks that require bi :CUSTOM_ID: h:f479a908-8071-4d69-97ea-c03bfd7b88bf :END: -#+begin_src nix-ts :tangle hosts/nixos/x86_64-linux/hintbooth/guests/adguardhome/default.nix - { self, config, lib, minimal, ... }: +#+begin_src nix-ts :tangle hosts/nixos/x86_64-linux/hintbooth/guests/adguardhome.nix + { self, lib, minimal, ... }: { imports = [ "${self}/profiles/nixos/microvm" @@ -4204,24 +4136,8 @@ This is my main server that I run at home. It handles most tasks that require bi swarselsystems = { isMicroVM = true; - isImpermanence = true; - proxyHost = "twothreetunnel"; - server = { - wireguard.interfaces = { - wgHome = { - isClient = true; - serverName = "hintbooth"; - }; - wgProxy = { - isClient = true; - serverName = "twothreetunnel"; - }; - }; - }; }; - globals.general.homeDnsServer = config.node.name; - } // lib.optionalAttrs (!minimal) { microvm = { @@ -4233,79 +4149,6 @@ This is my main server that I run at home. It handles most tasks that require bi microvm = true; }; - swarselmodules.server = { - adguardhome = true; - }; - - } - -#+end_src - -****** Nginx -:PROPERTIES: -:CUSTOM_ID: h:90dc7f71-f9da-49ef-b273-edfab7daaa05 -:END: - -#+begin_src nix-ts :tangle hosts/nixos/x86_64-linux/hintbooth/guests/nginx/default.nix - { self, config, lib, minimal, globals, confLib, ... }: - let - inherit (confLib.static) nginxAccessRules; - in - { - imports = [ - "${self}/profiles/nixos/microvm" - "${self}/modules/nixos" - ]; - - swarselsystems = { - isMicroVM = true; - isImpermanence = true; - proxyHost = config.node.name; - server = { - wireguard.interfaces = { - wgHome = { - isClient = true; - serverName = "hintbooth"; - }; - }; - }; - }; - - globals.general.homeWebProxy = config.node.name; - - } // lib.optionalAttrs (!minimal) { - - microvm = { - mem = 3072 * 1; - vcpu = 1; - }; - - swarselprofiles = { - microvm = true; - }; - - swarselmodules.server = { - nginx = true; - }; - - services.nginx = { - upstreams.fritzbox = { - servers.${globals.networks.home-lan.hosts.fritzbox.ipv4} = { }; - }; - virtualHosts.${globals.services.fritzbox.domain} = { - useACMEHost = globals.domains.main; - forceSSL = true; - acmeRoot = null; - locations."/" = { - proxyPass = "http://fritzbox"; - proxyWebsockets = true; - }; - extraConfig = '' - proxy_ssl_verify off; - '' + nginxAccessRules; - }; - }; - } #+end_src @@ -4811,7 +4654,7 @@ This machine mainly acts as my proxy server to stand before my local machines. postgresql = true; attic = true; garage = true; - hydra = true; + hydra = false; }; } @@ -4986,7 +4829,6 @@ This machine mainly acts as my proxy server to stand before my local machines. ./disk-config.nix "${self}/modules/nixos/optional/systemd-networkd-server.nix" - "${self}/modules/nixos/optional/nix-topology-self.nix" ]; topology.self = { @@ -5184,7 +5026,7 @@ This machine mainly acts as my proxy server to stand before my local machines. :END: #+begin_src nix-ts :tangle hosts/nixos/aarch64-linux/liliputsteps/default.nix - { self, config, lib, minimal, ... }: + { self, lib, minimal, ... }: { imports = [ ./hardware-configuration.nix @@ -5196,16 +5038,6 @@ This machine mainly acts as my proxy server to stand before my local machines. topology.self = { icon = "devices.cloud-server"; - interfaces.ProxyJump = { - virtual = true; - physicalConnections = [ - (config.lib.topology.mkConnection "moonside" "lan") - (config.lib.topology.mkConnection "twothreetunnel" "lan") - (config.lib.topology.mkConnection "belchsfactory" "lan") - (config.lib.topology.mkConnection "stoicclub" "lan") - (config.lib.topology.mkConnection "eagleland" "wan") - ]; - }; }; swarselsystems = { @@ -5413,10 +5245,7 @@ This machine mainly acts as my proxy server to stand before my local machines. icon = "devices.cloud-server"; }; - globals.general = { - webProxy = config.node.name; - oauthServer = config.node.name; - }; + globals.general.webProxy = config.node.name; swarselsystems = { flakePath = "/root/.dotfiles"; @@ -5439,7 +5268,6 @@ This machine mainly acts as my proxy server to stand before my local machines. "winters" "belchsfactory" "eagleland" - "hintbooth-adguardhome" ]; }; }; @@ -6654,7 +6482,6 @@ in (splitPath "services.kanidm.provision.systems.oauth2") (splitPath "sops.secrets") (splitPath "swarselsystems.server.dns") - (splitPath "topology.self.services") ] ++ expandOptions (splitPath "networking.nftables.firewall") [ "zones" "rules" ] ++ expandOptions (splitPath "services.firezone.gateway") [ "enable" "name" "apiUrl" "tokenFile" "package" "logLevel" ] @@ -7557,7 +7384,7 @@ Normally, doing that also resets the lecture that happens on the first use of =s { config, lib, ... }: let mapperTarget = lib.swarselsystems.mkIfElse config.swarselsystems.isCrypted "/dev/mapper/cryptroot" "/dev/disk/by-label/nixos"; - inherit (config.swarselsystems) isImpermanence isCrypted isBtrfs; + inherit (config.swarselsystems) isImpermanence isCrypted; in { options.swarselmodules.impermanence = lib.mkEnableOption "impermanence config"; @@ -7573,7 +7400,7 @@ Normally, doing that also resets the lecture that happens on the first use of =s # So if it doesn't run, the btrfs system effectively acts like a normal system # Taken from https://github.com/NotAShelf/nyx/blob/2a8273ed3f11a4b4ca027a68405d9eb35eba567b/modules/core/common/system/impermanence/default.nix boot.tmp.useTmpfs = lib.mkIf (!isImpermanence) true; - boot.initrd.systemd = lib.mkIf (isImpermanence && isBtrfs) { + boot.initrd.systemd = lib.mkIf isImpermanence { enable = true; services.rollback = { description = "Rollback BTRFS root subvolume to a pristine state"; @@ -9337,9 +9164,6 @@ Auto login for the initial session. #+end_src **** Firezone Client -:PROPERTIES: -:CUSTOM_ID: h:4d018a21-637b-4c7d-b9c9-7f1b95144a07 -:END: #+begin_src nix-ts :tangle modules/nixos/client/firezone-client.nix @@ -9460,8 +9284,6 @@ This is a collection of packages that are useful for server-type hosts that do n sops tmux busybox - ndisc6 - tcpdump swarsel-deploy ] ++ lib.optionals withHomeManager [ swarsel-gens @@ -9662,7 +9484,7 @@ This is a collection of packages that are useful for server-type hosts that do n }; }; config = { - extraConfig = lib.mkIf topmod.config.defaultStapling (lib.mkBefore '' + extraConfig = lib.mkIf topmod.config.defaultStapling (lib.mkAfter '' ssl_stapling on; ssl_stapling_verify on; resolver 1.1.1.1 8.8.8.8 valid=300s; @@ -9934,20 +9756,19 @@ Restricts access to the system by the nix build user as per https://discourse.ni } #+end_src -**** Network settings (globals.networks population) +**** Network settings :PROPERTIES: :CUSTOM_ID: h:0ff3acc5-9ce8-4b22-a2e2-f6f1e69d47a5 :END: Generate hostId using =head -c4 /dev/urandom | od -A none -t x4= -This section is mainly used to populate entries in =globals.networks= with the interfaces defined in the local secrets of the respective host. Also, we expose some convenient values under =globals.hosts= and setup basic networking. - #+begin_src nix-ts :tangle modules/nixos/server/network.nix { lib, config, ... }: let netConfig = config.repo.secrets.local.networking; netPrefix = "${if config.swarselsystems.isCloud then config.node.name else "home"}"; + # netName = "${netPrefix}-${config.swarselsystems.server.localNetwork}"; in { options = { @@ -9973,6 +9794,11 @@ This section is mainly used to populate entries in =globals.networks= with the i swarselsystems.server.localNetwork = netConfig.localNetwork or ""; + # globals.networks.${netName}.hosts.${config.node.name} = { + # inherit (netConfig.networks.${netConfig.localNetwork}) id; + # mac = netConfig.networks.${netConfig.localNetwork}.mac or null; + # }; + globals.networks = lib.mapAttrs' (netName: _: lib.nameValuePair "${netPrefix}-${netName}" { @@ -9985,8 +9811,7 @@ This section is mainly used to populate entries in =globals.networks= with the i netConfig.networks; globals.hosts.${config.node.name} = { - defaultGateway4 = netConfig.defaultGateway4 or null; - defaultGateway6 = netConfig.defaultGateway6 or null; + inherit (config.repo.secrets.local.networking) defaultGateway4; wanAddress4 = netConfig.wanAddress4 or null; wanAddress6 = netConfig.wanAddress6 or null; isHome = if (netPrefix == "home") then true else false; @@ -10048,9 +9873,6 @@ I also take some precautions in how I get networking information during stage 1. subnetMask = globals.networks.${config.swarselsystems.server.netConfigName}.subnetMask4; gatewayIp = globals.hosts.${config.node.name}.defaultGateway4; - inherit (globals.general) routerServer; - isRouter = config.node.name == routerServer; - hostKeyPathBase = "/etc/secrets/initrd/ssh_host_ed25519_key"; hostKeyPath = if config.swarselsystems.isImpermanence then @@ -10089,7 +9911,7 @@ I also take some precautions in how I get networking information during stage 1. }; boot = lib.mkIf (!config.swarselsystems.isClient) { - kernelParams = lib.mkIf (!config.swarselsystems.isCloud && ((config.swarselsystems.localVLANs == []) || isRouter)) [ + kernelParams = lib.mkIf (!config.swarselsystems.isCloud) [ "ip=${localIp}::${gatewayIp}:${subnetMask}:${config.networking.hostName}::none" ]; initrd = { @@ -10218,110 +10040,102 @@ In order to define a new wireguard interface, I have to: inherit (cfg) interfaces; ifaceList = builtins.attrValues interfaces; in - { - options = { - swarselmodules.server.${serviceName} = - lib.mkEnableOption "enable ${serviceName} settings"; + { + options = { + swarselmodules.server.${serviceName} = + lib.mkEnableOption "enable ${serviceName} settings"; - swarselsystems.server.wireguard = { - interfaces = let - topConfig = config; - in lib.mkOption { - type = lib.types.attrsOf (lib.types.submodule ({ config, name, ... }: { - options = { - isServer = lib.mkEnableOption "set this interface as a wireguard server"; - isClient = lib.mkEnableOption "set this interface as a wireguard client"; + swarselsystems.server.wireguard = { + interfaces = let + topConfig = config; + in lib.mkOption { + type = lib.types.attrsOf (lib.types.submodule ({ config, name, ... }: { + options = { + isServer = lib.mkEnableOption "set this interface as a wireguard server"; + isClient = lib.mkEnableOption "set this interface as a wireguard client"; - serverName = lib.mkOption { - type = lib.types.str; - default = if config.isServer then topConfig.node.name else ""; - description = "Hostname of the WireGuard server this interface connects to (when isClient = true)."; - }; - - serverNetConfigPrefix = lib.mkOption { - type = lib.types.str; - default = - let - serverCfg = nodes.${config.serverName}.config; - in - if serverCfg.swarselsystems.isCloud - then serverCfg.node.name - else "home"; - readOnly = true; - description = "Prefix used to look up the server network in globals.networks.\"-wg\"."; - }; - - ifName = lib.mkOption { - type = lib.types.str; - default = name; - description = "Name of the WireGuard interface."; - }; - - port = lib.mkOption { - type = lib.types.int; - default = servicePort; - description = "Port of the WireGuard interface."; - }; - - peers = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = lib.attrNames (lib.filterAttrs (name: _: name != topConfig.node.name) globals.networks."${config.serverNetConfigPrefix}-${config.ifName}".hosts); - description = "WireGuard peer config names of this wireguardinterface."; - }; + serverName = lib.mkOption { + type = lib.types.str; + default = if config.isServer then topConfig.node.name else ""; + description = "Hostname of the WireGuard server this interface connects to (when isClient = true)."; }; - })); - default = { }; - description = "WireGuard interfaces defined on this host."; - }; + + serverNetConfigPrefix = lib.mkOption { + type = lib.types.str; + default = + let + serverCfg = nodes.${config.serverName}.config; + in + if serverCfg.swarselsystems.isCloud + then serverCfg.node.name + else "home"; + readOnly = true; + description = "Prefix used to look up the server network in globals.networks.\"-wg\"."; + }; + + ifName = lib.mkOption { + type = lib.types.str; + default = name; + description = "Name of the WireGuard interface."; + }; + + port = lib.mkOption { + type = lib.types.int; + default = servicePort; + description = "Port of the WireGuard interface."; + }; + + peers = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = lib.attrNames (lib.filterAttrs (name: _: name != topConfig.node.name) globals.networks."${config.serverNetConfigPrefix}-${config.ifName}".hosts); + description = "WireGuard peer config names of this wireguardinterface."; + }; + }; + })); + default = { }; + description = "WireGuard interfaces defined on this host."; }; }; + }; - config = lib.mkIf config.swarselmodules.server.${serviceName} { + config = lib.mkIf config.swarselmodules.server.${serviceName} { - assertions = lib.concatLists ( - lib.flip lib.mapAttrsToList interfaces ( - ifName: ifCfg: + assertions = lib.concatLists ( + lib.flip lib.mapAttrsToList interfaces ( + ifName: ifCfg: let assertionPrefix = "While evaluating the wireguard network ${ifName}:"; in - [ - { - assertion = ifCfg.isServer || (ifCfg.isClient && ifCfg.serverName != ""); - message = "${assertionPrefix}: This node must either be a server for the wireguard network or a client with serverName set."; - } - { - assertion = lib.stringLength ifName < 16; - message = "${assertionPrefix}: The specified linkName '${ifName}' is too long (must be max 15 characters)."; - } - ] - ) - ); - - topology.self.interfaces = lib.mapAttrs' - (wgName: _: - lib.nameValuePair "${wgName}" { - network = wgName; - } - ) - config.swarselsystems.server.wireguard.interfaces; - - environment.systemPackages = with pkgs; [ - wireguard-tools - ]; - - sops.secrets = - lib.mkMerge ( [ { - wireguard-private-key = { - inherit sopsFile; - owner = serviceUser; - group = serviceGroup; - mode = "0600"; - }; + assertion = ifCfg.isServer || (ifCfg.isClient && ifCfg.serverName != ""); + message = "${assertionPrefix}: This node must either be a server for the wireguard network or a client with serverName set."; } - ] ++ (map - (i: + { + assertion = lib.stringLength ifName < 16; + message = "${assertionPrefix}: The specified linkName '${ifName}' is too long (must be max 15 characters)."; + } + ] + ) + ); + + environment.systemPackages = with pkgs; [ + wireguard-tools + ]; + + sops.secrets = + lib.mkMerge ( + [ + { + wireguard-private-key = { + inherit sopsFile; + owner = serviceUser; + group = serviceGroup; + mode = "0600"; + }; + } + ] ++ (map + (i: let clientSecrets = lib.optionalAttrs i.isClient { @@ -10346,26 +10160,26 @@ In order to define a new wireguard interface, I have to: }) i.peers)); in - clientSecrets // serverSecrets - ) - ifaceList) - ); - - networking.firewall = { - checkReversePath = lib.mkIf (lib.any (i: i.isClient) ifaceList) "loose"; - allowedUDPPorts = lib.mkMerge ( - lib.flip lib.mapAttrsToList interfaces ( - _: ifCfg: - lib.optional ifCfg.isServer ifCfg.port + clientSecrets // serverSecrets ) - ); - }; + ifaceList) + ); - networking.nftables.firewall = { - zones = lib.mkMerge - ( - lib.flip lib.mapAttrsToList interfaces ( - ifName: ifCfg: + networking.firewall = { + checkReversePath = lib.mkIf (lib.any (i: i.isClient) ifaceList) "loose"; + allowedUDPPorts = lib.mkMerge ( + lib.flip lib.mapAttrsToList interfaces ( + _: ifCfg: + lib.optional ifCfg.isServer ifCfg.port + ) + ); + }; + + networking.nftables.firewall = { + zones = lib.mkMerge + ( + lib.flip lib.mapAttrsToList interfaces ( + ifName: ifCfg: { ${ifName}.interfaces = [ ifName ]; } @@ -10374,30 +10188,30 @@ In order to define a new wireguard interface, I have to: let peerNet = globals.networks."${ifCfg.serverNetConfigPrefix}-${ifName}".hosts.${peer}; in - lib.nameValuePair "${ifName}-node-${peer}" { - parent = ifName; - ipv4Addresses = lib.optional (peerNet.ipv4 != null) peerNet.ipv4; - ipv6Addresses = lib.optional (peerNet.ipv6 != null) peerNet.ipv6; - } + lib.nameValuePair "${ifName}-node-${peer}" { + parent = ifName; + ipv4Addresses = lib.optional (peerNet.ipv4 != null) peerNet.ipv4; + ipv6Addresses = lib.optional (peerNet.ipv6 != null) peerNet.ipv6; + } ) ifCfg.peers) - ) - ); - rules = lib.mkMerge ( - lib.flip lib.mapAttrsToList interfaces ( - ifName: ifCfg: + ) + ); + rules = lib.mkMerge ( + lib.flip lib.mapAttrsToList interfaces ( + ifName: ifCfg: let inherit (config.networking.nftables.firewall) localZoneName; netCfg = globals.networks."${ifCfg.serverNetConfigPrefix}-${ifName}"; in - { - "${ifName}-to-${localZoneName}" = { - inherit (netCfg.firewallRuleForAll) allowedTCPPorts allowedUDPPorts allowedTCPPortRanges allowedUDPPortRanges; - from = [ ifName ]; - to = [ localZoneName ]; - ignoreEmptyRule = true; - }; - } + { + "${ifName}-to-${localZoneName}" = { + inherit (netCfg.firewallRuleForAll) allowedTCPPorts allowedUDPPorts allowedTCPPortRanges allowedUDPPortRanges; + from = [ ifName ]; + to = [ localZoneName ]; + ignoreEmptyRule = true; + }; + } // lib.listToAttrs (map (peer: lib.nameValuePair "${ifName}-node-${peer}-to-${localZoneName}" ( @@ -10410,75 +10224,75 @@ In order to define a new wireguard interface, I have to: ) ) ifCfg.peers) - ) - ); - }; + ) + ); + }; - systemd.network = { - enable = true; + systemd.network = { + enable = true; - networks = lib.mkMerge (map - (i: + networks = lib.mkMerge (map + (i: let inherit (i) ifName; in - { - "50-${ifName}" = { - matchConfig.Name = ifName; - linkConfig = { - MTUBytes = 1408; # TODO: figure out where we lose those 12 bits (8 from pppoe maybe + ???) - }; - - address = [ - globals.networks."${i.serverNetConfigPrefix}-${ifName}".hosts.${config.node.name}.cidrv4 - globals.networks."${i.serverNetConfigPrefix}-${ifName}".hosts.${config.node.name}.cidrv6 - ]; + { + "50-${ifName}" = { + matchConfig.Name = ifName; + linkConfig = { + MTUBytes = 1408; # TODO: figure out where we lose those 12 bits (8 from pppoe maybe + ???) }; - }) - ifaceList); - netdevs = lib.mkMerge (map - (i: + address = [ + globals.networks."${i.serverNetConfigPrefix}-${ifName}".hosts.${config.node.name}.cidrv4 + globals.networks."${i.serverNetConfigPrefix}-${ifName}".hosts.${config.node.name}.cidrv6 + ]; + }; + }) + ifaceList); + + netdevs = lib.mkMerge (map + (i: let inherit (i) ifName; in - { - "50-${ifName}" = { - netdevConfig = { - Kind = "wireguard"; - Name = ifName; - }; + { + "50-${ifName}" = { + netdevConfig = { + Kind = "wireguard"; + Name = ifName; + }; - wireguardConfig = { - ListenPort = lib.mkIf i.isServer servicePort; + wireguardConfig = { + ListenPort = lib.mkIf i.isServer servicePort; - PrivateKeyFile = config.sops.secrets.wireguard-private-key.path; + PrivateKeyFile = config.sops.secrets.wireguard-private-key.path; - RouteTable = lib.mkIf i.isClient "main"; - }; + RouteTable = lib.mkIf i.isClient "main"; + }; - wireguardPeers = - lib.optionals i.isClient [ - { - PublicKey = - builtins.readFile "${self}/secrets/public/wg/${i.serverName}.pub"; + wireguardPeers = + lib.optionals i.isClient [ + { + PublicKey = + builtins.readFile "${self}/secrets/public/wg/${i.serverName}.pub"; - PresharedKeyFile = - config.sops.secrets."wireguard-${i.serverName}-${config.node.name}-${i.ifName}-presharedKey".path; + PresharedKeyFile = + config.sops.secrets."wireguard-${i.serverName}-${config.node.name}-${i.ifName}-presharedKey".path; - Endpoint = - "server.${i.serverName}.${globals.domains.main}:${toString servicePort}"; + Endpoint = + "server.${i.serverName}.${globals.domains.main}:${toString servicePort}"; - PersistentKeepalive = 25; + PersistentKeepalive = 25; - AllowedIPs = - let - wgNetwork = globals.networks."${i.serverNetConfigPrefix}-${i.ifName}"; - in - (lib.optional (wgNetwork.cidrv4 != null) wgNetwork.cidrv4) + AllowedIPs = + let + wgNetwork = globals.networks."${i.serverNetConfigPrefix}-${i.ifName}"; + in + (lib.optional (wgNetwork.cidrv4 != null) wgNetwork.cidrv4) ++ (lib.optional (wgNetwork.cidrv6 != null) wgNetwork.cidrv6); - } - ] + } + ] ++ lib.optionals i.isServer (map (clientName: { PublicKey = @@ -10492,18 +10306,18 @@ In order to define a new wireguard interface, I have to: clientInWgNetwork = globals.networks."${i.serverNetConfigPrefix}-${i.ifName}".hosts.${clientName}; in - (lib.optional (clientInWgNetwork.ipv4 != null) - (lib.net.cidr.make 32 clientInWgNetwork.ipv4)) + (lib.optional (clientInWgNetwork.ipv4 != null) + (lib.net.cidr.make 32 clientInWgNetwork.ipv4)) ++ (lib.optional (clientInWgNetwork.ipv6 != null) (lib.net.cidr.make 128 clientInWgNetwork.ipv6)); }) i.peers); - }; - }) - ifaceList); - }; + }; + }) + ifaceList); }; - } + }; + } #+end_src **** BTRFS @@ -10528,44 +10342,12 @@ In order to define a new wireguard interface, I have to: :CUSTOM_ID: h:b54f2bbb-0088-46b2-957d-fd8234b772c3 :END: -This is the configuration to make [[#h:58c7563e-6954-42e6-a622-9d06523e8e24][Hintbooth (Router: HUNSN RM02)]] act as the router for my internal network. This is not a reusable module and highly adapted to its hardware. Below is a rough sketch of the functionality: - - - six LAN ports, five of which are bridged - - lan1โ€“lan5 are enslaved into said bridge and behave as a single VLANโ€‘aware switch - - all VLANs are defined under =globals.networks.home-lan.vlans= - - for each VLAN, a routed interface me-${vlanName} is created on the router (NOTE: this interface also serves as the communication link to the local microvms - the respective extra interfaces are defined in [[#h:049fc27e-a28f-4ff0-b5f0-d81401bdd56f][systemd-networkd (server home)]]) - - RA and forwarding are enabled on these me-* interfaces so the router advertises vlanCfg.cidrv6 and routes between VLANs / WAN / WireGuard - - the sixth LAN port is used as the WAN / untrusted uplink to the =Fritz!Box= - - the mapping from MAC addresses to interfaces is defined in =config.repo.secrets.local.networking.networks..mac= (and performed in [[#h:99bf6c0e-2566-4a50-b219-fb6a7d4fb2cd][systemd-networkd (base)]] using =renameInterfacesByMac=) - - connectivity to microvms should not be lost in case there is no cable connected to the router - - this is achieved by connecting the veth interface pair veth-br / veth-int - - veth-br is part of the bridge and carries all VLANs tagged, as if it were another physical switch port - - veth-int stays on the host side and is used as the internal attachment point for microvms / guests - - ConfigureWithoutCarrier and ActivationPolicy = "always-up" are used so that the bridge and veth side stay UP; this however does not guarantee connectivity by itself as the kernel will not route packets if the underlying interface is not up (see also [[#h:049fc27e-a28f-4ff0-b5f0-d81401bdd56f][systemd-networkd (server home)]]) - - nftables firewall is derived from the same VLAN definitions: - - a zone =vlan-*= is created for each VLAN and bound to =me-*=, as well as zones for WAN, WG, and DNS - - all internal =vlan-*= zones are allowed to go to untrusted; NAT is implemented via a custom postrouting chain that masquerades both IPv4 and IPv6 traffic - - any VLAN with internet access is allowed to reach AdGuardHome for DNS (access-adguardhome-dns) - - this is important so that we can make use of the internal nginx instance to prevent bottlenecks over the web proxy - - policy between internal networks: - - the home VLAN is allowed to access the services and devices VLANs - - the services VLAN is allowed to reach selected ports on local (currently wireguard) - - WireGuard peers in wgHome are allowed to talk to each other (wgHome โ†’ wgHome) - - global IPv4/IPv6 forwarding is enabled via boot.kernel.sysctl so this host acts as the main router between all VLANs, the WireGuard network, and the WAN (untrusted) +This is the configuration to make [[#h:58c7563e-6954-42e6-a622-9d06523e8e24][Hintbooth (Router: HUNSN RM02)]] act as the router for my internal network. This is not a reusable module and highly adapted to its hardware. #+begin_src nix-ts :tangle modules/nixos/server/router.nix - { lib, config, globals, confLib, ... }: + { lib, config, globals, ... }: let serviceName = "router"; - bridgeVLANs = lib.mapAttrsToList - (_: vlan: { - VLAN = vlan.id; - }) - globals.networks.home-lan.vlans; - selectVLANs = vlans: map (vlan: { VLAN = globals.networks.home-lan.vlans.${vlan}.id; }) vlans; - lan5VLANs = selectVLANs [ "home" "devices" "guests" ]; - lan4VLANs = selectVLANs [ "home" "services" ]; - inherit (confLib.gen { }) homeDnsServer; in { options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; @@ -10573,27 +10355,13 @@ This is the configuration to make [[#h:58c7563e-6954-42e6-a622-9d06523e8e24][Hin { services.avahi.reflector = true; - topology.self.interfaces = (lib.mapAttrs' - (vlanName: _: - lib.nameValuePair "vlan-${vlanName}" { - network = lib.mkForce vlanName; - } - ) - globals.networks.home-lan.vlans) // (lib.mapAttrs' - (vlanName: _: - lib.nameValuePair "me-${vlanName}" { - network = lib.mkForce vlanName; - } - ) - globals.networks.home-lan.vlans); - networking.nftables = { firewall = { zones = { untrusted.interfaces = [ "lan" ]; wgHome.interfaces = [ "wgHome" ]; - adguardhome.ipv4Addresses = [ globals.networks.home-lan.vlans.services.hosts.${homeDnsServer}.ipv4 ]; - adguardhome.ipv6Addresses = [ globals.networks.home-lan.vlans.services.hosts.${homeDnsServer}.ipv6 ]; + adguardhome.ipv4Addresses = [ globals.networks.home-lan.vlans.services.hosts.hintbooth-adguardhome.ipv4 ]; + adguardhome.ipv6Addresses = [ globals.networks.home-lan.vlans.services.hosts.hintbooth-adguardhome.ipv6 ]; } // lib.flip lib.concatMapAttrs globals.networks.home-lan.vlans ( vlanName: _: { @@ -10603,7 +10371,7 @@ This is the configuration to make [[#h:58c7563e-6954-42e6-a622-9d06523e8e24][Hin rules = { masquerade-internet = { - from = map (name: "vlan-${name}") (globals.general.internetVLANs); + from = map (name: "vlan-${name}") (builtins.attrNames globals.networks.home-lan.vlans); to = [ "untrusted" ]; # masquerade = true; NOTE: custom rule below for ip4 + ip6 late = true; # Only accept after any rejects have been processed @@ -10612,7 +10380,7 @@ This is the configuration to make [[#h:58c7563e-6954-42e6-a622-9d06523e8e24][Hin # Allow access to the AdGuardHome DNS server from any VLAN that has internet access access-adguardhome-dns = { - from = map (name: "vlan-${name}") (globals.general.internetVLANs); + from = map (name: "vlan-${name}") (builtins.attrNames globals.networks.home-lan.vlans); to = [ "adguardhome" ]; verdict = "accept"; }; @@ -10632,7 +10400,7 @@ This is the configuration to make [[#h:58c7563e-6954-42e6-a622-9d06523e8e24][Hin services-to-local = { from = [ "vlan-services" ]; to = [ "local" ]; - allowedUDPPorts = [ 52829 547 ]; + allowedUDPPorts = [ 52829 ]; }; # Forward traffic between wireguard participants @@ -10650,7 +10418,7 @@ This is the configuration to make [[#h:58c7563e-6954-42e6-a622-9d06523e8e24][Hin late = true; rules = lib.forEach - (map (name: "vlan-${name}") (globals.general.internetVLANs)) + (map (name: "vlan-${name}") (builtins.attrNames globals.networks.home-lan.vlans)) ( zone: lib.concatStringsSep " " [ @@ -10672,68 +10440,7 @@ This is the configuration to make [[#h:58c7563e-6954-42e6-a622-9d06523e8e24][Hin systemd.network = { wait-online.anyInterface = true; - - netdevs = { - "10-veth" = { - netdevConfig = { - Kind = "veth"; - Name = "veth-br"; - }; - peerConfig = { - Name = "veth-int"; - }; - }; - "20-br" = { - netdevConfig = { - Kind = "bridge"; - Name = "br"; - }; - bridgeConfig = { - VLANFiltering = true; - }; - }; - }; networks = { - "40-br" = { - matchConfig.Name = "br"; - bridgeConfig = { }; - linkConfig = { - ActivationPolicy = "always-up"; - RequiredForOnline = "no"; - }; - networkConfig = { - ConfigureWithoutCarrier = true; - LinkLocalAddressing = "no"; - }; - }; - "15-veth-br" = { - matchConfig.Name = "veth-br"; - - linkConfig = { - RequiredForOnline = "no"; - }; - - networkConfig = { - Bridge = "br"; - }; - inherit bridgeVLANs; - }; - "15-veth-int" = { - matchConfig.Name = "veth-int"; - - linkConfig = { - ActivationPolicy = "always-up"; - RequiredForOnline = "no"; - }; - - networkConfig = { - ConfigureWithoutCarrier = true; - LinkLocalAddressing = "no"; - }; - - vlan = map (name: "vlan-${name}") (builtins.attrNames globals.networks.home-lan.vlans); - }; - # br "30-lan1" = { matchConfig.MACAddress = config.repo.secrets.local.networking.networks.lan1.mac; linkConfig.RequiredForOnline = "enslaved"; @@ -10741,9 +10448,7 @@ This is the configuration to make [[#h:58c7563e-6954-42e6-a622-9d06523e8e24][Hin Bridge = "br"; ConfigureWithoutCarrier = true; }; - inherit bridgeVLANs; }; - # wifi "30-lan2" = { matchConfig.MACAddress = config.repo.secrets.local.networking.networks.lan2.mac; linkConfig.RequiredForOnline = "enslaved"; @@ -10751,9 +10456,7 @@ This is the configuration to make [[#h:58c7563e-6954-42e6-a622-9d06523e8e24][Hin Bridge = "br"; ConfigureWithoutCarrier = true; }; - inherit bridgeVLANs; }; - # summers "30-lan3" = { matchConfig.MACAddress = config.repo.secrets.local.networking.networks.lan3.mac; linkConfig.RequiredForOnline = "enslaved"; @@ -10761,9 +10464,7 @@ This is the configuration to make [[#h:58c7563e-6954-42e6-a622-9d06523e8e24][Hin Bridge = "br"; ConfigureWithoutCarrier = true; }; - inherit bridgeVLANs; }; - # winters "30-lan4" = { matchConfig.MACAddress = config.repo.secrets.local.networking.networks.lan4.mac; linkConfig.RequiredForOnline = "enslaved"; @@ -10771,9 +10472,7 @@ This is the configuration to make [[#h:58c7563e-6954-42e6-a622-9d06523e8e24][Hin Bridge = "br"; ConfigureWithoutCarrier = true; }; - bridgeVLANs = lan4VLANs; }; - # lr "30-lan5" = { matchConfig.MACAddress = config.repo.secrets.local.networking.networks.lan5.mac; linkConfig.RequiredForOnline = "enslaved"; @@ -10781,38 +10480,11 @@ This is the configuration to make [[#h:58c7563e-6954-42e6-a622-9d06523e8e24][Hin Bridge = "br"; ConfigureWithoutCarrier = true; }; - bridgeVLANs = lan5VLANs; }; - } // lib.flip lib.concatMapAttrs globals.networks.home-lan.vlans ( - vlanName: vlanCfg: { - "40-me-${vlanName}" = lib.mkForce { - address = [ - vlanCfg.hosts.${config.node.name}.cidrv4 - vlanCfg.hosts.${config.node.name}.cidrv6 - ]; - matchConfig.Name = "me-${vlanName}"; - networkConfig = { - IPv4Forwarding = "yes"; - IPv6PrivacyExtensions = "yes"; - IPv6SendRA = true; - IPv6AcceptRA = false; - }; - ipv6Prefixes = [ - { - Prefix = vlanCfg.cidrv6; - } - ]; - ipv6SendRAConfig = { - Managed = true; # set RA M flag -> DHCPv6 for addresses - OtherInformation = true; # optional, for โ€œother infoโ€ via DHCPv6 - }; - linkConfig.RequiredForOnline = "routable"; - }; - } - ); - + }; }; + }; } #+end_src @@ -10887,6 +10559,7 @@ This is the configuration to make [[#h:58c7563e-6954-42e6-a622-9d06523e8e24][Hin virtualHosts = { "${serviceDomain}" = { useACMEHost = globals.domains.main; + forceSSL = true; acmeRoot = null; locations = { @@ -11017,8 +10690,6 @@ This is the configuration to make [[#h:58c7563e-6954-42e6-a622-9d06523e8e24][Hin mpv ]; - topology.self.services.${serviceName}.info = "https://${serviceDomain}"; - users = { groups = { ${serviceGroup} = { @@ -11360,50 +11031,6 @@ This is the configuration to make [[#h:58c7563e-6954-42e6-a622-9d06523e8e24][Hin } #+end_src -**** podman - -#+begin_src nix-ts :tangle modules/nixos/server/podman.nix - { config, lib, ... }: - let - serviceName = "podman"; - in - { - options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; - config = lib.mkIf config.swarselmodules.server.${serviceName} { - - virtualisation = { - podman.enable = true; - oci-containers.backend = "podman"; - }; - - networking.nftables.firewall = lib.mkIf config.networking.nftables.enable { - - zones.podman = { - interfaces = [ "podman0" ]; - }; - - rules = { - podman-to-postgres = lib.mkIf config.services.postgresql.enable { - from = [ "podman" ]; - to = [ "local" ]; - before = [ "drop" ]; - allowedTCPPorts = [ config.services.postgresql.settings.port ]; - }; - - local-to-podman = { - from = [ "local" "wgProxy" "wgHme"]; - to = [ "podman" ]; - before = [ "drop" ]; - verdict = "accept"; - }; - }; - }; - - }; - } -#+end_src - - **** matrix :PROPERTIES: :CUSTOM_ID: h:1e68d84a-8f99-422f-89ac-78f664ac0013 @@ -13557,7 +13184,6 @@ kanidm person credential create-reset-token "radicale.access" = { }; "slink.access" = { }; "opkssh.access" = { }; - "adguardhome.access" = { }; }; inherit (config.repo.secrets.local) persons; @@ -13700,11 +13326,6 @@ kanidm person credential create-reset-token "email" "profile" ]; - "adguardhome.access" = [ - "openid" - "email" - "profile" - ]; }; preferShortUsername = true; claimMaps.groups = { @@ -13715,7 +13336,6 @@ kanidm person credential create-reset-token "firefly.access" = [ "firefly_access" ]; "radicale.access" = [ "radicale_access" ]; "slink.access" = [ "slink_access" ]; - "adguardhome.access" = [ "adguardhome_access" ]; }; }; }; @@ -13767,8 +13387,7 @@ kanidm person credential create-reset-token #+begin_src nix-ts :tangle modules/nixos/server/oauth2-proxy.nix { lib, config, globals, dns, confLib, ... }: let - inherit (confLib.gen { name = "oauth2-proxy"; port = 3004; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress proxyAddress4 proxyAddress6; - inherit (confLib.static) isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf homeWebProxy oauthServer nginxAccessRules; + inherit (confLib.gen { name = "oauth2-proxy"; port = 3004; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf; kanidmDomain = globals.services.kanidm.domain; mainDomain = globals.domains.main; @@ -13887,6 +13506,10 @@ kanidm person credential create-reset-token }; config = lib.mkIf config.swarselmodules.server.${serviceName} { + nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = { + "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6; + }; + sops = { secrets = { "oauth2-cookie-secret" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; }; @@ -13918,8 +13541,8 @@ kanidm person credential create-reset-token }; }; services.${serviceName} = { - domain = serviceDomain; - inherit proxyAddress4 proxyAddress6 isHome; + domain = serviceDomain; + inherit proxyAddress4 proxyAddress6 isHome; }; }; @@ -13972,42 +13595,32 @@ kanidm person credential create-reset-token }; }; - nodes = - let - genNginx = toAddress: extraConfig: { - upstreams = { - ${serviceName} = { - servers = { - "${toAddress}:${builtins.toString servicePort}" = { }; - }; - }; - }; - virtualHosts = { - "${serviceDomain}" = { - useACMEHost = globals.domains.main; - - forceSSL = true; - acmeRoot = null; - locations = { - "/" = { - proxyPass = "http://${serviceName}"; - }; - }; - extraConfig = '' - proxy_set_header X-Scheme $scheme; - proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri; - '' + lib.optionalString (extraConfig != "") extraConfig; - }; + nodes.${webProxy}.services.nginx = { + upstreams = { + ${serviceName} = { + servers = { + "${serviceAddress}:${builtins.toString servicePort}" = { }; }; }; - in - { - ${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = { - "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6; - }; - ${webProxy}.services.nginx = genNginx serviceAddress ""; - ${homeWebProxy}.services.nginx = genNginx globals.hosts.${oauthServer}.wanAddress4 nginxAccessRules; }; + virtualHosts = { + "${serviceDomain}" = { + useACMEHost = globals.domains.main; + + forceSSL = true; + acmeRoot = null; + locations = { + "/" = { + proxyPass = "http://${serviceName}"; + }; + }; + extraConfig = '' + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri; + ''; + }; + }; + }; }; } #+end_src @@ -14157,10 +13770,6 @@ kanidm person credential create-reset-token options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; config = lib.mkIf config.swarselmodules.server.${serviceName} { - swarselmodules.server = { - podman = true; - postgresql = true; - }; nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = { "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6; @@ -14768,10 +14377,6 @@ kanidm person credential create-reset-token }; config = lib.mkIf config.swarselmodules.server.${serviceName} { - swarselmodules.server = { - podman = true; - }; - nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = { "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6; }; @@ -14893,117 +14498,113 @@ Deployment notes: - finally, disable new user registration in web ui #+begin_src nix-ts :tangle modules/nixos/server/slink.nix - { self, lib, config, dns, globals, confLib, ... }: - let - inherit (confLib.gen { name = "slink"; port = 3000; dir = "/var/lib/slink"; }) servicePort serviceName serviceDomain serviceDir serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf; +{ self, lib, config, dns, globals, confLib, ... }: +let + inherit (confLib.gen { name = "slink"; port = 3000; dir = "/var/lib/slink"; }) servicePort serviceName serviceDomain serviceDir serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf; - containerRev = "sha256:98b9442696f0a8cbc92f0447f54fa4bad227af5dcfd6680545fedab2ed28ddd9"; - in - { - options = { - swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; + containerRev = "sha256:98b9442696f0a8cbc92f0447f54fa4bad227af5dcfd6680545fedab2ed28ddd9"; +in +{ + options = { + swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; + }; + config = lib.mkIf config.swarselmodules.server.${serviceName} { + + nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = { + "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6; }; - config = lib.mkIf config.swarselmodules.server.${serviceName} { - swarselmodules.server = { - podman = true; + virtualisation.oci-containers.containers.${serviceName} = { + image = "anirdev/slink@${containerRev}"; + environment = { + "ORIGIN" = "https://${serviceDomain}"; + "TZ" = config.repo.secrets.common.location.timezone; + "STORAGE_PROVIDER" = "local"; + "IMAGE_MAX_SIZE" = "50M"; + "USER_APPROVAL_REQUIRED" = "true"; }; - - nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = { - "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6; - }; - - virtualisation.oci-containers.containers.${serviceName} = { - image = "anirdev/slink@${containerRev}"; - environment = { - "ORIGIN" = "https://${serviceDomain}"; - "TZ" = config.repo.secrets.common.location.timezone; - "STORAGE_PROVIDER" = "local"; - "IMAGE_MAX_SIZE" = "50M"; - "USER_APPROVAL_REQUIRED" = "true"; - }; - ports = [ "${builtins.toString servicePort}:${builtins.toString servicePort}" ]; - volumes = [ - "${serviceDir}/var/data:/app/var/data" - "${serviceDir}/images:/app/slink/images" - ]; - }; - - systemd.tmpfiles.settings."12-slink" = builtins.listToAttrs ( - map - (path: { - name = "${serviceDir}/${path}"; - value = { - d = { - group = "root"; - user = "root"; - mode = "0750"; - }; - }; - }) [ - "var/data" - "images" - ] - ); - - # networking.firewall.allowedTCPPorts = [ servicePort ]; - - environment.persistence."/persist".directories = lib.mkIf config.swarselsystems.isImpermanence [ - { directory = serviceDir; } + ports = [ "${builtins.toString servicePort}:${builtins.toString servicePort}" ]; + volumes = [ + "${serviceDir}/var/data:/app/var/data" + "${serviceDir}/images:/app/slink/images" ]; + }; - topology.self.services.${serviceName} = { - name = lib.swarselsystems.toCapitalized serviceName; - info = "https://${serviceDomain}"; - icon = "${self}/files/topology-images/shlink.png"; - }; - - globals = { - networks = { - ${webProxyIf}.hosts = lib.mkIf isProxied { - ${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ]; - }; - ${homeProxyIf}.hosts = lib.mkIf isHome { - ${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ]; - }; - }; - services.${serviceName} = { - domain = serviceDomain; - inherit proxyAddress4 proxyAddress6 isHome; - }; - }; - - nodes.${webProxy}.services.nginx = { - upstreams = { - ${serviceName} = { - servers = { - "${serviceAddress}:${builtins.toString servicePort}" = { }; + systemd.tmpfiles.settings."12-slink" = builtins.listToAttrs ( + map + (path: { + name = "${serviceDir}/${path}"; + value = { + d = { + group = "root"; + user = "root"; + mode = "0750"; }; }; - }; - virtualHosts = { - "${serviceDomain}" = { - useACMEHost = globals.domains.main; + }) [ + "var/data" + "images" + ] + ); - forceSSL = true; - acmeRoot = null; - oauth2.enable = true; - oauth2.allowedGroups = [ "slink_access" ]; - locations = { - "/" = { - proxyPass = "http://${serviceName}"; - }; - "/image" = { - proxyPass = "http://${serviceName}"; - setOauth2Headers = false; - bypassAuth = true; - }; + # networking.firewall.allowedTCPPorts = [ servicePort ]; + + environment.persistence."/persist".directories = lib.mkIf config.swarselsystems.isImpermanence [ + { directory = serviceDir; } + ]; + + topology.self.services.${serviceName} = { + name = lib.swarselsystems.toCapitalized serviceName; + info = "https://${serviceDomain}"; + icon = "${self}/files/topology-images/shlink.png"; + }; + + globals = { + networks = { + ${webProxyIf}.hosts = lib.mkIf isProxied { + ${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ]; + }; + ${homeProxyIf}.hosts = lib.mkIf isHome { + ${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ]; + }; + }; + services.${serviceName} = { + domain = serviceDomain; + inherit proxyAddress4 proxyAddress6 isHome; + }; + }; + + nodes.${webProxy}.services.nginx = { + upstreams = { + ${serviceName} = { + servers = { + "${serviceAddress}:${builtins.toString servicePort}" = { }; + }; + }; + }; + virtualHosts = { + "${serviceDomain}" = { + useACMEHost = globals.domains.main; + + forceSSL = true; + acmeRoot = null; + oauth2.enable = true; + oauth2.allowedGroups = [ "slink_access" ]; + locations = { + "/" = { + proxyPass = "http://${serviceName}"; + }; + "/image" = { + proxyPass = "http://${serviceName}"; + setOauth2Headers = false; + bypassAuth = true; }; }; }; }; }; - } + }; +} #+end_src **** Snipe-IT (currently unused) @@ -15094,7 +14695,7 @@ Deployment notes: :END: #+begin_src nix-ts :tangle modules/nixos/server/homebox.nix - { self, lib, pkgs, config, globals, dns, confLib, ... }: + { lib, pkgs, config, globals, dns, confLib, ... }: let inherit (confLib.gen { name = "homebox"; port = 7745; }) servicePort serviceName serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf; in @@ -15106,11 +14707,7 @@ Deployment notes: "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6; }; - topology.self.services.${serviceName} = { - name = "Homebox"; - info = "https://${serviceDomain}"; - icon = "${self}/files/topology-images/${serviceName}.png"; - }; + topology.self.services.${serviceName}.info = "https://${serviceDomain}"; globals = { networks = { @@ -15188,7 +14785,6 @@ Deployment notes: options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; config = lib.mkIf config.swarselmodules.server.${serviceName} { - services.${serviceName} = { enable = true; user = serviceUser; @@ -15233,7 +14829,7 @@ or 2) use classic path addressing =aws s3 cp s3:/// s3:/// s3:/// s3:/// s3:/// s3:/// s3:/// s3:///=64 bytes. - # head -c 64 /dev/urandom | base64 -w 0 > secrets/${secret} - # chmod 600 secrets/${secret} - # fi - # '') - # ); - # loadSecretEnvironment = - # component: - # let - # relevantSecrets = lib.subtractLists (builtins.attrNames cfg.${component}.settings) ( - # builtins.attrNames cfg.settingsSecret - # ); - # in - # lib.concatLines ( - # lib.forEach relevantSecrets ( - # secret: - # ''export ${secret}=$(< ${ - # if cfg.settingsSecret.${secret} == null then - # "secrets/${secret}" - # else - # "\"$CREDENTIALS_DIRECTORY/${secret}\"" - # })'' - # ) - # ); - # in - # { - # script = lib.mkForce '' - # mkdir -p "$TZDATA_DIR" - - # # Generate and load secrets - # ${generateSecrets} - # ${loadSecretEnvironment "domain"} - - # echo "Running migrations" - # ${lib.getExe cfg.domain.package} eval "Domain.Release.migrate(manual: true)" - # ''; - # }; - - - nodes = { - ${homeProxy} = - let - nodeCfg = nodes.${homeProxy}.config; - nodePkgs = nodes.${homeProxy}.pkgs; - in - { - sops.secrets.firezone-gateway-token = { inherit (nodeCfg.swarselsystems) sopsFile; mode = "0400"; }; - networking.nftables = { - firewall = { - zones.firezone.interfaces = [ "tun-firezone" ]; - rules = { - # masquerade firezone traffic - masquerade-firezone = { - from = [ "firezone" ]; - to = [ "vlan-services" ]; - # masquerade = true; NOTE: custom rule below for ip4 + ip6 - late = true; # Only accept after any rejects have been processed - verdict = "accept"; - }; - # forward firezone traffic - forward-incoming-firezone-traffic = { - from = [ "firezone" ]; - to = [ "vlan-services" ]; - verdict = "accept"; - }; - - # FIXME: is this needed? conntrack should take care of it and we want to masquerade anyway - forward-outgoing-firezone-traffic = { - from = [ "vlan-services" ]; - to = [ "firezone" ]; - verdict = "accept"; - }; - }; - }; - chains.postrouting = { - masquerade-firezone = { - after = [ "hook" ]; - late = true; - rules = - lib.forEach - [ - "firezone" - ] - ( - zone: - lib.concatStringsSep " " [ - "meta protocol { ip, ip6 }" - (lib.head nodeCfg.networking.nftables.firewall.zones.${zone}.ingressExpression) - (lib.head nodeCfg.networking.nftables.firewall.zones.vlan-services.egressExpression) - "masquerade random" - ] - ); - }; - }; + smtp = { + inherit (config.repo.secrets.local.firezone.mail) from username; + host = globals.services.mailserver.domain; + port = 465; + implicitTls = true; + passwordFile = config.sops.secrets.firezone-smtp-password.path; }; - boot.kernel.sysctl = { - "net.core.wmem_max" = 16777216; - "net.core.rmem_max" = 134217728; - }; - services.firezone.gateway = { + provision = { enable = true; - # logLevel = "trace"; - inherit (nodeCfg.node) name; - apiUrl = "wss://${globals.services.firezone.domain}/api/"; - tokenFile = nodeCfg.sops.secrets.firezone-gateway-token.path; - package = nodePkgs.stable25_05.firezone-gateway; # newer versions of firezone-gateway are not compatible with server package - }; - - topology.self.services."${serviceName}-gateway" = { - name = lib.swarselsystems.toCapitalized "${serviceName} Gateway"; - icon = "${self}/files/topology-images/${serviceName}.png"; - }; - }; - ${idmServer} = - let - nodeCfg = nodes.${idmServer}.config; - accountId = "6b3c6ba7-5240-4684-95ce-f40fdae45096"; - externalId = "08d714e9-1ab9-4133-a39d-00e843a960cc"; - in - { - sops.secrets.kanidm-firezone = { inherit (nodeCfg.swarselsystems) sopsFile; owner = "kanidm"; group = "kanidm"; mode = "0440"; }; - services.kanidm.provision = { - groups."firezone.access" = { }; - systems.oauth2.firezone = { - displayName = "Firezone VPN"; - # NOTE: state: both uuids are runtime values - originUrl = [ - "https://${globals.services.firezone.domain}/${accountId}/sign_in/providers/${externalId}/handle_callback" - "https://${globals.services.firezone.domain}/${accountId}/settings/identity_providers/openid_connect/${externalId}/handle_callback" - ]; - originLanding = "https://${globals.services.firezone.domain}/"; - basicSecretFile = nodeCfg.sops.secrets.kanidm-firezone.path; - preferShortUsername = true; - scopeMaps."firezone.access" = [ - "openid" - "email" - "profile" - ]; - }; - - }; - }; - ${webProxy} = { - services.nginx = { - upstreams = { - ${serviceName} = { - servers."${serviceAddress}:${builtins.toString webPort}" = { }; - }; - "${serviceName}-api" = { - servers."${serviceAddress}:${builtins.toString apiPort}" = { }; - }; - }; - virtualHosts = { - ${serviceDomain} = { - useACMEHost = globals.domains.main; - forceSSL = true; - acmeRoot = null; - locations."/" = { - # The trailing slash is important to strip the location prefix from the request - proxyPass = "http://${serviceName}/"; - proxyWebsockets = true; + accounts.main = { + name = "Home"; + relayGroups.relays.name = "Relays"; + gatewayGroups.home.name = "Home"; + actors.admin = { + type = "account_admin_user"; + name = "Admin"; + email = "admin@${globals.domains.main}"; }; - locations."/api/" = { - # The trailing slash is important to strip the location prefix from the request - proxyPass = "http://${serviceName}-api/"; - proxyWebsockets = true; + groups.anyone = { + name = "anyone"; + members = [ + "admin" + ]; }; + + auth.oidc = + let + client_id = "firezone"; + in + { + name = "Kanidm"; + adapter = "openid_connect"; + adapter_config = { + scope = "openid email profile"; + response_type = "code"; + inherit client_id; + discovery_document_uri = "https://${globals.services.kanidm.domain}/oauth2/openid/${client_id}/.well-known/openid-configuration"; + clientSecretFile = config.sops.secrets.kanidm-firezone-client.path; + }; + }; + + resources = + lib.genAttrs homeDomains + (domain: { + type = "dns"; + name = domain; + address = domain; + gatewayGroups = [ "home" ]; + filters = [ + { protocol = "icmp"; } + { + protocol = "tcp"; + ports = [ + 443 + 80 + ]; + } + { + protocol = "udp"; + ports = [ 443 ]; + } + ]; + }) + // { + "home.vlan-services.v4" = { + type = "cidr"; + name = "home.vlan-services.v4"; + address = globals.networks.home-lan.vlans.services.cidrv4; + gatewayGroups = [ "home" ]; + }; + "home.vlan-services.v6" = { + type = "cidr"; + name = "home.vlan-services.v6"; + address = globals.networks.home-lan.vlans.services.cidrv6; + gatewayGroups = [ "home" ]; + }; + }; + + policies = + { } + // allow "everyone" "home.vlan-services.v4" + // allow "anyone" "home.vlan-services.v4" + // allow "everyone" "home.vlan-services.v6" + // allow "anyone" "home.vlan-services.v6" + // lib.mergeAttrsList (map (domain: allow "everyone" domain) homeDomains) + // lib.mergeAttrsList (map (domain: allow "anyone" domain) homeDomains); }; }; + + domain = { + settings.ERLANG_DISTRIBUTION_PORT = domainPort; + package = pkgs.dev.firezone-server-domain; + }; + api = { + externalUrl = "https://${serviceDomain}/api/"; + address = "0.0.0.0"; + port = apiPort; + package = pkgs.dev.firezone-server-api; + }; + web = { + externalUrl = "https://${serviceDomain}/"; + address = "0.0.0.0"; + port = webPort; + package = pkgs.dev.firezone-server-web; + }; + }; + + relay = { + enable = true; + port = relayPort; + inherit (config.node) name; + apiUrl = "wss://${serviceDomain}/api/"; + tokenFile = config.sops.secrets.firezone-relay-token.path; + publicIpv4 = proxyAddress4; + publicIpv6 = proxyAddress6; + openFirewall = lib.mkIf (!isProxied) true; + package = pkgs.dev.firezone-relay; }; }; - }; + # systemd.services.firezone-initialize = + # let + # generateSecrets = + # let + # requiredSecrets = lib.filterAttrs (_: v: v == null) cfg.settingsSecret; + # in + # '' + # mkdir -p secrets + # chmod 700 secrets + # '' + # + lib.concatLines ( + # lib.forEach (builtins.attrNames requiredSecrets) (secret: '' + # if [[ ! -e secrets/${secret} ]]; then + # echo "Generating ${secret}" + # # Some secrets like TOKENS_KEY_BASE require a value >=64 bytes. + # head -c 64 /dev/urandom | base64 -w 0 > secrets/${secret} + # chmod 600 secrets/${secret} + # fi + # '') + # ); + # loadSecretEnvironment = + # component: + # let + # relevantSecrets = lib.subtractLists (builtins.attrNames cfg.${component}.settings) ( + # builtins.attrNames cfg.settingsSecret + # ); + # in + # lib.concatLines ( + # lib.forEach relevantSecrets ( + # secret: + # ''export ${secret}=$(< ${ + # if cfg.settingsSecret.${secret} == null then + # "secrets/${secret}" + # else + # "\"$CREDENTIALS_DIRECTORY/${secret}\"" + # })'' + # ) + # ); + # in + # { + # script = lib.mkForce '' + # mkdir -p "$TZDATA_DIR" - }; - } -#+end_src -**** Adguardhome -:PROPERTIES: -:CUSTOM_ID: h:ecb66cb8-12b5-44e8-ad6b-7848711e1ffe -:END: + # # Generate and load secrets + # ${generateSecrets} + # ${loadSecretEnvironment "domain"} + + # echo "Running migrations" + # ${lib.getExe cfg.domain.package} eval "Domain.Release.migrate(manual: true)" + # ''; + # }; -#+begin_src nix-ts :tangle modules/nixos/server/adguardhome.nix - { self, inputs, lib, config, globals, dns, confLib, ... }: - let - inherit (confLib.gen { name = "adguardhome"; port = 3000; }) serviceName servicePort serviceAddress serviceDomain proxyAddress4 proxyAddress6; - inherit (confLib.static) isHome isProxied homeProxy homeProxyIf webProxy webProxyIf homeWebProxy dnsServer homeDnsServer homeServiceAddress nginxAccessRules; - - homeServices = lib.attrNames (lib.filterAttrs (_: serviceCfg: serviceCfg.isHome) globals.services); - homeDomains = map (name: globals.services.${name}.domain) homeServices; - in - { - options = { - swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; - }; - config = lib.mkIf config.swarselmodules.server.${serviceName} { - - - globals = { - networks = { - ${webProxyIf}.hosts = lib.mkIf isProxied { - ${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ]; - }; - ${homeProxyIf}.hosts = lib.mkIf isHome { - ${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ]; - }; - }; - services.${serviceName} = { - domain = serviceDomain; - inherit proxyAddress4 proxyAddress6 isHome; - }; - }; - - networking.firewall = { - allowedTCPPorts = [ 53 ]; - allowedUDPPorts = [ 53 ]; - }; - - services.adguardhome = { - enable = true; - mutableSettings = false; - host = "0.0.0.0"; - port = servicePort; - settings = { - dns = { - bind_hosts = [ - globals.networks.home-lan.vlans.services.hosts.${homeDnsServer}.ipv4 - globals.networks.home-lan.vlans.services.hosts.${homeDnsServer}.ipv6 - ]; - ratelimit = 300; - upstream_dns = [ - "https://dns.cloudflare.com/dns-query" - "https://dns.google/dns-query" - "https://doh.mullvad.net/dns-query" - ]; - bootstrap_dns = [ - "1.1.1.1" - "2606:4700:4700::1111" - "8.8.8.8" - "2001:4860:4860::8844" - ]; - dhcp.enabled = false; - }; - filtering.rewrites = [ - ] - # Use the local mirror-proxy for some services (not necessary, just for speed) - ++ - map - (domain: { - inherit domain; - # FIXME: change to homeWebProxy once that is setup - answer = globals.networks.home-lan.vlans.services.hosts.${homeWebProxy}.ipv4; - # answer = globals.hosts.${webProxy}.wanAddress4; - }) - homeDomains; - filters = [ + nodes = { + ${homeProxy} = + let + nodeCfg = nodes.${homeProxy}.config; + nodePkgs = nodes.${homeProxy}.pkgs; + in { - name = "AdGuard DNS filter"; - url = "https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt"; - enabled = true; - } - { - name = "AdAway Default Blocklist"; - url = "https://adaway.org/hosts.txt"; - enabled = true; - } - { - name = "OISD (Big)"; - url = "https://big.oisd.nl"; - enabled = true; - } - ]; - }; - }; + sops.secrets.firezone-gateway-token = { inherit (nodeCfg.swarselsystems) sopsFile; mode = "0400"; }; + networking.nftables = { + firewall = { + zones.firezone.interfaces = [ "tun-firezone" ]; + rules = { + # masquerade firezone traffic + masquerade-firezone = { + from = [ "firezone" ]; + to = [ "vlan-services" ]; + # masquerade = true; NOTE: custom rule below for ip4 + ip6 + late = true; # Only accept after any rejects have been processed + verdict = "accept"; + }; + # forward firezone traffic + forward-incoming-firezone-traffic = { + from = [ "firezone" ]; + to = [ "vlan-services" ]; + verdict = "accept"; + }; - environment.persistence."/persist".directories = lib.mkIf config.swarselsystems.isImpermanence [ - { - directory = "/var/lib/private/AdGuardHome"; - mode = "0700"; - } - ]; - - nodes = - let - genNginx = toAddress: extraConfig: { - upstreams = { - ${serviceName} = { - servers = { - "${toAddress}:${builtins.toString servicePort}" = { }; + # FIXME: is this needed? conntrack should take care of it and we want to masquerade anyway + forward-outgoing-firezone-traffic = { + from = [ "vlan-services" ]; + to = [ "firezone" ]; + verdict = "accept"; + }; + }; + }; + chains.postrouting = { + masquerade-firezone = { + after = [ "hook" ]; + late = true; + rules = + lib.forEach + [ + "firezone" + ] + ( + zone: + lib.concatStringsSep " " [ + "meta protocol { ip, ip6 }" + (lib.head nodeCfg.networking.nftables.firewall.zones.${zone}.ingressExpression) + (lib.head nodeCfg.networking.nftables.firewall.zones.vlan-services.egressExpression) + "masquerade random" + ] + ); + }; }; }; + + boot.kernel.sysctl = { + "net.core.wmem_max" = 16777216; + "net.core.rmem_max" = 134217728; + }; + services.firezone.gateway = { + enable = true; + logLevel = "trace"; + inherit (nodeCfg.node) name; + apiUrl = "wss://${globals.services.firezone.domain}/api/"; + tokenFile = nodeCfg.sops.secrets.firezone-gateway-token.path; + package = nodePkgs.stable25_05.firezone-gateway; # newer versions of firezone-gateway are not compatible with server package + }; }; - virtualHosts = { - "${serviceDomain}" = { - useACMEHost = globals.domains.main; - forceSSL = true; - acmeRoot = null; - oauth2 = { - enable = true; - allowedGroups = [ "adguardhome_access" ]; + ${idmServer} = + let + nodeCfg = nodes.${idmServer}.config; + accountId = "6b3c6ba7-5240-4684-95ce-f40fdae45096"; + externalId = "08d714e9-1ab9-4133-a39d-00e843a960cc"; + in + { + sops.secrets.kanidm-firezone = { inherit (nodeCfg.swarselsystems) sopsFile; owner = "kanidm"; group = "kanidm"; mode = "0440"; }; + services.kanidm.provision = { + groups."firezone.access" = { }; + systems.oauth2.firezone = { + displayName = "Firezone VPN"; + # NOTE: state: both uuids are runtime values + originUrl = [ + "https://${globals.services.firezone.domain}/${accountId}/sign_in/providers/${externalId}/handle_callback" + "https://${globals.services.firezone.domain}/${accountId}/settings/identity_providers/openid_connect/${externalId}/handle_callback" + ]; + originLanding = "https://${globals.services.firezone.domain}/"; + basicSecretFile = nodeCfg.sops.secrets.kanidm-firezone.path; + preferShortUsername = true; + scopeMaps."firezone.access" = [ + "openid" + "email" + "profile" + ]; }; - locations = { - "/" = { - proxyPass = "http://${serviceName}"; + + }; + }; + ${webProxy} = { + services.nginx = { + upstreams = { + ${serviceName} = { + servers."${serviceAddress}:${builtins.toString webPort}" = { }; + }; + "${serviceName}-api" = { + servers."${serviceAddress}:${builtins.toString apiPort}" = { }; + }; + }; + virtualHosts = { + ${serviceDomain} = { + useACMEHost = globals.domains.main; + forceSSL = true; + acmeRoot = null; + locations."/" = { + # The trailing slash is important to strip the location prefix from the request + proxyPass = "http://${serviceName}/"; + proxyWebsockets = true; + }; + locations."/api/" = { + # The trailing slash is important to strip the location prefix from the request + proxyPass = "http://${serviceName}-api/"; proxyWebsockets = true; }; }; - extraConfig = lib.mkIf (extraConfig != "") extraConfig; }; }; }; - in - { - ${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = { - "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6; - }; - ${webProxy}.services.nginx = genNginx serviceAddress ""; - ${homeWebProxy}.services.nginx = genNginx homeServiceAddress nginxAccessRules; }; - }; - } + + }; + } #+end_src *** Darwin :PROPERTIES: @@ -17912,22 +17271,15 @@ Some standard options that should be set for every microvm host. #+begin_src nix-ts :tangle modules/nixos/optional/microvm-host.nix { config, lib, ... }: { + # imports = [ + # inputs.microvm.nixosModules.host + # ]; + config = lib.mkIf (config.guests != { }) { - systemd.tmpfiles.settings."15-microvms" = builtins.listToAttrs ( - map - (path: { - name = "${lib.optionalString config.swarselsystems.isImpermanence "/persist"}/microvms/${path}"; - value = { - d = { - group = "kvm"; - user = "microvm"; - mode = "0750"; - }; - }; - }) (builtins.attrNames config.guests) - ); - + microvm = { + hypervisor = lib.mkDefault "qemu"; + }; }; } #+end_src @@ -17937,111 +17289,41 @@ Some standard options that should be set for every microvm host. :CUSTOM_ID: h:46419b40-c40b-4b55-ac6f-a30169322bd6 :END: -Some standard options that should be set for every microvm guest. We set the default +Some standard options that should be set vor every microvm guest. We set the default #+begin_src nix-ts :tangle modules/nixos/optional/microvm-guest.nix - { self, lib, config, inputs, microVMParent, nodes, ... }: - { - imports = [ - inputs.disko.nixosModules.disko - inputs.home-manager.nixosModules.home-manager - inputs.impermanence.nixosModules.impermanence - inputs.lanzaboote.nixosModules.lanzaboote - inputs.microvm.nixosModules.microvm - inputs.nix-index-database.nixosModules.nix-index - inputs.nix-minecraft.nixosModules.minecraft-servers - inputs.nix-topology.nixosModules.default - inputs.nswitch-rcm-nix.nixosModules.nswitch-rcm - inputs.simple-nixos-mailserver.nixosModules.default - inputs.sops.nixosModules.sops - inputs.stylix.nixosModules.stylix - inputs.swarsel-nix.nixosModules.default - inputs.nixos-nftables-firewall.nixosModules.default - - (inputs.nixos-extra-modules + "/modules/interface-naming.nix") - - "${self}/modules/shared/meta.nix" - ]; - - config = { - _module.args.dns = inputs.dns; - - nix.settings.experimental-features = [ - "nix-command" - "flakes" - ]; - systemd.services."systemd-networkd".environment.SYSTEMD_LOG_LEVEL = "debug"; - # NOTE: this is needed, we dont import sevrer network module for microvms - globals.hosts.${config.node.name}.isHome = true; - - fileSystems."/persist".neededForBoot = lib.mkForce true; - - systemd.network.networks."10-vlan-services" = { - dhcpV6Config = { - WithoutRA = "solicit"; - # duid-en is nice in principle, but I already have MAC info anyways for reservations - DUIDType = "link-layer"; - }; - # networkConfig = { - # IPv6PrivacyExtensions = "no"; - # IPv6AcceptRA = false; - # }; - ipv6AcceptRAConfig = { - DHCPv6Client = "always"; - }; - }; - - microvm = { - shares = [ - { - tag = "persist"; - source = "${lib.optionalString nodes.${microVMParent}.config.swarselsystems.isImpermanence "/persist"}/microvms/${config.networking.hostName}"; - mountPoint = "/persist"; - proto = "virtiofs"; - } - ]; - # mount the writeable overlay so that we can use nix shells inside the microvm - volumes = [ - { - image = "/tmp/nix-store-overlay-${config.networking.hostName}.img"; - autoCreate = true; - mountPoint = config.microvm.writableStoreOverlay; - size = 1024; - } - ]; - }; - }; - } - -#+end_src - -**** systemd-networkd (base) -:PROPERTIES: -:CUSTOM_ID: h:99bf6c0e-2566-4a50-b219-fb6a7d4fb2cd -:END: - -This set of options enables the network of the system to be managed by =systemd-networkd=: - - =networking.useNetworkd= has the effect that options from =networking.*= are not performed using network scripts but rather using =systemd-networkd=. - - =systemd.network.enable= enables the actual management of networks using the =systemd-networkd= interface. - -#+begin_src nix-ts :tangle modules/nixos/optional/systemd-networkd-base.nix - { lib, config, ... }: + { self, inputs, ... }: { - networking = { - useDHCP = lib.mkForce false; - useNetworkd = true; - dhcpcd.enable = lib.mkIf (!config.swarselsystems.isMicroVM) false; - renameInterfacesByMac = lib.mkIf (!config.swarselsystems.isMicroVM) (lib.mapAttrs (_: v: if (v ? mac) then v.mac else "") ( - config.repo.secrets.local.networking.networks or { } - )); - }; + imports = [ + inputs.disko.nixosModules.disko + inputs.home-manager.nixosModules.home-manager + inputs.impermanence.nixosModules.impermanence + inputs.lanzaboote.nixosModules.lanzaboote + inputs.microvm.nixosModules.host + inputs.microvm.nixosModules.microvm + inputs.nix-index-database.nixosModules.nix-index + inputs.nix-minecraft.nixosModules.minecraft-servers + inputs.nix-topology.nixosModules.default + inputs.nswitch-rcm-nix.nixosModules.nswitch-rcm + inputs.simple-nixos-mailserver.nixosModules.default + inputs.sops.nixosModules.sops + inputs.stylix.nixosModules.stylix + inputs.swarsel-nix.nixosModules.default + inputs.nixos-nftables-firewall.nixosModules.default - systemd.network.enable = true; + (inputs.nixos-extra-modules + "/modules/interface-naming.nix") + + "${self}/modules/shared/meta.nix" + ]; + + config = { + system.stateVersion = "23.05"; + }; } #+end_src -**** systemd-networkd (server base) +**** systemd-networkd (server) :PROPERTIES: :CUSTOM_ID: h:12370671-7892-4a74-a804-84f871acde06 :END: @@ -18049,33 +17331,31 @@ This set of options enables the network of the system to be managed by =systemd- Some standard options that should be set vor every microvm guest. We set the default #+begin_src nix-ts :tangle modules/nixos/optional/systemd-networkd-server.nix - { self, lib, config, globals, ... }: - let - inherit (config.swarselsystems) isCrypted localVLANs; - inherit (globals.general) routerServer; - - isRouter = config.node.name == routerServer; - ifName = config.swarselsystems.server.localNetwork; - in + { lib, config, globals, ... }: { - imports = [ - "${self}/modules/nixos/optional/systemd-networkd-base.nix" - ]; - - boot.initrd.systemd.network = lib.mkIf (isCrypted && ((localVLANs == [ ]) || isRouter)) { + networking = { + useDHCP = lib.mkForce false; + useNetworkd = true; + dhcpcd.enable = false; + renameInterfacesByMac = lib.mapAttrs (_: v: if (v ? mac) then v.mac else "") ( + config.repo.secrets.local.networking.networks or { } + ); + }; + boot.initrd.systemd.network = { enable = true; - networks."10-${ifName}" = config.systemd.network.networks."10-${ifName}"; + networks."10-${config.swarselsystems.server.localNetwork}" = config.systemd.network.networks."10-${config.swarselsystems.server.localNetwork}"; }; systemd = { network = { + enable = true; wait-online.enable = false; networks = let netConfig = config.repo.secrets.local.networking; in { - "10-${ifName}" = lib.mkIf (isRouter || (localVLANs == [ ])) { + "10-${config.swarselsystems.server.localNetwork}" = { address = [ "${globals.networks.${config.swarselsystems.server.netConfigName}.hosts.${config.node.name}.cidrv4}" "${globals.networks.${config.swarselsystems.server.netConfigName}.hosts.${config.node.name}.cidrv6}" @@ -18104,158 +17384,136 @@ Some standard options that should be set vor every microvm guest. We set the def #+end_src -**** TODO systemd-networkd (server home) +**** systemd-networkd (vlans/microvms) :PROPERTIES: -:CUSTOM_ID: h:049fc27e-a28f-4ff0-b5f0-d81401bdd56f +:CUSTOM_ID: h:9e1b68cb-f482-417d-8be8-48bfbf3a0d99 :END: -This sets up the networking framework that is needed for a server that manages its VLAN interfaces using =systemd-networkd=. A host that is not both in the home network and using VLANs should rather be using [[#h:12370671-7892-4a74-a804-84f871acde06][systemd-networkd (server base)]] only. +This sets up the networking framework that is needed for a server that hosts microvms. -We will differentiate between a host that uses microvms versus a host that is not using them. - -For a host with microvms the general idea is as follows: -- For each local VLAN we create a VLAN here - we also create a macvlan interface for the hosts which is bound to the respective VLAN interface; also binding to that VLAN interface are the macvtap devices that are being created by the microvm module. - - normally, a guest using macvtap is not reachable by the host unless using a switch that supports hairpin-mode. However, consumers of the same VLAN can still communicate, which is realized using the macvlan =me-*= interface. +The general idea is as follows: +- A host has =n= physical interfaces, which bind to the =br= bridge. Also bound to the bridge is the =veth= interfaces that the vlans are applied to. This makes it so that the macvlan interfaces still get an IP even if the physical interfaces have no carrier. +- For each VLAN defined in globals we create a VLAN here - we also create a macvlan interface for the hosts which is bound to the respective VLAN interface; also binding to that VLAN interface are the macvtap devices that are being created by the microvm module. + - normally, a guest using macvtap is not reachable by the host unless using a switch that supports hairpin-mode. However, consumers of the same VLAN can still communicate, which is realized using the macvlan interface. - even then, the kernel will only route requests when the underlying interface is up. In the case that no physical ports are used, this means that the bridge interface would effectively not work (even when administratively set to UP using =activationPolicy=) - the aforementioned =veth= takes care of that problem. - - this is really only a consideration for the [[#h:b54f2bbb-0088-46b2-957d-fd8234b772c3][Router]] (because if the interface to the router is missing on the hosts, there will be no connectivity anyways) and is hence implemented there -The principle is the same for a host without microvms, but we do not need the local =me-*= interfaces and can ignore =macvtap= config. +#+begin_src nix-ts :tangle modules/nixos/optional/systemd-networkd-vlan.nix + { lib, config, globals, ... }: + { -A VLAN can also be used as the initrd network - this is however disabled for the router host. For that host, we need to connect from the =FritzBox!= side in case we need to reboot it (TODO: fix interface naming lan/wan which blocks this) - - -#+begin_src nix-ts :tangle modules/nixos/optional/systemd-networkd-server-home.nix - { self,lib, config, globals, ... }: - let - inherit (globals.general) routerServer; - inherit (config.swarselsystems) withMicroVMs isCrypted initrdVLAN; - - isRouter = config.node.name == routerServer; - localVLANsList = config.swarselsystems.localVLANs; - localVLANs = lib.genAttrs localVLANsList (x: globals.networks.home-lan.vlans.${x}); - in - { - imports = [ - "${self}/modules/nixos/optional/systemd-networkd-server.nix" - ]; - config = { - assertions = [ - { - assertion = ((localVLANsList != []) && (initrdVLAN != null)) || (localVLANsList == []) || (!isCrypted); - message = "This host uses VLANs and disk encryption, thus a VLAN must be specified for initrd or disk encryption must be removed."; - } - ]; - - boot.initrd = lib.mkIf (isCrypted && (localVLANsList != []) && (!isRouter)) { - availableKernelModules = [ "8021q" ]; - systemd.network = { - enable = true; - netdevs."30-vlan-${initrdVLAN}" = { - netdevConfig = { - Kind = "vlan"; - Name = "vlan-${initrdVLAN}"; - }; - vlanConfig.Id = globals.networks.home-lan.vlans.${initrdVLAN}.id; - }; - networks = { - "10-lan" = { - matchConfig.Name = "lan"; - # This interface should only be used from attached vlans. - # So don't acquire a link local address and only wait for - # this interface to gain a carrier. - networkConfig.LinkLocalAddressing = "no"; - linkConfig.RequiredForOnline = "carrier"; - vlan = [ "vlan-${initrdVLAN}" ]; - }; - "30-vlan-${initrdVLAN}" = { - address = [ - globals.networks.home-lan.vlans.${initrdVLAN}.hosts.${config.node.name}.cidrv4 - globals.networks.home-lan.vlans.${initrdVLAN}.hosts.${config.node.name}.cidrv6 - ]; - matchConfig.Name = "vlan-${initrdVLAN}"; - networkConfig = { - IPv6PrivacyExtensions = "yes"; - }; - linkConfig.RequiredForOnline = "routable"; - }; - }; + systemd.network = { + wait-online.anyInterface = true; + netdevs = { + "10-veth" = { + netdevConfig = { + Kind = "veth"; + Name = "veth-br"; + }; + peerConfig = { + Name = "veth-int"; }; }; - - systemd.network = { - netdevs = lib.flip lib.concatMapAttrs localVLANs ( - vlanName: vlanCfg: { - "30-vlan-${vlanName}" = { - netdevConfig = { - Kind = "vlan"; - Name = "vlan-${vlanName}"; - }; - vlanConfig.Id = vlanCfg.id; - }; - # Create a MACVTAP for ourselves too, so that we can communicate with - # our guests on the same interface. - "40-me-${vlanName}" = lib.mkIf withMicroVMs { - netdevConfig = { - Name = "me-${vlanName}"; - Kind = "macvlan"; - }; - extraConfig = '' - [MACVLAN] - Mode=bridge - ''; - }; - } - ); - networks = { - "10-lan" = lib.mkIf (!isRouter) { - matchConfig.Name = "lan"; - # This interface should only be used from attached vlans. - # So don't acquire a link local address and only wait for - # this interface to gain a carrier. - networkConfig.LinkLocalAddressing = "no"; - linkConfig.RequiredForOnline = "carrier"; - vlan = (map (name: "vlan-${name}") (builtins.attrNames localVLANs)); - }; - # Remaining macvtap interfaces should not be touched. - "90-macvtap-ignore" = lib.mkIf withMicroVMs { - matchConfig.Kind = "macvtap"; - linkConfig.ActivationPolicy = "manual"; - linkConfig.Unmanaged = "yes"; - }; - } - // lib.flip lib.concatMapAttrs localVLANs ( - vlanName: vlanCfg: - let - me = { - address = [ - vlanCfg.hosts.${config.node.name}.cidrv4 - vlanCfg.hosts.${config.node.name}.cidrv6 - ]; - gateway = lib.optionals (vlanName == "services") [ vlanCfg.hosts.${routerServer}.ipv4 vlanCfg.hosts.${routerServer}.ipv6 ]; - matchConfig.Name = "${if withMicroVMs then "me" else "vlan"}-${vlanName}"; - networkConfig.IPv6PrivacyExtensions = "yes"; - linkConfig.RequiredForOnline = "routable"; - }; - - in - { - "30-vlan-${vlanName}" = if (!withMicroVMs) then me else { - matchConfig.Name = "vlan-${vlanName}"; - # This interface should only be used from attached macvlans. - # So don't acquire a link local address and only wait for - # this interface to gain a carrier. - networkConfig.LinkLocalAddressing = "no"; - networkConfig.MACVLAN = "me-${vlanName}"; - linkConfig.RequiredForOnline = if isRouter then "no" else "carrier"; - }; - "40-me-${vlanName}" = lib.mkIf withMicroVMs (lib.mkDefault me); - } - ); + "20-br" = { + netdevConfig = { + Kind = "bridge"; + Name = "br"; + }; }; + } // lib.flip lib.concatMapAttrs globals.networks.home-lan.vlans ( + vlanName: vlanCfg: { + "30-vlan-${vlanName}" = { + netdevConfig = { + Kind = "vlan"; + Name = "vlan-${vlanName}"; + }; + vlanConfig.Id = vlanCfg.id; + }; + "40-me-${vlanName}" = { + netdevConfig = { + Name = "me-${vlanName}"; + Kind = "macvlan"; + }; + extraConfig = '' + [MACVLAN] + Mode=bridge + ''; + }; + } + ); + networks = { + "40-br" = { + matchConfig.Name = "br"; + bridgeConfig = { }; + linkConfig = { + ActivationPolicy = "always-up"; + RequiredForOnline = "no"; + }; + networkConfig = { + ConfigureWithoutCarrier = true; + LinkLocalAddressing = "no"; + }; + }; + "15-veth-br" = { + matchConfig.Name = "veth-br"; - }; + linkConfig = { + RequiredForOnline = "no"; + }; - } + networkConfig = { + Bridge = "br"; + }; + }; + "15-veth-int" = { + matchConfig.Name = "veth-int"; + + linkConfig = { + ActivationPolicy = "always-up"; + RequiredForOnline = "no"; + }; + + networkConfig = { + ConfigureWithoutCarrier = true; + LinkLocalAddressing = "no"; + }; + + vlan = map (name: "vlan-${name}") (builtins.attrNames globals.networks.home-lan.vlans); + }; + "90-macvtap-ignore" = { + matchConfig.Kind = "macvtap"; + linkConfig.ActivationPolicy = "manual"; + linkConfig.Unmanaged = "yes"; + }; + } // lib.flip lib.concatMapAttrs globals.networks.home-lan.vlans ( + vlanName: vlanCfg: { + "30-vlan-${vlanName}" = { + matchConfig.Name = "vlan-${vlanName}"; + networkConfig.LinkLocalAddressing = "no"; + networkConfig.MACVLAN = "me-${vlanName}"; + linkConfig.RequiredForOnline = "no"; + }; + "40-me-${vlanName}" = { + address = [ + vlanCfg.hosts.${config.node.name}.cidrv4 + vlanCfg.hosts.${config.node.name}.cidrv6 + ]; + matchConfig.Name = "me-${vlanName}"; + networkConfig = { + IPv4Forwarding = "yes"; + IPv6PrivacyExtensions = "yes"; + IPv6SendRA = true; + IPv6AcceptRA = false; + }; + ipv6Prefixes = [ + { Prefix = vlanCfg.cidrv6; } + ]; + linkConfig.RequiredForOnline = "routable"; + }; + } + ); + }; + + } #+end_src @@ -18267,28 +17525,16 @@ A VLAN can also be used as the initrd network - this is however disabled for the Hold standard options for nix-topology per config #+begin_src nix-ts :tangle modules/nixos/optional/nix-topology-self.nix - { lib, config, globals, confLib, ... }: - let - inherit (confLib.static) webProxy; - in + { lib, config, globals, ... }: { topology.self = { icon = lib.mkIf config.swarselsystems.isCloud "devices.cloud-server"; - interfaces = { - wan = lib.mkIf (config.swarselsystems.isCloud && config.swarselsystems.server.localNetwork == "wan") { }; - lan = lib.mkIf (config.swarselsystems.isCloud && config.swarselsystems.server.localNetwork == "lan") { }; - wgProxy = lib.mkIf (config.swarselsystems.server.wireguard ? wgHome) { - addresses = [ globals.networks."${webProxy}-wg.hosts".${config.node.name}.ipv4 ]; - renderer.hidePhysicalConnections = true; - virtual = true; - type = "wireguard"; - }; - wgHome = lib.mkIf (config.swarselsystems.server.wireguard ? wgHome) { - addresses = [ globals.networks.home-wgHome.hosts.${config.node.name}.ipv4 ]; - renderer.hidePhysicalConnections = true; - virtual = true; - type = "wireguard"; - }; + interfaces.wan = lib.mkIf config.swarselsystems.isCloud { }; + interfaces.wg = lib.mkIf (config.swarselsystems.server.wireguard.isClient || config.swarselsystems.server.wireguard.isServer) { + addresses = [ globals.networks.twothreetunnel-wg.hosts.${config.node.name}.ipv4 ]; + renderer.hidePhysicalConnections = true; + virtual = true; + type = "wireguard"; }; }; } @@ -22430,9 +21676,6 @@ Sets up a systemd user service for anki that does not stall the shutdown process #+end_src ***** firezone service for tray -:PROPERTIES: -:CUSTOM_ID: h:2690d49b-2b25-4204-b349-36e3efe2462a -:END: #+begin_src nix-ts :tangle modules/home/common/firezone-tray.nix { lib, config, pkgs, ... }: @@ -25101,18 +24344,6 @@ TODO: check which of these can be replaced but builtin functions. type = lib.types.str; default = ""; }; - # @ future me: dont put this under server prefix - # home-manager would then try to import all swarselsystems.server.* options - localVLANs = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ ]; - }; - # @ future me: dont put this under server prefix - # home-manager would then try to import all swarselsystems.server.* options - initrdVLAN = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - }; mainUser = lib.mkOption { type = lib.types.str; default = "swarsel"; @@ -25465,29 +24696,29 @@ In short, the options defined here are passed to the modules systems using =_mod :END: #+begin_src nix-ts :noweb yes :tangle modules/shared/config-lib.nix { self, config, lib, globals, inputs, outputs, minimal, nixosConfig ? null, ... }: - let - domainDefault = service: config.repo.secrets.common.services.domains.${service}; - proxyDefault = config.swarselsystems.proxyHost; - - addressDefault = - if - config.swarselsystems.proxyHost != config.node.name - then - if - config.swarselsystems.server.wireguard.interfaces.wgProxy.isClient - then - globals.networks."${config.swarselsystems.server.wireguard.interfaces.wgProxy.serverNetConfigPrefix}-wgProxy".hosts.${config.node.name}.ipv4 - else - globals.networks.${config.swarselsystems.server.netConfigName}.hosts.${config.node.name}.ipv4 - else - "localhost"; - in { _module.args = { confLib = rec { + + addressDefault = + if + config.swarselsystems.proxyHost != config.node.name + then + if + config.swarselsystems.server.wireguard.interfaces.wgProxy.isClient + then + globals.networks."${config.swarselsystems.server.wireguard.interfaces.wgProxy.serverNetConfigPrefix}-wgProxy".hosts.${config.node.name}.ipv4 + else + globals.networks.${config.swarselsystems.server.netConfigName}.hosts.${config.node.name}.ipv4 + else + "localhost"; + + domainDefault = service: config.repo.secrets.common.services.domains.${service}; + proxyDefault = config.swarselsystems.proxyHost; + getConfig = if nixosConfig == null then config else nixosConfig; - gen = { name ? "n/a", user ? name, group ? name, dir ? null, port ? null, domain ? (domainDefault name), address ? addressDefault, proxy ? proxyDefault }: rec { + gen = { name, user ? name, group ? name, dir ? null, port ? null, domain ? (domainDefault name), address ? addressDefault, proxy ? proxyDefault }: rec { servicePort = port; serviceName = name; specificServiceName = "${name}-${config.node.name}"; @@ -25502,66 +24733,44 @@ In short, the options defined here are passed to the modules systems using =_mod proxyAddress4 = globals.hosts.${proxy}.wanAddress4 or null; proxyAddress6 = globals.hosts.${proxy}.wanAddress6 or null; inherit (globals.hosts.${config.node.name}) isHome; - inherit (globals.general) homeProxy webProxy dnsServer homeDnsServer homeWebProxy idmServer; + inherit (globals.general) homeProxy webProxy dnsServer idmServer; webProxyIf = "${webProxy}-wgProxy"; homeProxyIf = "home-wgHome"; isProxied = config.node.name != webProxy; }; - static = rec { - inherit (globals.hosts.${config.node.name}) isHome; - inherit (globals.general) homeProxy webProxy dnsServer homeDnsServer homeWebProxy idmServer oauthServer; - webProxyIf = "${webProxy}-wgProxy"; - homeProxyIf = "home-wgHome"; - isProxied = config.node.name != webProxy; - nginxAccessRules = '' - allow ${globals.networks.home-lan.vlans.home.cidrv4}; - allow ${globals.networks.home-lan.vlans.home.cidrv6}; - allow ${globals.networks.home-lan.vlans.services.hosts.${homeProxy}.ipv4}; - allow ${globals.networks.home-lan.vlans.services.hosts.${homeProxy}.ipv6}; - deny all; - ''; - homeServiceAddress = lib.optionalString (config.swarselsystems.server.wireguard.interfaces ? wgHome) globals.networks."${config.swarselsystems.server.wireguard.interfaces.wgHome.serverNetConfigPrefix}-wgHome".hosts.${config.node.name}.ipv4; - }; - - mkMicrovm = - if config.swarselsystems.withMicroVMs then - (guestName: { - ${guestName} = { - backend = "microvm"; - autostart = true; - modules = [ - (config.node.configDir + /guests/${guestName}/default.nix) - { - node.secretsDir = config.node.configDir + /secrets/${guestName}; - node.configDir = config.node.configDir + /guests/${guestName}; - networking.nftables.firewall = { - zones.untrusted.interfaces = lib.mkIf - ( - lib.length config.guests.${guestName}.networking.links == 1 - ) - config.guests.${guestName}.networking.links; - }; - } - "${self}/modules/nixos/optional/microvm-guest.nix" - "${self}/modules/nixos/optional/systemd-networkd-base.nix" - ]; - microvm = { - system = config.node.arch; - baseMac = config.repo.secrets.local.networking.networks.lan.mac; - interfaces.vlan-services = { }; + mkMicrovm = if config.swarselsystems.withMicroVMs then (guestName: { + ${guestName} = { + backend = "microvm"; + autostart = true; + modules = [ + (config.node.configDir + /guests/${guestName}.nix) + { + node.secretsDir = config.node.configDir + /secrets/${guestName}; + node.configDir = config.node.configDir + /guests/${guestName}; + networking.nftables.firewall = { + zones.untrusted.interfaces = lib.mkIf ( + lib.length config.guests.${guestName}.networking.links == 1 + ) config.guests.${guestName}.networking.links; }; - extraSpecialArgs = { - inherit (outputs) nodes; - inherit (inputs.self.pkgs.${config.node.arch}) lib; - inherit inputs outputs minimal; - inherit (inputs) self; - withHomeManager = false; - microVMParent = config.node.name; - globals = outputs.globals.${config.node.arch}; - }; - }; - }) else (_: { _ = { }; }); + } + "${self}/modules/nixos/optional/microvm-guest.nix" + ]; + microvm = { + system = config.node.arch; + baseMac = config.repo.secrets.local.networking.networks.lan.mac; + interfaces.vlan-services = { }; + }; + extraSpecialArgs = { + inherit (outputs) nodes; + inherit (inputs.self.pkgs.${config.node.arch}) lib; + inherit inputs outputs minimal; + inherit (inputs) self; + withHomeManager = false; + globals = outputs.globals.${config.node.arch}; + }; + }; + }) else (_: {_ = {};}); }; }; @@ -28024,8 +27233,6 @@ Modules that need to be loaded on the NixOS level. Note that these will not be a general = lib.mkDefault true; packages = lib.mkDefault true; ssh = lib.mkDefault true; - wireguard = lib.mkDefault true; - dns-home = lib.mkDefault true; }; }; }; @@ -28324,7 +27531,7 @@ This holds modules that are to be used on most hosts. These are also the most im #+end_src -* Emacs +* Emacse :PROPERTIES: :CUSTOM_ID: h:ed4cd05c-0879-41c6-bc39-3f1246a96f04 :END: @@ -30445,7 +29652,7 @@ It supports all functions that I normally need. Note that getting completions fo (use-package nix-ts-mode :after lsp-mode - :mode ("\\.nix\\'" . "\\.nix\\.enc\\'") + :mode "\\.nix\\'" :ensure t :hook (nix-ts-mode . lsp-deferred) ;; So that envrc mode will work diff --git a/files/emacs/init.el b/files/emacs/init.el index 52ffc4e..26d3439 100644 --- a/files/emacs/init.el +++ b/files/emacs/init.el @@ -1117,7 +1117,7 @@ create a new one." (use-package nix-ts-mode :after lsp-mode - :mode ("\\.nix\\'" . "\\.nix\\.enc\\'") + :mode "\\.nix\\'" :ensure t :hook (nix-ts-mode . lsp-deferred) ;; So that envrc mode will work diff --git a/files/topology-images/Cisco_SG_200-08.png b/files/topology-images/Cisco_SG_200-08.png deleted file mode 100644 index 216fbfc..0000000 Binary files a/files/topology-images/Cisco_SG_200-08.png and /dev/null differ diff --git a/files/topology-images/Fritz!Box_7682.png b/files/topology-images/Fritz!Box_7682.png deleted file mode 100644 index 84ed885..0000000 Binary files a/files/topology-images/Fritz!Box_7682.png and /dev/null differ diff --git a/files/topology-images/TL-SG108E.png b/files/topology-images/TL-SG108E.png deleted file mode 100644 index 6d3d57d..0000000 Binary files a/files/topology-images/TL-SG108E.png and /dev/null differ diff --git a/files/topology-images/atlasos.png b/files/topology-images/atlasos.png deleted file mode 100644 index c7c28a4..0000000 Binary files a/files/topology-images/atlasos.png and /dev/null differ diff --git a/files/topology-images/clamav.png b/files/topology-images/clamav.png deleted file mode 100644 index 8832dc8..0000000 Binary files a/files/topology-images/clamav.png and /dev/null differ diff --git a/files/topology-images/comfyui.png b/files/topology-images/comfyui.png deleted file mode 100644 index 88f1191..0000000 Binary files a/files/topology-images/comfyui.png and /dev/null differ diff --git a/files/topology-images/dgxos.png b/files/topology-images/dgxos.png deleted file mode 100644 index d593fc3..0000000 Binary files a/files/topology-images/dgxos.png and /dev/null differ diff --git a/files/topology-images/dovecot.png b/files/topology-images/dovecot.png deleted file mode 100644 index 16e35fa..0000000 Binary files a/files/topology-images/dovecot.png and /dev/null differ diff --git a/files/topology-images/firezone.png b/files/topology-images/firezone.png deleted file mode 100644 index fbbbf67..0000000 Binary files a/files/topology-images/firezone.png and /dev/null differ diff --git a/files/topology-images/garage.png b/files/topology-images/garage.png deleted file mode 100644 index 50306cf..0000000 Binary files a/files/topology-images/garage.png and /dev/null differ diff --git a/files/topology-images/home-manager.png b/files/topology-images/home-manager.png deleted file mode 100644 index 8ff9258..0000000 Binary files a/files/topology-images/home-manager.png and /dev/null differ diff --git a/files/topology-images/homebox.png b/files/topology-images/homebox.png deleted file mode 100644 index c4728f9..0000000 Binary files a/files/topology-images/homebox.png and /dev/null differ diff --git a/files/topology-images/kea.png b/files/topology-images/kea.png deleted file mode 100644 index 9e68bcd..0000000 Binary files a/files/topology-images/kea.png and /dev/null differ diff --git a/files/topology-images/minecraft.png b/files/topology-images/minecraft.png deleted file mode 100644 index a9690b9..0000000 Binary files a/files/topology-images/minecraft.png and /dev/null differ diff --git a/files/topology-images/nintendo-switch.png b/files/topology-images/nintendo-switch.png index b42d542..21f8de3 100644 Binary files a/files/topology-images/nintendo-switch.png and b/files/topology-images/nintendo-switch.png differ diff --git a/files/topology-images/nsd.png b/files/topology-images/nsd.png deleted file mode 100644 index 4a76c8f..0000000 Binary files a/files/topology-images/nsd.png and /dev/null differ diff --git a/files/topology-images/ollama.png b/files/topology-images/ollama.png deleted file mode 100644 index 8c2d452..0000000 Binary files a/files/topology-images/ollama.png and /dev/null differ diff --git a/files/topology-images/openwebui.png b/files/topology-images/openwebui.png deleted file mode 100644 index a158087..0000000 Binary files a/files/topology-images/openwebui.png and /dev/null differ diff --git a/files/topology-images/postfix.png b/files/topology-images/postfix.png deleted file mode 100644 index c809b0f..0000000 Binary files a/files/topology-images/postfix.png and /dev/null differ diff --git a/files/topology-images/roundcube.png b/files/topology-images/roundcube.png deleted file mode 100644 index 014dc92..0000000 Binary files a/files/topology-images/roundcube.png and /dev/null differ diff --git a/files/topology-images/rspamd.png b/files/topology-images/rspamd.png deleted file mode 100644 index 8bf4c12..0000000 Binary files a/files/topology-images/rspamd.png and /dev/null differ diff --git a/files/topology-images/sunshine.png b/files/topology-images/sunshine.png deleted file mode 100644 index 14c9b79..0000000 Binary files a/files/topology-images/sunshine.png and /dev/null differ diff --git a/files/topology-images/tp_link_tl-sg108e.jpg b/files/topology-images/tp_link_tl-sg108e.jpg deleted file mode 100644 index ea8826c..0000000 Binary files a/files/topology-images/tp_link_tl-sg108e.jpg and /dev/null differ diff --git a/files/topology-images/windows.png b/files/topology-images/windows.png deleted file mode 100644 index c16d05f..0000000 Binary files a/files/topology-images/windows.png and /dev/null differ diff --git a/flake.lock b/flake.lock index 5731952..44acb12 100644 --- a/flake.lock +++ b/flake.lock @@ -203,11 +203,11 @@ ] }, "locked": { - "lastModified": 1764011051, - "narHash": "sha256-M7SZyPZiqZUR/EiiBJnmyUbOi5oE/03tCeFrTiUZchI=", + "lastModified": 1728330715, + "narHash": "sha256-xRJ2nPOXb//u1jaBnDP56M7v5ldavjbtR6lfGqSvcKg=", "owner": "numtide", "repo": "devshell", - "rev": "17ed8d9744ebe70424659b0ef74ad6d41fc87071", + "rev": "dd6b80932022cea34a019e2bb32f6fa9e494dfef", "type": "github" }, "original": { @@ -426,11 +426,11 @@ "flake-compat_3": { "flake": false, "locked": { - "lastModified": 1761588595, - "narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=", + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", "owner": "edolstra", "repo": "flake-compat", - "rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", "type": "github" }, "original": { @@ -688,11 +688,11 @@ "systems": "systems_3" }, "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "lastModified": 1726560853, + "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=", "owner": "numtide", "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a", "type": "github" }, "original": { @@ -1369,11 +1369,11 @@ "pre-commit-hooks": "pre-commit-hooks" }, "locked": { - "lastModified": 1767198021, - "narHash": "sha256-O/7ZAy0OczYEy7zl+EegeekvRqb3JPh0btyBKtRvbVw=", + "lastModified": 1762088663, + "narHash": "sha256-rpCvFan9Dji1Vw4HfVqYdfWesz5sKZE3uSgYR9gRreA=", "owner": "oddlama", "repo": "nix-topology", - "rev": "0c052d902678b592b957eac2c250e4030fe70ebc", + "rev": "c15f569794a0f1a437850d0ac81675bcf23ca6cb", "type": "github" }, "original": { @@ -1862,11 +1862,11 @@ }, "nixpkgs_12": { "locked": { - "lastModified": 1766651565, - "narHash": "sha256-QEhk0eXgyIqTpJ/ehZKg9IKS7EtlWxF3N7DXy42zPfU=", + "lastModified": 1730531603, + "narHash": "sha256-Dqg6si5CqIzm87sp57j5nTaeBbWhHFaVyG7V6L8k3lY=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "3e2499d5539c16d0d173ba53552a4ff8547f4539", + "rev": "7ffd9ae656aec493492b44d0ddfb28e79a1ea25d", "type": "github" }, "original": { @@ -2574,14 +2574,18 @@ "nixpkgs": [ "nix-topology", "nixpkgs" + ], + "nixpkgs-stable": [ + "nix-topology", + "nixpkgs" ] }, "locked": { - "lastModified": 1765911976, - "narHash": "sha256-t3T/xm8zstHRLx+pIHxVpQTiySbKqcQbK+r+01XVKc0=", + "lastModified": 1730797577, + "narHash": "sha256-SrID5yVpyUfknUTGWgYkTyvdr9J1LxUym4om3SVGPkg=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "b68b780b69702a090c8bb1b973bab13756cc7a27", + "rev": "1864030ed24a2b8b4e4d386a5eeaf0c5369e50a9", "type": "github" }, "original": { diff --git a/hosts/nixos/aarch64-linux/belchsfactory/default.nix b/hosts/nixos/aarch64-linux/belchsfactory/default.nix index f44891b..f024b3b 100644 --- a/hosts/nixos/aarch64-linux/belchsfactory/default.nix +++ b/hosts/nixos/aarch64-linux/belchsfactory/default.nix @@ -61,7 +61,7 @@ postgresql = true; attic = true; garage = true; - hydra = true; + hydra = false; }; } diff --git a/hosts/nixos/aarch64-linux/liliputsteps/default.nix b/hosts/nixos/aarch64-linux/liliputsteps/default.nix index 28083e9..4a4ead2 100644 --- a/hosts/nixos/aarch64-linux/liliputsteps/default.nix +++ b/hosts/nixos/aarch64-linux/liliputsteps/default.nix @@ -1,4 +1,4 @@ -{ self, config, lib, minimal, ... }: +{ self, lib, minimal, ... }: { imports = [ ./hardware-configuration.nix @@ -10,16 +10,6 @@ topology.self = { icon = "devices.cloud-server"; - interfaces.ProxyJump = { - virtual = true; - physicalConnections = [ - (config.lib.topology.mkConnection "moonside" "lan") - (config.lib.topology.mkConnection "twothreetunnel" "lan") - (config.lib.topology.mkConnection "belchsfactory" "lan") - (config.lib.topology.mkConnection "stoicclub" "lan") - (config.lib.topology.mkConnection "eagleland" "wan") - ]; - }; }; swarselsystems = { diff --git a/hosts/nixos/aarch64-linux/stoicclub/default.nix b/hosts/nixos/aarch64-linux/stoicclub/default.nix index 38128a9..01b40d4 100644 --- a/hosts/nixos/aarch64-linux/stoicclub/default.nix +++ b/hosts/nixos/aarch64-linux/stoicclub/default.nix @@ -5,7 +5,6 @@ ./disk-config.nix "${self}/modules/nixos/optional/systemd-networkd-server.nix" - "${self}/modules/nixos/optional/nix-topology-self.nix" ]; topology.self = { diff --git a/hosts/nixos/aarch64-linux/twothreetunnel/default.nix b/hosts/nixos/aarch64-linux/twothreetunnel/default.nix index 2b16886..0b33db2 100644 --- a/hosts/nixos/aarch64-linux/twothreetunnel/default.nix +++ b/hosts/nixos/aarch64-linux/twothreetunnel/default.nix @@ -12,10 +12,7 @@ icon = "devices.cloud-server"; }; - globals.general = { - webProxy = config.node.name; - oauthServer = config.node.name; - }; + globals.general.webProxy = config.node.name; swarselsystems = { flakePath = "/root/.dotfiles"; @@ -38,7 +35,6 @@ "winters" "belchsfactory" "eagleland" - "hintbooth-adguardhome" ]; }; }; diff --git a/hosts/nixos/x86_64-linux/bakery/default.nix b/hosts/nixos/x86_64-linux/bakery/default.nix index f11512a..fb971d6 100644 --- a/hosts/nixos/x86_64-linux/bakery/default.nix +++ b/hosts/nixos/x86_64-linux/bakery/default.nix @@ -17,8 +17,8 @@ in ]; topology.self.interfaces = { - eth1.network = lib.mkForce "home"; - wifi = { }; + "eth1" = { }; + "wifi" = { }; }; swarselsystems = { diff --git a/hosts/nixos/x86_64-linux/hintbooth/default.nix b/hosts/nixos/x86_64-linux/hintbooth/default.nix index 648be45..3e3e344 100644 --- a/hosts/nixos/x86_64-linux/hintbooth/default.nix +++ b/hosts/nixos/x86_64-linux/hintbooth/default.nix @@ -1,27 +1,26 @@ -{ self, config, lib, minimal, confLib, globals, ... }: +{ self, config, lib, minimal, confLib, ... }: { imports = [ ./hardware-configuration.nix ./disk-config.nix - "${self}/modules/nixos/optional/systemd-networkd-server-home.nix" - "${self}/modules/nixos/optional/microvm-host.nix" + "${self}/modules/nixos/optional/systemd-networkd-server.nix" + "${self}/modules/nixos/optional/systemd-networkd-vlan.nix" ]; topology.self = { interfaces = { - lan2.physicalConnections = [{ node = "summers"; interface = "eth1"; }]; - lan3.physicalConnections = [{ node = "summers"; interface = "eth2"; }]; - lan4.physicalConnections = [{ node = "switch-bedroom"; interface = "eth1"; }]; - lan5.physicalConnections = [{ node = "switch-livingroom"; interface = "eth1"; }]; + "eth1" = { }; + "eth2" = { }; + "eth3" = { }; + "eth4" = { }; + "eth5" = { }; + "eth6" = { }; }; }; - globals.general = { - homeProxy = config.node.name; - routerServer = config.node.name; - }; + globals.general.homeProxy = config.node.name; swarselsystems = { info = "HUNSN RM02, 8GB RAM"; @@ -36,16 +35,12 @@ swapSize = "8G"; networkKernelModules = [ "igb" ]; withMicroVMs = true; - localVLANs = map (name: "${name}") (builtins.attrNames globals.networks.home-lan.vlans); - initrdVLAN = "home"; server = { wireguard.interfaces = { wgHome = { isServer = true; peers = [ "winters" - "hintbooth-adguardhome" - "hintbooth-nginx" ]; }; }; @@ -68,7 +63,6 @@ guests = lib.mkIf (!minimal && config.swarselsystems.withMicroVMs) ( { } // confLib.mkMicrovm "adguardhome" - // confLib.mkMicrovm "nginx" ); } diff --git a/hosts/nixos/x86_64-linux/hintbooth/guests/adguardhome.nix b/hosts/nixos/x86_64-linux/hintbooth/guests/adguardhome.nix new file mode 100644 index 0000000..2a0d511 --- /dev/null +++ b/hosts/nixos/x86_64-linux/hintbooth/guests/adguardhome.nix @@ -0,0 +1,23 @@ +{ self, lib, minimal, ... }: +{ + imports = [ + "${self}/profiles/nixos/microvm" + "${self}/modules/nixos" + ]; + + swarselsystems = { + isMicroVM = true; + }; + +} // lib.optionalAttrs (!minimal) { + + microvm = { + mem = 1024 * 1; + vcpu = 1; + }; + + swarselprofiles = { + microvm = true; + }; + +} diff --git a/hosts/nixos/x86_64-linux/hintbooth/guests/adguardhome/default.nix b/hosts/nixos/x86_64-linux/hintbooth/guests/adguardhome/default.nix deleted file mode 100644 index b10f730..0000000 --- a/hosts/nixos/x86_64-linux/hintbooth/guests/adguardhome/default.nix +++ /dev/null @@ -1,43 +0,0 @@ -{ self, config, lib, minimal, ... }: -{ - imports = [ - "${self}/profiles/nixos/microvm" - "${self}/modules/nixos" - ]; - - swarselsystems = { - isMicroVM = true; - isImpermanence = true; - proxyHost = "twothreetunnel"; - server = { - wireguard.interfaces = { - wgHome = { - isClient = true; - serverName = "hintbooth"; - }; - wgProxy = { - isClient = true; - serverName = "twothreetunnel"; - }; - }; - }; - }; - - globals.general.homeDnsServer = config.node.name; - -} // lib.optionalAttrs (!minimal) { - - microvm = { - mem = 1024 * 1; - vcpu = 1; - }; - - swarselprofiles = { - microvm = true; - }; - - swarselmodules.server = { - adguardhome = true; - }; - -} diff --git a/hosts/nixos/x86_64-linux/hintbooth/guests/nginx/default.nix b/hosts/nixos/x86_64-linux/hintbooth/guests/nginx/default.nix deleted file mode 100644 index 39656a1..0000000 --- a/hosts/nixos/x86_64-linux/hintbooth/guests/nginx/default.nix +++ /dev/null @@ -1,60 +0,0 @@ -{ self, config, lib, minimal, globals, confLib, ... }: -let - inherit (confLib.static) nginxAccessRules; -in -{ - imports = [ - "${self}/profiles/nixos/microvm" - "${self}/modules/nixos" - ]; - - swarselsystems = { - isMicroVM = true; - isImpermanence = true; - proxyHost = config.node.name; - server = { - wireguard.interfaces = { - wgHome = { - isClient = true; - serverName = "hintbooth"; - }; - }; - }; - }; - - globals.general.homeWebProxy = config.node.name; - -} // lib.optionalAttrs (!minimal) { - - microvm = { - mem = 3072 * 1; - vcpu = 1; - }; - - swarselprofiles = { - microvm = true; - }; - - swarselmodules.server = { - nginx = true; - }; - - services.nginx = { - upstreams.fritzbox = { - servers.${globals.networks.home-lan.hosts.fritzbox.ipv4} = { }; - }; - virtualHosts.${globals.services.fritzbox.domain} = { - useACMEHost = globals.domains.main; - forceSSL = true; - acmeRoot = null; - locations."/" = { - proxyPass = "http://fritzbox"; - proxyWebsockets = true; - }; - extraConfig = '' - proxy_ssl_verify off; - '' + nginxAccessRules; - }; - }; - -} diff --git a/hosts/nixos/x86_64-linux/hintbooth/secrets/adguardhome/secrets.yaml b/hosts/nixos/x86_64-linux/hintbooth/secrets/adguardhome/secrets.yaml deleted file mode 100644 index ff54541..0000000 --- a/hosts/nixos/x86_64-linux/hintbooth/secrets/adguardhome/secrets.yaml +++ /dev/null @@ -1,57 +0,0 @@ -wireguard-private-key: ENC[AES256_GCM,data:5RdR6CvGBwaklSgiP0kmz/ShroIa1By7ZqgxKrnSGjHRyrzaeWGTuJmqKJM=,iv:D5UmcQkbRs8WVQUA8XpFCwLy8+O4+RoJLWOkHj0H7ss=,tag:feSuK9jW+wLeygqhKHycDw==,type:str] -sops: - age: - - recipient: age1wmx8y2hs83j2u5srdnfxljrzxm8jtxl6fr0mq7xf2ldxyglpzf2qq89rpx - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBMEM4alliWlBCT3VsbVA5 - OGt5bmQvZW1TaUNkbWtFdzVGNDNpY0hBOVhzCm84TldYNHBrU01HMlBkbGNwZFAw - WVk0T3FycVRHUUNtM1pTYkQ4Qmw3RTgKLS0tIE9LUlNEVjJHOGVIK1RSMmRXUDF6 - QlRKY1hRVzNTVXhESUd3OElXL2pBZXcKDWYoOzi2b4qeIbCVCfTj0lTW+OfbnsXB - 8MugCHu7+b+ju0v/lUP66jDW9/2AH4PzHtCNHjsafyzr2qnW8HlOzA== - -----END AGE ENCRYPTED FILE----- - - recipient: age1c2enwel9un28dcs4wg0vcyamx9a4a6g3walkhu8w5lqhmd804paq9d24as - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJRWJXR2tYdEd4cTZsSi9l - Tm1pSC9pek5BakpEMlkwVTcrMlBuVzlXWUVrCmlnV0xJc25nL0twK3VCZ3FRK2x2 - RW52Q1NxWUhTUGY0NnQ0WEhLMWxIcFUKLS0tIG83eVM0KzdLQ004aDRKNTYvdmVZ - d3ZOSStBMFpSU2ZjNWhFRkREQWlUdmcKggVvLy1mLYGf8084RQtlipS4+z4dfPsN - HZfid0srwYnezlQ5qOY8/HrDLWHEyuZ4xFZVi4n0k49qBpNwJdmvyQ== - -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-01-02T04:14:03Z" - mac: ENC[AES256_GCM,data:aA+oIq31QBla9hOpApaMeP7MFl/hI0kDjC1QyPkmexXuMB2pQJ6bBEmazreX2m2TPtHv1rtVUak7F6TbA+97IFb9EQFuAREi1Ca0xjz2eGVFQKu94qkS/FNemXTAkEZxC9LQ1TRqNXXNITehKUeIN65epuNbWqo+iOW0OHEXm/w=,iv:1NKL2PZBUDyHEIiB2ZpvTdCh9ZO+r8bPyJo+EO1PBmQ=,tag:5W9owm1Z+7O1CGVmH1afUw==,type:str] - pgp: - - created_at: "2026-01-02T21:12:51Z" - enc: |- - -----BEGIN PGP MESSAGE----- - - hQIMAwDh3VI7VctTARAAmvkQ9V14f0BT/bNdFVZtTlY4yVon37CX32SZPUcHV7o8 - Dya0sZd9tuVATSv79TnybscuNx95fkoZJwujBfAadexn2zY8zl1oEWEHx7p+8/mE - W8JbQAjbcbX9sNQYXc8kYJylBThmgNN/HXK7CGtgDFr9xnGzDBnDm/M31P1HwYBm - IdIQgFGErEt1K3xvw28Lk3tPuZLK3Y+H2Yna7RRF6K1blGJUvEnL6yFdA10/eFW7 - 8066mO26F2l5xFuktK0nNeniLHKa5VVYp8iM+JMhX38l0wiIi8pGyxo3uAjNpa0w - IfpCneEBe/yyaUPcWMjXmUG5LJe3kWUup8cSzvu01Z3W159/QsflxIMkIsklqhim - B2zuPdAlYsjjS/05DIHInN2IIB/rjADkQvXji1XYLhWJj4jxDeck/UIc6Q22TED+ - autlbl8d/5sqyO5ghPpShF/s0vMTqUfpXZrDrbuyDFqCfwi0ahP03bUsv20ZEz6u - zG3K5HuXHh7ATSppwuMbcv7vcjF1tkbo6XhWZDv0rY0DFWqiYhnxWwlFlGLxf4zX - g6r7Ca/E/YXG/eOET6M9DxwHjj0D7u/ryAkCktqPL9w8oNGarZQ/xMx0+ocI3byc - Zvzlmd63BtgaGNSxH3stK29KN3ED8cDkG/JzAxCATWiUBBkqW/ga4sGZqtLlSO+F - AgwDC9FRLmchgYQBD/9JbFZie25PO2CyELlUWm5SmJcugT9SK/mIA2fe1PlA+Gnf - 5z9iXraMSQchz4R1IoiixDhubwKeKp/auqhlOPvo58Lsi6iDR/WaLWabD+hcyAb1 - ck/f/PUzTLhlLcfu18VPfXVzfnky3dX8P5aS0WMLAQblj2RaaiHxnPqf49kXSn3q - VSJ0pr0nEsPuWtoCkHUAwAJ8X5GPXN2OD4YbHsNaA9h2vrJAxNd5+HNsvg8JtI88 - X/uMM7cWcaXcmNZOz166HUIPcJ5cabJ48Sv8sDfMPOcTiJkMiESBnRYTwdUcp08m - nGipSrUeW3pVOC1bGyukZb6sF84pTtCpqS+kOSfKFlxFFdAEcpzFIPuOMeo2dbKj - GSGPDemZFC2yFq883yk9/mZbgjOUsqrj0ZP3rCD5ZHpfUM5IxGQ+mKaOucTXYmif - lrTPMYnAc7pHxKZ87BgiKBYrfRAZvorLYKv8zG8YagAUw8iCtc68YUUdvLW9haQf - rwWCU1z+sszYSac7I57gfqICQhMUbs1n9S2Cn0C0xo4q2Lu36ysip4rEVGg6TmUu - znXYu+3orodw2TwC0tGxXHYKwmlr7EGnBCbdVKpDoCbV6cYkDYoPUFg0alqIPd5r - KCkee9MaCLLX7IdBrbLf1lkHGwSAs81GfZRMLBauM7/hn+hMUeIJnMbtJnVIB9Je - AdT2nSH06+POnjvxa2t0dUasnG/6ISBRSk6FgBBZ+pdVlrvaB4javgWGpiAWCUu6 - b2CMZF3HullmLj+wwAKlsZsIOXGICN5GeQxLHYF8Kx7Doj68Owu/zGM5MS+7XQ== - =wYdb - -----END PGP MESSAGE----- - fp: 4BE7925262289B476DBBC17B76FD3810215AE097 - unencrypted_suffix: _unencrypted - version: 3.11.0 diff --git a/hosts/nixos/x86_64-linux/hintbooth/secrets/nginx/secrets.yaml b/hosts/nixos/x86_64-linux/hintbooth/secrets/nginx/secrets.yaml deleted file mode 100644 index cc13dad..0000000 --- a/hosts/nixos/x86_64-linux/hintbooth/secrets/nginx/secrets.yaml +++ /dev/null @@ -1,57 +0,0 @@ -wireguard-private-key: ENC[AES256_GCM,data:3T0ZoPAs/OIkhdZlH171d9d2Ycxtp4WfI92pTBI3vRw7BVvEgQZKu5DCvbA=,iv:gsczaGwcI3JocOazMIEsgHFruEKDPxOTUQzx+rdCaio=,tag:/Sw7QsZ4fV+BMWdfcUevBA==,type:str] -sops: - age: - - recipient: age1wmx8y2hs83j2u5srdnfxljrzxm8jtxl6fr0mq7xf2ldxyglpzf2qq89rpx - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBMEM4alliWlBCT3VsbVA5 - OGt5bmQvZW1TaUNkbWtFdzVGNDNpY0hBOVhzCm84TldYNHBrU01HMlBkbGNwZFAw - WVk0T3FycVRHUUNtM1pTYkQ4Qmw3RTgKLS0tIE9LUlNEVjJHOGVIK1RSMmRXUDF6 - QlRKY1hRVzNTVXhESUd3OElXL2pBZXcKDWYoOzi2b4qeIbCVCfTj0lTW+OfbnsXB - 8MugCHu7+b+ju0v/lUP66jDW9/2AH4PzHtCNHjsafyzr2qnW8HlOzA== - -----END AGE ENCRYPTED FILE----- - - recipient: age1c2enwel9un28dcs4wg0vcyamx9a4a6g3walkhu8w5lqhmd804paq9d24as - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJRWJXR2tYdEd4cTZsSi9l - Tm1pSC9pek5BakpEMlkwVTcrMlBuVzlXWUVrCmlnV0xJc25nL0twK3VCZ3FRK2x2 - RW52Q1NxWUhTUGY0NnQ0WEhLMWxIcFUKLS0tIG83eVM0KzdLQ004aDRKNTYvdmVZ - d3ZOSStBMFpSU2ZjNWhFRkREQWlUdmcKggVvLy1mLYGf8084RQtlipS4+z4dfPsN - HZfid0srwYnezlQ5qOY8/HrDLWHEyuZ4xFZVi4n0k49qBpNwJdmvyQ== - -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-01-03T05:23:18Z" - mac: ENC[AES256_GCM,data:u9N7GzLPDW7cHT4mkUAC9Diq1RdV5iSwcz/fqzXQKRmic09eVydAgyk2g6NbJ+4tBbAjIfeUch8Bhf5eG0sGzeDkb1qWAMEnP8EPmQ64OdRyN2SxJgxkc8KFGxkrGz9slS2ozWth6q/tKBSsOYbo8WDlCqXhmYp+zBxvYFR30Mg=,iv:HC1e2i0E7dV9/au+A0kHd+UXDhw3xf7RbTpwJI+hjpY=,tag:dPCDh9qalNtbHIhs//cBpg==,type:str] - pgp: - - created_at: "2026-01-02T21:12:51Z" - enc: |- - -----BEGIN PGP MESSAGE----- - - hQIMAwDh3VI7VctTARAAmvkQ9V14f0BT/bNdFVZtTlY4yVon37CX32SZPUcHV7o8 - Dya0sZd9tuVATSv79TnybscuNx95fkoZJwujBfAadexn2zY8zl1oEWEHx7p+8/mE - W8JbQAjbcbX9sNQYXc8kYJylBThmgNN/HXK7CGtgDFr9xnGzDBnDm/M31P1HwYBm - IdIQgFGErEt1K3xvw28Lk3tPuZLK3Y+H2Yna7RRF6K1blGJUvEnL6yFdA10/eFW7 - 8066mO26F2l5xFuktK0nNeniLHKa5VVYp8iM+JMhX38l0wiIi8pGyxo3uAjNpa0w - IfpCneEBe/yyaUPcWMjXmUG5LJe3kWUup8cSzvu01Z3W159/QsflxIMkIsklqhim - B2zuPdAlYsjjS/05DIHInN2IIB/rjADkQvXji1XYLhWJj4jxDeck/UIc6Q22TED+ - autlbl8d/5sqyO5ghPpShF/s0vMTqUfpXZrDrbuyDFqCfwi0ahP03bUsv20ZEz6u - zG3K5HuXHh7ATSppwuMbcv7vcjF1tkbo6XhWZDv0rY0DFWqiYhnxWwlFlGLxf4zX - g6r7Ca/E/YXG/eOET6M9DxwHjj0D7u/ryAkCktqPL9w8oNGarZQ/xMx0+ocI3byc - Zvzlmd63BtgaGNSxH3stK29KN3ED8cDkG/JzAxCATWiUBBkqW/ga4sGZqtLlSO+F - AgwDC9FRLmchgYQBD/9JbFZie25PO2CyELlUWm5SmJcugT9SK/mIA2fe1PlA+Gnf - 5z9iXraMSQchz4R1IoiixDhubwKeKp/auqhlOPvo58Lsi6iDR/WaLWabD+hcyAb1 - ck/f/PUzTLhlLcfu18VPfXVzfnky3dX8P5aS0WMLAQblj2RaaiHxnPqf49kXSn3q - VSJ0pr0nEsPuWtoCkHUAwAJ8X5GPXN2OD4YbHsNaA9h2vrJAxNd5+HNsvg8JtI88 - X/uMM7cWcaXcmNZOz166HUIPcJ5cabJ48Sv8sDfMPOcTiJkMiESBnRYTwdUcp08m - nGipSrUeW3pVOC1bGyukZb6sF84pTtCpqS+kOSfKFlxFFdAEcpzFIPuOMeo2dbKj - GSGPDemZFC2yFq883yk9/mZbgjOUsqrj0ZP3rCD5ZHpfUM5IxGQ+mKaOucTXYmif - lrTPMYnAc7pHxKZ87BgiKBYrfRAZvorLYKv8zG8YagAUw8iCtc68YUUdvLW9haQf - rwWCU1z+sszYSac7I57gfqICQhMUbs1n9S2Cn0C0xo4q2Lu36ysip4rEVGg6TmUu - znXYu+3orodw2TwC0tGxXHYKwmlr7EGnBCbdVKpDoCbV6cYkDYoPUFg0alqIPd5r - KCkee9MaCLLX7IdBrbLf1lkHGwSAs81GfZRMLBauM7/hn+hMUeIJnMbtJnVIB9Je - AdT2nSH06+POnjvxa2t0dUasnG/6ISBRSk6FgBBZ+pdVlrvaB4javgWGpiAWCUu6 - b2CMZF3HullmLj+wwAKlsZsIOXGICN5GeQxLHYF8Kx7Doj68Owu/zGM5MS+7XQ== - =wYdb - -----END PGP MESSAGE----- - fp: 4BE7925262289B476DBBC17B76FD3810215AE097 - unencrypted_suffix: _unencrypted - version: 3.11.0 diff --git a/hosts/nixos/x86_64-linux/pyramid/default.nix b/hosts/nixos/x86_64-linux/pyramid/default.nix index 54b80c5..5f662f8 100644 --- a/hosts/nixos/x86_64-linux/pyramid/default.nix +++ b/hosts/nixos/x86_64-linux/pyramid/default.nix @@ -23,9 +23,9 @@ in topology.self = { interfaces = { - eth1.network = lib.mkForce "home"; - wifi = { }; - fritz-wg.network = "fritz-wg"; + "eth1" = { }; + "wifi" = { }; + "fritz-wg" = { }; }; }; @@ -64,7 +64,7 @@ in main = { # name = "BOE 0x0BC9 Unknown"; name = "BOE 0x0BC9"; - mode = "2560x1600"; + mode = "2560x1600"; # TEMPLATE scale = "1"; position = "2560,0"; workspace = "15:L"; @@ -78,8 +78,8 @@ in personal = true; }; - # networking.nftables = { - # enable = lib.mkForce false; - # firewall.enable = lib.mkForce false; - # }; + networking.nftables = { + enable = lib.mkForce false; + firewall.enable = lib.mkForce false; + }; } diff --git a/hosts/nixos/x86_64-linux/pyramid/disk-config.nix b/hosts/nixos/x86_64-linux/pyramid/disk-config.nix index a3e2361..6feb4c8 100644 --- a/hosts/nixos/x86_64-linux/pyramid/disk-config.nix +++ b/hosts/nixos/x86_64-linux/pyramid/disk-config.nix @@ -75,7 +75,7 @@ fileSystems = { "/persist".neededForBoot = true; "/home".neededForBoot = true; - "/".neededForBoot = true; # this is ok because this is not a impermanence host + "/".neededForBoot = true; "/var/log".neededForBoot = true; }; } diff --git a/hosts/nixos/x86_64-linux/winters/secrets/pii.nix.enc b/hosts/nixos/x86_64-linux/winters/secrets/pii.nix.enc index dc6fd8a..8256be6 100644 --- a/hosts/nixos/x86_64-linux/winters/secrets/pii.nix.enc +++ b/hosts/nixos/x86_64-linux/winters/secrets/pii.nix.enc @@ -1,5 +1,5 @@ { - "data": "ENC[AES256_GCM,data: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,iv:kkH/Hy/0PNzkVdTfYTgKBAN6nYslP0OFIndsmORZVEg=,tag:j/fMiT9DCog0CHnM74MNMw==,type:str]", + "data": "ENC[AES256_GCM,data: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,iv:Wc2rOI9aWgchjFGCl5R8d6E6GmYEKCIkIAZlUIlbE/4=,tag:3p301gA9WrBjwcpXs68ayg==,type:str]", "sops": { "age": [ { @@ -7,8 +7,8 @@ "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3UFZTaXFNdjF2UmRFd3VL\nY2pZZ3ZaRkhZSjdVUjIraHV5ZlNaNGtwM3k0CkZ4OVRFcmR3MFBDcmdsbWFId3Iy\nVzQyUGI1eG44d3JFL2NvZEg4NnduT2cKLS0tIEdhOEZETk9nRTlVbmJ5UW9GalVx\nS00yaUpJZVFVNThFei8yRzJYejRkYk0Kf6Z8WnG8phRtFIUWIPys3PW0OImhAcF+\nUFLuL4Qr7zWaeItCRieYCs1yBn7KbUJHZNkJcvnkYW50NYvlEa8wBw==\n-----END AGE ENCRYPTED FILE-----\n" } ], - "lastmodified": "2026-01-02T22:52:45Z", - "mac": "ENC[AES256_GCM,data:p/m76sd+5HhD+tz7oSnoSzVRCnB1czTUTF90LSyLQuL6aVyTpVZp+p6/CnYc/fG+L/8wBUsLrwwajl22S2+MZAqvQFoYQwY/AiFb10wZNK2fzPEURW3P+QYzaf62nb4G3GlckjAcGxGyeGcU4TnL1qZEDgp/KcdZpsUwvVQvV/U=,iv:k7m4dOr13gczZTGlz7uHIQB/uFPEQJX19uHuLB1fupg=,tag:mzpbLMV5aun7IOvPIJv0ng==,type:str]", + "lastmodified": "2025-12-31T12:22:14Z", + "mac": "ENC[AES256_GCM,data:H17OWQwkZaugzTuMM8kBPZLYZs/poaLJt8osoY/gzC2CMpWXUtWpwgJ83CO7GkiPrPN2SZtEiaADP3PvZZqVcV5rDJNhdELmdvZfB14RQDUD9rYfnIX5uuzMMII+kguTkk+Zd1IRWv+MN9y4cdhys0lYJ7Nw1RyEMP9Bxd1zvcA=,iv:01Yode7T/2pUP1dFLyIUoDIfeWRWKf1Qq7pHvUDKQJQ=,tag:Ldxq5cRB2iexLhIrBfqGVQ==,type:str]", "pgp": [ { "created_at": "2025-12-02T14:59:33Z", diff --git a/modules/nixos/common/impermanence.nix b/modules/nixos/common/impermanence.nix index 2e9b437..e111c86 100644 --- a/modules/nixos/common/impermanence.nix +++ b/modules/nixos/common/impermanence.nix @@ -1,7 +1,7 @@ { config, lib, ... }: let mapperTarget = lib.swarselsystems.mkIfElse config.swarselsystems.isCrypted "/dev/mapper/cryptroot" "/dev/disk/by-label/nixos"; - inherit (config.swarselsystems) isImpermanence isCrypted isBtrfs; + inherit (config.swarselsystems) isImpermanence isCrypted; in { options.swarselmodules.impermanence = lib.mkEnableOption "impermanence config"; @@ -17,7 +17,7 @@ in # So if it doesn't run, the btrfs system effectively acts like a normal system # Taken from https://github.com/NotAShelf/nyx/blob/2a8273ed3f11a4b4ca027a68405d9eb35eba567b/modules/core/common/system/impermanence/default.nix boot.tmp.useTmpfs = lib.mkIf (!isImpermanence) true; - boot.initrd.systemd = lib.mkIf (isImpermanence && isBtrfs) { + boot.initrd.systemd = lib.mkIf isImpermanence { enable = true; services.rollback = { description = "Rollback BTRFS root subvolume to a pristine state"; diff --git a/modules/nixos/common/nodes.nix b/modules/nixos/common/nodes.nix index daa270c..236354d 100644 --- a/modules/nixos/common/nodes.nix +++ b/modules/nixos/common/nodes.nix @@ -33,7 +33,6 @@ let (splitPath "services.kanidm.provision.systems.oauth2") (splitPath "sops.secrets") (splitPath "swarselsystems.server.dns") - (splitPath "topology.self.services") ] ++ expandOptions (splitPath "networking.nftables.firewall") [ "zones" "rules" ] ++ expandOptions (splitPath "services.firezone.gateway") [ "enable" "name" "apiUrl" "tokenFile" "package" "logLevel" ] diff --git a/modules/nixos/optional/microvm-guest.nix b/modules/nixos/optional/microvm-guest.nix index 21c29ce..adf069f 100644 --- a/modules/nixos/optional/microvm-guest.nix +++ b/modules/nixos/optional/microvm-guest.nix @@ -1,10 +1,11 @@ -{ self, lib, config, inputs, microVMParent, nodes, ... }: +{ self, inputs, ... }: { imports = [ inputs.disko.nixosModules.disko inputs.home-manager.nixosModules.home-manager inputs.impermanence.nixosModules.impermanence inputs.lanzaboote.nixosModules.lanzaboote + inputs.microvm.nixosModules.host inputs.microvm.nixosModules.microvm inputs.nix-index-database.nixosModules.nix-index inputs.nix-minecraft.nixosModules.minecraft-servers @@ -22,51 +23,6 @@ ]; config = { - _module.args.dns = inputs.dns; - - nix.settings.experimental-features = [ - "nix-command" - "flakes" - ]; - systemd.services."systemd-networkd".environment.SYSTEMD_LOG_LEVEL = "debug"; - # NOTE: this is needed, we dont import sevrer network module for microvms - globals.hosts.${config.node.name}.isHome = true; - - fileSystems."/persist".neededForBoot = lib.mkForce true; - - systemd.network.networks."10-vlan-services" = { - dhcpV6Config = { - WithoutRA = "solicit"; - # duid-en is nice in principle, but I already have MAC info anyways for reservations - DUIDType = "link-layer"; - }; - # networkConfig = { - # IPv6PrivacyExtensions = "no"; - # IPv6AcceptRA = false; - # }; - ipv6AcceptRAConfig = { - DHCPv6Client = "always"; - }; - }; - - microvm = { - shares = [ - { - tag = "persist"; - source = "${lib.optionalString nodes.${microVMParent}.config.swarselsystems.isImpermanence "/persist"}/microvms/${config.networking.hostName}"; - mountPoint = "/persist"; - proto = "virtiofs"; - } - ]; - # mount the writeable overlay so that we can use nix shells inside the microvm - volumes = [ - { - image = "/tmp/nix-store-overlay-${config.networking.hostName}.img"; - autoCreate = true; - mountPoint = config.microvm.writableStoreOverlay; - size = 1024; - } - ]; - }; + system.stateVersion = "23.05"; }; } diff --git a/modules/nixos/optional/microvm-host.nix b/modules/nixos/optional/microvm-host.nix index 073353c..2948824 100644 --- a/modules/nixos/optional/microvm-host.nix +++ b/modules/nixos/optional/microvm-host.nix @@ -1,21 +1,13 @@ { config, lib, ... }: { + # imports = [ + # inputs.microvm.nixosModules.host + # ]; + config = lib.mkIf (config.guests != { }) { - systemd.tmpfiles.settings."15-microvms" = builtins.listToAttrs ( - map - (path: { - name = "${lib.optionalString config.swarselsystems.isImpermanence "/persist"}/microvms/${path}"; - value = { - d = { - group = "kvm"; - user = "microvm"; - mode = "0750"; - }; - }; - }) - (builtins.attrNames config.guests) - ); - + microvm = { + hypervisor = lib.mkDefault "qemu"; + }; }; } diff --git a/modules/nixos/optional/nix-topology-self.nix b/modules/nixos/optional/nix-topology-self.nix index e713893..66299f0 100644 --- a/modules/nixos/optional/nix-topology-self.nix +++ b/modules/nixos/optional/nix-topology-self.nix @@ -1,25 +1,13 @@ -{ lib, config, globals, confLib, ... }: -let - inherit (confLib.static) webProxy; -in +{ lib, config, globals, ... }: { topology.self = { icon = lib.mkIf config.swarselsystems.isCloud "devices.cloud-server"; - interfaces = { - wan = lib.mkIf (config.swarselsystems.isCloud && config.swarselsystems.server.localNetwork == "wan") { }; - lan = lib.mkIf (config.swarselsystems.isCloud && config.swarselsystems.server.localNetwork == "lan") { }; - wgProxy = lib.mkIf (config.swarselsystems.server.wireguard ? wgHome) { - addresses = [ globals.networks."${webProxy}-wg.hosts".${config.node.name}.ipv4 ]; - renderer.hidePhysicalConnections = true; - virtual = true; - type = "wireguard"; - }; - wgHome = lib.mkIf (config.swarselsystems.server.wireguard ? wgHome) { - addresses = [ globals.networks.home-wgHome.hosts.${config.node.name}.ipv4 ]; - renderer.hidePhysicalConnections = true; - virtual = true; - type = "wireguard"; - }; + interfaces.wan = lib.mkIf config.swarselsystems.isCloud { }; + interfaces.wg = lib.mkIf (config.swarselsystems.server.wireguard.isClient || config.swarselsystems.server.wireguard.isServer) { + addresses = [ globals.networks.twothreetunnel-wg.hosts.${config.node.name}.ipv4 ]; + renderer.hidePhysicalConnections = true; + virtual = true; + type = "wireguard"; }; }; } diff --git a/modules/nixos/optional/systemd-networkd-base.nix b/modules/nixos/optional/systemd-networkd-base.nix deleted file mode 100644 index 238a1ff..0000000 --- a/modules/nixos/optional/systemd-networkd-base.nix +++ /dev/null @@ -1,13 +0,0 @@ -{ lib, config, ... }: -{ - networking = { - useDHCP = lib.mkForce false; - useNetworkd = true; - dhcpcd.enable = lib.mkIf (!config.swarselsystems.isMicroVM) false; - renameInterfacesByMac = lib.mkIf (!config.swarselsystems.isMicroVM) (lib.mapAttrs (_: v: if (v ? mac) then v.mac else "") ( - config.repo.secrets.local.networking.networks or { } - )); - }; - - systemd.network.enable = true; -} diff --git a/modules/nixos/optional/systemd-networkd-server-home.nix b/modules/nixos/optional/systemd-networkd-server-home.nix deleted file mode 100644 index 9b6ef50..0000000 --- a/modules/nixos/optional/systemd-networkd-server-home.nix +++ /dev/null @@ -1,131 +0,0 @@ -{ self, lib, config, globals, ... }: -let - inherit (globals.general) routerServer; - inherit (config.swarselsystems) withMicroVMs isCrypted initrdVLAN; - - isRouter = config.node.name == routerServer; - localVLANsList = config.swarselsystems.localVLANs; - localVLANs = lib.genAttrs localVLANsList (x: globals.networks.home-lan.vlans.${x}); -in -{ - imports = [ - "${self}/modules/nixos/optional/systemd-networkd-server.nix" - ]; - config = { - assertions = [ - { - assertion = ((localVLANsList != [ ]) && (initrdVLAN != null)) || (localVLANsList == [ ]) || (!isCrypted); - message = "This host uses VLANs and disk encryption, thus a VLAN must be specified for initrd or disk encryption must be removed."; - } - ]; - - boot.initrd = lib.mkIf (isCrypted && (localVLANsList != [ ]) && (!isRouter)) { - availableKernelModules = [ "8021q" ]; - systemd.network = { - enable = true; - netdevs."30-vlan-${initrdVLAN}" = { - netdevConfig = { - Kind = "vlan"; - Name = "vlan-${initrdVLAN}"; - }; - vlanConfig.Id = globals.networks.home-lan.vlans.${initrdVLAN}.id; - }; - networks = { - "10-lan" = { - matchConfig.Name = "lan"; - # This interface should only be used from attached vlans. - # So don't acquire a link local address and only wait for - # this interface to gain a carrier. - networkConfig.LinkLocalAddressing = "no"; - linkConfig.RequiredForOnline = "carrier"; - vlan = [ "vlan-${initrdVLAN}" ]; - }; - "30-vlan-${initrdVLAN}" = { - address = [ - globals.networks.home-lan.vlans.${initrdVLAN}.hosts.${config.node.name}.cidrv4 - globals.networks.home-lan.vlans.${initrdVLAN}.hosts.${config.node.name}.cidrv6 - ]; - matchConfig.Name = "vlan-${initrdVLAN}"; - networkConfig = { - IPv6PrivacyExtensions = "yes"; - }; - linkConfig.RequiredForOnline = "routable"; - }; - }; - }; - }; - - systemd.network = { - netdevs = lib.flip lib.concatMapAttrs localVLANs ( - vlanName: vlanCfg: { - "30-vlan-${vlanName}" = { - netdevConfig = { - Kind = "vlan"; - Name = "vlan-${vlanName}"; - }; - vlanConfig.Id = vlanCfg.id; - }; - # Create a MACVTAP for ourselves too, so that we can communicate with - # our guests on the same interface. - "40-me-${vlanName}" = lib.mkIf withMicroVMs { - netdevConfig = { - Name = "me-${vlanName}"; - Kind = "macvlan"; - }; - extraConfig = '' - [MACVLAN] - Mode=bridge - ''; - }; - } - ); - networks = { - "10-lan" = lib.mkIf (!isRouter) { - matchConfig.Name = "lan"; - # This interface should only be used from attached vlans. - # So don't acquire a link local address and only wait for - # this interface to gain a carrier. - networkConfig.LinkLocalAddressing = "no"; - linkConfig.RequiredForOnline = "carrier"; - vlan = (map (name: "vlan-${name}") (builtins.attrNames localVLANs)); - }; - # Remaining macvtap interfaces should not be touched. - "90-macvtap-ignore" = lib.mkIf withMicroVMs { - matchConfig.Kind = "macvtap"; - linkConfig.ActivationPolicy = "manual"; - linkConfig.Unmanaged = "yes"; - }; - } - // lib.flip lib.concatMapAttrs localVLANs ( - vlanName: vlanCfg: - let - me = { - address = [ - vlanCfg.hosts.${config.node.name}.cidrv4 - vlanCfg.hosts.${config.node.name}.cidrv6 - ]; - gateway = lib.optionals (vlanName == "services") [ vlanCfg.hosts.${routerServer}.ipv4 vlanCfg.hosts.${routerServer}.ipv6 ]; - matchConfig.Name = "${if withMicroVMs then "me" else "vlan"}-${vlanName}"; - networkConfig.IPv6PrivacyExtensions = "yes"; - linkConfig.RequiredForOnline = "routable"; - }; - - in - { - "30-vlan-${vlanName}" = if (!withMicroVMs) then me else { - matchConfig.Name = "vlan-${vlanName}"; - # This interface should only be used from attached macvlans. - # So don't acquire a link local address and only wait for - # this interface to gain a carrier. - networkConfig.LinkLocalAddressing = "no"; - networkConfig.MACVLAN = "me-${vlanName}"; - linkConfig.RequiredForOnline = if isRouter then "no" else "carrier"; - }; - "40-me-${vlanName}" = lib.mkIf withMicroVMs (lib.mkDefault me); - } - ); - }; - - }; - -} diff --git a/modules/nixos/optional/systemd-networkd-server.nix b/modules/nixos/optional/systemd-networkd-server.nix index 76b2bf3..99019b2 100644 --- a/modules/nixos/optional/systemd-networkd-server.nix +++ b/modules/nixos/optional/systemd-networkd-server.nix @@ -1,30 +1,28 @@ -{ self, lib, config, globals, ... }: -let - inherit (config.swarselsystems) isCrypted localVLANs; - inherit (globals.general) routerServer; - - isRouter = config.node.name == routerServer; - ifName = config.swarselsystems.server.localNetwork; -in +{ lib, config, globals, ... }: { - imports = [ - "${self}/modules/nixos/optional/systemd-networkd-base.nix" - ]; - - boot.initrd.systemd.network = lib.mkIf (isCrypted && ((localVLANs == [ ]) || isRouter)) { + networking = { + useDHCP = lib.mkForce false; + useNetworkd = true; + dhcpcd.enable = false; + renameInterfacesByMac = lib.mapAttrs (_: v: if (v ? mac) then v.mac else "") ( + config.repo.secrets.local.networking.networks or { } + ); + }; + boot.initrd.systemd.network = { enable = true; - networks."10-${ifName}" = config.systemd.network.networks."10-${ifName}"; + networks."10-${config.swarselsystems.server.localNetwork}" = config.systemd.network.networks."10-${config.swarselsystems.server.localNetwork}"; }; systemd = { network = { + enable = true; wait-online.enable = false; networks = let netConfig = config.repo.secrets.local.networking; in { - "10-${ifName}" = lib.mkIf (isRouter || (localVLANs == [ ])) { + "10-${config.swarselsystems.server.localNetwork}" = { address = [ "${globals.networks.${config.swarselsystems.server.netConfigName}.hosts.${config.node.name}.cidrv4}" "${globals.networks.${config.swarselsystems.server.netConfigName}.hosts.${config.node.name}.cidrv6}" diff --git a/modules/nixos/optional/systemd-networkd-vlan.nix b/modules/nixos/optional/systemd-networkd-vlan.nix new file mode 100644 index 0000000..2a3470e --- /dev/null +++ b/modules/nixos/optional/systemd-networkd-vlan.nix @@ -0,0 +1,116 @@ +{ lib, config, globals, ... }: +{ + + systemd.network = { + wait-online.anyInterface = true; + netdevs = { + "10-veth" = { + netdevConfig = { + Kind = "veth"; + Name = "veth-br"; + }; + peerConfig = { + Name = "veth-int"; + }; + }; + "20-br" = { + netdevConfig = { + Kind = "bridge"; + Name = "br"; + }; + }; + } // lib.flip lib.concatMapAttrs globals.networks.home-lan.vlans ( + vlanName: vlanCfg: { + "30-vlan-${vlanName}" = { + netdevConfig = { + Kind = "vlan"; + Name = "vlan-${vlanName}"; + }; + vlanConfig.Id = vlanCfg.id; + }; + "40-me-${vlanName}" = { + netdevConfig = { + Name = "me-${vlanName}"; + Kind = "macvlan"; + }; + extraConfig = '' + [MACVLAN] + Mode=bridge + ''; + }; + } + ); + networks = { + "40-br" = { + matchConfig.Name = "br"; + bridgeConfig = { }; + linkConfig = { + ActivationPolicy = "always-up"; + RequiredForOnline = "no"; + }; + networkConfig = { + ConfigureWithoutCarrier = true; + LinkLocalAddressing = "no"; + }; + }; + "15-veth-br" = { + matchConfig.Name = "veth-br"; + + linkConfig = { + RequiredForOnline = "no"; + }; + + networkConfig = { + Bridge = "br"; + }; + }; + "15-veth-int" = { + matchConfig.Name = "veth-int"; + + linkConfig = { + ActivationPolicy = "always-up"; + RequiredForOnline = "no"; + }; + + networkConfig = { + ConfigureWithoutCarrier = true; + LinkLocalAddressing = "no"; + }; + + vlan = map (name: "vlan-${name}") (builtins.attrNames globals.networks.home-lan.vlans); + }; + "90-macvtap-ignore" = { + matchConfig.Kind = "macvtap"; + linkConfig.ActivationPolicy = "manual"; + linkConfig.Unmanaged = "yes"; + }; + } // lib.flip lib.concatMapAttrs globals.networks.home-lan.vlans ( + vlanName: vlanCfg: { + "30-vlan-${vlanName}" = { + matchConfig.Name = "vlan-${vlanName}"; + networkConfig.LinkLocalAddressing = "no"; + networkConfig.MACVLAN = "me-${vlanName}"; + linkConfig.RequiredForOnline = "no"; + }; + "40-me-${vlanName}" = { + address = [ + vlanCfg.hosts.${config.node.name}.cidrv4 + vlanCfg.hosts.${config.node.name}.cidrv6 + ]; + matchConfig.Name = "me-${vlanName}"; + networkConfig = { + IPv4Forwarding = "yes"; + IPv6PrivacyExtensions = "yes"; + IPv6SendRA = true; + IPv6AcceptRA = false; + }; + ipv6Prefixes = [ + { Prefix = vlanCfg.cidrv6; } + ]; + linkConfig.RequiredForOnline = "routable"; + }; + } + ); + }; + +} diff --git a/modules/nixos/server/adguardhome.nix b/modules/nixos/server/adguardhome.nix deleted file mode 100644 index f5b6262..0000000 --- a/modules/nixos/server/adguardhome.nix +++ /dev/null @@ -1,138 +0,0 @@ -{ self, inputs, lib, config, globals, dns, confLib, ... }: -let - inherit (confLib.gen { name = "adguardhome"; port = 3000; }) serviceName servicePort serviceAddress serviceDomain proxyAddress4 proxyAddress6; - inherit (confLib.static) isHome isProxied homeProxy homeProxyIf webProxy webProxyIf homeWebProxy dnsServer homeDnsServer homeServiceAddress nginxAccessRules; - - homeServices = lib.attrNames (lib.filterAttrs (_: serviceCfg: serviceCfg.isHome) globals.services); - homeDomains = map (name: globals.services.${name}.domain) homeServices; -in -{ - options = { - swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; - }; - config = lib.mkIf config.swarselmodules.server.${serviceName} { - - - globals = { - networks = { - ${webProxyIf}.hosts = lib.mkIf isProxied { - ${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ]; - }; - ${homeProxyIf}.hosts = lib.mkIf isHome { - ${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ]; - }; - }; - services.${serviceName} = { - domain = serviceDomain; - inherit proxyAddress4 proxyAddress6 isHome; - }; - }; - - networking.firewall = { - allowedTCPPorts = [ 53 ]; - allowedUDPPorts = [ 53 ]; - }; - - services.adguardhome = { - enable = true; - mutableSettings = false; - host = "0.0.0.0"; - port = servicePort; - settings = { - dns = { - bind_hosts = [ - globals.networks.home-lan.vlans.services.hosts.${homeDnsServer}.ipv4 - globals.networks.home-lan.vlans.services.hosts.${homeDnsServer}.ipv6 - ]; - ratelimit = 300; - upstream_dns = [ - "https://dns.cloudflare.com/dns-query" - "https://dns.google/dns-query" - "https://doh.mullvad.net/dns-query" - ]; - bootstrap_dns = [ - "1.1.1.1" - "2606:4700:4700::1111" - "8.8.8.8" - "2001:4860:4860::8844" - ]; - dhcp.enabled = false; - }; - filtering.rewrites = [ - ] - # Use the local mirror-proxy for some services (not necessary, just for speed) - ++ - map - (domain: { - inherit domain; - # FIXME: change to homeWebProxy once that is setup - answer = globals.networks.home-lan.vlans.services.hosts.${homeWebProxy}.ipv4; - # answer = globals.hosts.${webProxy}.wanAddress4; - }) - homeDomains; - filters = [ - { - name = "AdGuard DNS filter"; - url = "https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt"; - enabled = true; - } - { - name = "AdAway Default Blocklist"; - url = "https://adaway.org/hosts.txt"; - enabled = true; - } - { - name = "OISD (Big)"; - url = "https://big.oisd.nl"; - enabled = true; - } - ]; - }; - }; - - environment.persistence."/persist".directories = lib.mkIf config.swarselsystems.isImpermanence [ - { - directory = "/var/lib/private/AdGuardHome"; - mode = "0700"; - } - ]; - - nodes = - let - genNginx = toAddress: extraConfig: { - upstreams = { - ${serviceName} = { - servers = { - "${toAddress}:${builtins.toString servicePort}" = { }; - }; - }; - }; - virtualHosts = { - "${serviceDomain}" = { - useACMEHost = globals.domains.main; - forceSSL = true; - acmeRoot = null; - oauth2 = { - enable = true; - allowedGroups = [ "adguardhome_access" ]; - }; - locations = { - "/" = { - proxyPass = "http://${serviceName}"; - proxyWebsockets = true; - }; - }; - extraConfig = lib.mkIf (extraConfig != "") extraConfig; - }; - }; - }; - in - { - ${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = { - "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6; - }; - ${webProxy}.services.nginx = genNginx serviceAddress ""; - ${homeWebProxy}.services.nginx = genNginx homeServiceAddress nginxAccessRules; - }; - }; -} diff --git a/modules/nixos/server/attic.nix b/modules/nixos/server/attic.nix index 3aeb11e..e278ed6 100644 --- a/modules/nixos/server/attic.nix +++ b/modules/nixos/server/attic.nix @@ -14,12 +14,6 @@ in "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6; }; - topology.self.services.${serviceName} = { - name = lib.swarselsystems.toCapitalized serviceName; - info = "https://${serviceDomain}"; - # attic does not have a logo - }; - globals = { networks = { ${webProxyIf}.hosts = lib.mkIf isProxied { diff --git a/modules/nixos/server/disk-encrypt.nix b/modules/nixos/server/disk-encrypt.nix index 943077c..9c0da25 100644 --- a/modules/nixos/server/disk-encrypt.nix +++ b/modules/nixos/server/disk-encrypt.nix @@ -4,9 +4,6 @@ let subnetMask = globals.networks.${config.swarselsystems.server.netConfigName}.subnetMask4; gatewayIp = globals.hosts.${config.node.name}.defaultGateway4; - inherit (globals.general) routerServer; - isRouter = config.node.name == routerServer; - hostKeyPathBase = "/etc/secrets/initrd/ssh_host_ed25519_key"; hostKeyPath = if config.swarselsystems.isImpermanence then @@ -45,7 +42,7 @@ in }; boot = lib.mkIf (!config.swarselsystems.isClient) { - kernelParams = lib.mkIf (!config.swarselsystems.isCloud && ((config.swarselsystems.localVLANs == [ ]) || isRouter)) [ + kernelParams = lib.mkIf (!config.swarselsystems.isCloud) [ "ip=${localIp}::${gatewayIp}:${subnetMask}:${config.networking.hostName}::none" ]; initrd = { diff --git a/modules/nixos/server/dns-home.nix b/modules/nixos/server/dns-home.nix deleted file mode 100644 index abb3f5a..0000000 --- a/modules/nixos/server/dns-home.nix +++ /dev/null @@ -1,16 +0,0 @@ -{ lib, config, globals, confLib, ... }: -let - inherit (confLib.gen { name = "dns-home"; }) serviceName homeProxy; -in -{ - options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; - config = lib.mkIf (config.swarselmodules.server.${serviceName}) { - - networking.hosts = { - ${globals.networks.home-lan.vlans.services.hosts.${homeProxy}.ipv4} = [ "server.${homeProxy}.${globals.domains.main}" ]; - ${globals.networks.home-lan.vlans.services.hosts.${homeProxy}.ipv6} = [ "server.${homeProxy}.${globals.domains.main}" ]; - }; - - }; - -} diff --git a/modules/nixos/server/firezone.nix b/modules/nixos/server/firezone.nix index 26addfc..eb0f546 100644 --- a/modules/nixos/server/firezone.nix +++ b/modules/nixos/server/firezone.nix @@ -1,4 +1,4 @@ -{ self, lib, pkgs, config, globals, confLib, dns, nodes, ... }: +{ lib, pkgs, config, globals, confLib, dns, nodes, ... }: let inherit (confLib.gen { name = "firezone"; dir = "/var/lib/private/firezone"; }) serviceName serviceDir serviceAddress serviceDomain proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy homeProxyIf webProxyIf idmServer dnsServer; inherit (config.swarselsystems) sopsFile; @@ -60,12 +60,6 @@ in }; }; - topology.self.services.${serviceName} = { - name = lib.swarselsystems.toCapitalized serviceName; - info = "https://${serviceDomain}"; - icon = "${self}/files/topology-images/${serviceName}.png"; - }; - sops = { secrets = { kanidm-firezone-client = { inherit sopsFile; mode = "0400"; }; @@ -320,17 +314,12 @@ in }; services.firezone.gateway = { enable = true; - # logLevel = "trace"; + logLevel = "trace"; inherit (nodeCfg.node) name; apiUrl = "wss://${globals.services.firezone.domain}/api/"; tokenFile = nodeCfg.sops.secrets.firezone-gateway-token.path; package = nodePkgs.stable25_05.firezone-gateway; # newer versions of firezone-gateway are not compatible with server package }; - - topology.self.services."${serviceName}-gateway" = { - name = lib.swarselsystems.toCapitalized "${serviceName} Gateway"; - icon = "${self}/files/topology-images/${serviceName}.png"; - }; }; ${idmServer} = let diff --git a/modules/nixos/server/garage.nix b/modules/nixos/server/garage.nix index de46446..d180487 100644 --- a/modules/nixos/server/garage.nix +++ b/modules/nixos/server/garage.nix @@ -1,5 +1,5 @@ # inspired by https://github.com/atropos112/nixos/blob/7fef652006a1c939f4caf9c8a0cb0892d9cdfe21/modules/garage.nix -{ self, lib, pkgs, config, globals, dns, confLib, ... }: +{ lib, pkgs, config, globals, dns, confLib, ... }: let inherit (confLib.gen { name = "garage"; @@ -81,12 +81,6 @@ in "*.${subDomain}-web" = dns.lib.combinators.host proxyAddress4 proxyAddress6; }; - topology.self.services.${serviceName} = { - name = lib.swarselsystems.toCapitalized serviceName; - info = "https://${serviceDomain}"; - icon = "${self}/files/topology-images/${serviceName}.png"; - }; - sops = { secrets.garage-admin-token = { inherit sopsFile; }; secrets.garage-rpc-secret = { inherit sopsFile; }; diff --git a/modules/nixos/server/homebox.nix b/modules/nixos/server/homebox.nix index 05fd201..5dba937 100644 --- a/modules/nixos/server/homebox.nix +++ b/modules/nixos/server/homebox.nix @@ -1,4 +1,4 @@ -{ self, lib, pkgs, config, globals, dns, confLib, ... }: +{ lib, pkgs, config, globals, dns, confLib, ... }: let inherit (confLib.gen { name = "homebox"; port = 7745; }) servicePort serviceName serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf; in @@ -10,11 +10,7 @@ in "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6; }; - topology.self.services.${serviceName} = { - name = "Homebox"; - info = "https://${serviceDomain}"; - icon = "${self}/files/topology-images/${serviceName}.png"; - }; + topology.self.services.${serviceName}.info = "https://${serviceDomain}"; globals = { networks = { diff --git a/modules/nixos/server/hydra.nix b/modules/nixos/server/hydra.nix index 9798ff8..9227117 100644 --- a/modules/nixos/server/hydra.nix +++ b/modules/nixos/server/hydra.nix @@ -13,8 +13,6 @@ in "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6; }; - topology.self.services.${serviceName}.info = "https://${serviceDomain}"; - globals = { networks = { ${webProxyIf}.hosts = lib.mkIf isProxied { diff --git a/modules/nixos/server/kanidm.nix b/modules/nixos/server/kanidm.nix index da583f7..339da48 100644 --- a/modules/nixos/server/kanidm.nix +++ b/modules/nixos/server/kanidm.nix @@ -228,7 +228,6 @@ in "radicale.access" = { }; "slink.access" = { }; "opkssh.access" = { }; - "adguardhome.access" = { }; }; inherit (config.repo.secrets.local) persons; @@ -371,11 +370,6 @@ in "email" "profile" ]; - "adguardhome.access" = [ - "openid" - "email" - "profile" - ]; }; preferShortUsername = true; claimMaps.groups = { @@ -386,7 +380,6 @@ in "firefly.access" = [ "firefly_access" ]; "radicale.access" = [ "radicale_access" ]; "slink.access" = [ "slink_access" ]; - "adguardhome.access" = [ "adguardhome_access" ]; }; }; }; diff --git a/modules/nixos/server/kavita.nix b/modules/nixos/server/kavita.nix index 8a44cdc..717266d 100644 --- a/modules/nixos/server/kavita.nix +++ b/modules/nixos/server/kavita.nix @@ -62,6 +62,7 @@ in virtualHosts = { "${serviceDomain}" = { useACMEHost = globals.domains.main; + forceSSL = true; acmeRoot = null; locations = { diff --git a/modules/nixos/server/kea.nix b/modules/nixos/server/kea.nix index b9686f6..01074fa 100644 --- a/modules/nixos/server/kea.nix +++ b/modules/nixos/server/kea.nix @@ -1,75 +1,6 @@ -{ self, lib, config, globals, confLib, ... }: +{ lib, config, globals, confLib, ... }: let - inherit (confLib.gen { name = "kea"; dir = "/var/lib/private/kea"; }) serviceName serviceDir homeDnsServer; - dhcpX = intX: - let - x = builtins.toString intX; - in - { - enable = true; - settings = { - reservations-out-of-pool = true; - lease-database = { - name = "/var/lib/kea/dhcp${x}.leases"; - persist = true; - type = "memfile"; - }; - valid-lifetime = 86400; - renew-timer = 3600; - interfaces-config = { - interfaces = map (name: "me-${name}") (builtins.attrNames globals.networks.home-lan.vlans); - service-sockets-max-retries = -1; - }; - "subnet${x}" = lib.flip lib.mapAttrsToList globals.networks.home-lan.vlans ( - vlanName: vlanCfg: { - inherit (vlanCfg) id; - interface = "me-${vlanName}"; - subnet = vlanCfg."cidrv${x}"; - rapid-commit = lib.mkIf (intX == 6) true; - pools = [ - { - pool = "${lib.net.cidr.host 20 vlanCfg."cidrv${x}"} - ${lib.net.cidr.host (-6) vlanCfg."cidrv${x}"}"; - } - ]; - pd-pools = lib.mkIf (intX == 6) [ - { - prefix = builtins.replaceStrings [ "::" ] [ ":0:0:100::" ] (lib.head (lib.splitString "/" vlanCfg.cidrv6)); - prefix-len = 56; - delegated-len = 64; - } - ]; - option-data = - lib.optional (intX == 4) - { - name = "routers"; - data = vlanCfg.hosts.hintbooth."ipv${x}"; - } - # Advertise DNS server for VLANS that have internet access - ++ - lib.optional - (lib.elem vlanName globals.general.internetVLANs) - { - name = if (intX == 4) then "domain-name-servers" else "dns-servers"; - data = globals.networks.home-lan.vlans.services.hosts.${homeDnsServer}."ipv${x}"; - }; - reservations = lib.concatLists ( - lib.forEach (builtins.attrValues vlanCfg.hosts) ( - hostCfg: - lib.optional (hostCfg.mac != null) { - hw-address = lib.mkIf (intX == 4) hostCfg.mac; - duid = lib.mkIf (intX == 6) "00:03:00:01:${hostCfg.mac}"; # 00:03 = duid type 3; 00:01 = ethernet - ip-address = lib.mkIf (intX == 4) hostCfg."ipv${x}"; - ip-addresses = lib.mkIf (intX == 6) [ hostCfg."ipv${x}" ]; - prefixes = lib.mkIf (intX == 6) [ - "${builtins.replaceStrings ["::"] [":0:0:${builtins.toString (256 + hostCfg.id)}::"] (lib.head (lib.splitString "/" vlanCfg.cidrv6))}/64" - ]; - } - ) - ); - } - ); - }; - }; + inherit (confLib.gen { name = "kea"; dir = "/var/lib/private/kea"; }) serviceName serviceDir; in { options = { @@ -81,18 +12,65 @@ in { directory = serviceDir; mode = "0700"; } ]; - topology = { - extractors.kea.enable = false; - self.services.${serviceName} = { - name = lib.swarselsystems.toCapitalized serviceName; - icon = "${self}/files/topology-images/${serviceName}.png"; + services.kea.dhcp4 = { + enable = true; + settings = { + lease-database = { + name = "/var/lib/kea/dhcp4.leases"; + persist = true; + type = "memfile"; + }; + valid-lifetime = 86400; + renew-timer = 3600; + interfaces-config = { + # XXX: BUG: why does this bind other macvtaps? + interfaces = map (name: "me-${name}") (builtins.attrNames globals.networks.home-lan.vlans); + service-sockets-max-retries = -1; + }; + subnet4 = lib.flip lib.mapAttrsToList globals.networks.home-lan.vlans ( + vlanName: vlanCfg: { + inherit (vlanCfg) id; + interface = "me-${vlanName}"; + subnet = vlanCfg.cidrv4; + pools = [ + { + pool = "${lib.net.cidr.host 20 vlanCfg.cidrv4} - ${lib.net.cidr.host (-6) vlanCfg.cidrv4}"; + } + ]; + option-data = + [ + { + name = "routers"; + data = vlanCfg.hosts.hintbooth.ipv4; # FIXME: how to advertise v6 address also? + } + ]; + # Advertise DNS server for VLANS that have internet access + # ++ + # lib.optional + # (lib.elem vlanName [ + # "services" + # "home" + # "devices" + # "guests" + # ]) + # { + # name = "domain-name-servers"; + # data = globals.networks.home-lan.vlans.services.hosts.hintbooth-adguardhome.ipv4; + # }; + reservations = lib.concatLists ( + lib.forEach (builtins.attrValues vlanCfg.hosts) ( + hostCfg: + lib.optional (hostCfg.mac != null) { + hw-address = hostCfg.mac; + ip-address = hostCfg.ipv4; + } + ) + ); + } + ); }; }; - services.kea = { - dhcp4 = dhcpX 4; - dhcp6 = dhcpX 6; - }; }; } diff --git a/modules/nixos/server/koillection.nix b/modules/nixos/server/koillection.nix index 0cef41b..951812e 100644 --- a/modules/nixos/server/koillection.nix +++ b/modules/nixos/server/koillection.nix @@ -13,10 +13,6 @@ in options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; config = lib.mkIf config.swarselmodules.server.${serviceName} { - swarselmodules.server = { - podman = true; - postgresql = true; - }; nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = { "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6; diff --git a/modules/nixos/server/mailserver.nix b/modules/nixos/server/mailserver.nix index 24df0c8..8d08b9f 100644 --- a/modules/nixos/server/mailserver.nix +++ b/modules/nixos/server/mailserver.nix @@ -1,4 +1,4 @@ -{ self, lib, config, globals, dns, confLib, ... }: +{ lib, config, globals, dns, confLib, ... }: let inherit (config.swarselsystems) sopsFile; inherit (confLib.gen { name = "mailserver"; dir = "/var/lib/dovecot"; user = "virtualMail"; group = "virtualMail"; port = 443; }) serviceName serviceDir servicePort serviceUser serviceGroup serviceAddress serviceDomain proxyAddress4 proxyAddress6 isHome webProxy dnsServer; @@ -32,16 +32,6 @@ in }; }; - topology.self.services = lib.listToAttrs (map - (service: - lib.nameValuePair "${service}" { - name = lib.swarselsystems.toCapitalized service; - info = lib.mkIf (service == "postfix" || service == "roundcube") (if service == "postfix" then "https://${serviceDomain}" else "https://${roundcubeDomain}"); - icon = "${self}/files/topology-images/${service}.png"; - } - ) - [ "postfix" "dovecot" "rspamd" "clamav" "roundcube" ]); - sops.secrets = { user1-hashed-pw = { inherit sopsFile; owner = serviceUser; }; user2-hashed-pw = { inherit sopsFile; owner = serviceUser; }; diff --git a/modules/nixos/server/minecraft/default.nix b/modules/nixos/server/minecraft/default.nix index d54e031..d333d0a 100644 --- a/modules/nixos/server/minecraft/default.nix +++ b/modules/nixos/server/minecraft/default.nix @@ -1,4 +1,4 @@ -{ self, lib, config, pkgs, globals, dns, confLib, ... }: +{ lib, config, pkgs, globals, dns, confLib, ... }: let inherit (confLib.gen { name = "minecraft"; port = 25565; dir = "/opt/minecraft"; proxy = config.node.name; }) serviceName servicePort serviceDir serviceDomain proxyAddress4 proxyAddress6 isHome dnsServer; inherit (config.swarselsystems) mainUser; @@ -12,11 +12,7 @@ in "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6; }; - topology.self.services.${serviceName} = { - name = "Minecraft"; - info = "https://${serviceDomain}"; - icon = "${self}/files/topology-images/${serviceName}.png"; - }; + topology.self.services.${serviceName}.info = "https://${serviceDomain}"; globals.services.${serviceName} = { domain = serviceDomain; diff --git a/modules/nixos/server/navidrome.nix b/modules/nixos/server/navidrome.nix index d825653..9bf5fc8 100644 --- a/modules/nixos/server/navidrome.nix +++ b/modules/nixos/server/navidrome.nix @@ -16,8 +16,6 @@ in mpv ]; - topology.self.services.${serviceName}.info = "https://${serviceDomain}"; - users = { groups = { ${serviceGroup} = { diff --git a/modules/nixos/server/network.nix b/modules/nixos/server/network.nix index 064a509..9172d54 100644 --- a/modules/nixos/server/network.nix +++ b/modules/nixos/server/network.nix @@ -2,6 +2,7 @@ let netConfig = config.repo.secrets.local.networking; netPrefix = "${if config.swarselsystems.isCloud then config.node.name else "home"}"; + # netName = "${netPrefix}-${config.swarselsystems.server.localNetwork}"; in { options = { @@ -27,6 +28,11 @@ in swarselsystems.server.localNetwork = netConfig.localNetwork or ""; + # globals.networks.${netName}.hosts.${config.node.name} = { + # inherit (netConfig.networks.${netConfig.localNetwork}) id; + # mac = netConfig.networks.${netConfig.localNetwork}.mac or null; + # }; + globals.networks = lib.mapAttrs' (netName: _: lib.nameValuePair "${netPrefix}-${netName}" { @@ -39,8 +45,7 @@ in netConfig.networks; globals.hosts.${config.node.name} = { - defaultGateway4 = netConfig.defaultGateway4 or null; - defaultGateway6 = netConfig.defaultGateway6 or null; + inherit (config.repo.secrets.local.networking) defaultGateway4; wanAddress4 = netConfig.wanAddress4 or null; wanAddress6 = netConfig.wanAddress6 or null; isHome = if (netPrefix == "home") then true else false; diff --git a/modules/nixos/server/nftables.nix b/modules/nixos/server/nftables.nix index 6ded12c..b31407f 100644 --- a/modules/nixos/server/nftables.nix +++ b/modules/nixos/server/nftables.nix @@ -40,7 +40,6 @@ in nnf-drop.enable = true; nnf-loopback.enable = true; nnf-ssh.enable = true; - nnf-dhcpv6.enable = true; }; rules.untrusted-to-local = { diff --git a/modules/nixos/server/nginx.nix b/modules/nixos/server/nginx.nix index 4f57d92..604f509 100644 --- a/modules/nixos/server/nginx.nix +++ b/modules/nixos/server/nginx.nix @@ -67,7 +67,7 @@ in }; }; config = { - extraConfig = lib.mkIf topmod.config.defaultStapling (lib.mkBefore '' + extraConfig = lib.mkIf topmod.config.defaultStapling (lib.mkAfter '' ssl_stapling on; ssl_stapling_verify on; resolver 1.1.1.1 8.8.8.8 valid=300s; diff --git a/modules/nixos/server/nsd/default.nix b/modules/nixos/server/nsd/default.nix index 84efeca..6e79fad 100644 --- a/modules/nixos/server/nsd/default.nix +++ b/modules/nixos/server/nsd/default.nix @@ -1,4 +1,4 @@ -{ self, lib, config, globals, dns, confLib, ... }: +{ lib, config, globals, dns, confLib, ... }: let inherit (confLib.gen { name = "nsd"; port = 53; }) serviceName servicePort proxyAddress4 proxyAddress6; inherit (config.swarselsystems) sopsFile; @@ -34,11 +34,6 @@ in }; }; - topology.self.services.${serviceName} = { - name = lib.toUpper serviceName; - icon = "${self}/files/topology-images/${serviceName}.png"; - }; - services.nsd = { enable = true; keys = { diff --git a/modules/nixos/server/nsd/site1.nix b/modules/nixos/server/nsd/site1.nix index 8c155c7..901774c 100644 --- a/modules/nixos/server/nsd/site1.nix +++ b/modules/nixos/server/nsd/site1.nix @@ -3,7 +3,7 @@ with dns.lib.combinators; { SOA = { nameServer = "soa"; adminEmail = "admin@${globals.domains.main}"; # this option is not parsed as domain (we cannot just write "admin") - serial = 2026010201; # update this on changes for secondary dns + serial = 2025122401; # update this on changes for secondary dns }; useOrigin = false; diff --git a/modules/nixos/server/oauth2-proxy.nix b/modules/nixos/server/oauth2-proxy.nix index 83e06b3..2d85ba0 100644 --- a/modules/nixos/server/oauth2-proxy.nix +++ b/modules/nixos/server/oauth2-proxy.nix @@ -1,7 +1,6 @@ { lib, config, globals, dns, confLib, ... }: let - inherit (confLib.gen { name = "oauth2-proxy"; port = 3004; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress proxyAddress4 proxyAddress6; - inherit (confLib.static) isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf homeWebProxy oauthServer nginxAccessRules; + inherit (confLib.gen { name = "oauth2-proxy"; port = 3004; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf; kanidmDomain = globals.services.kanidm.domain; mainDomain = globals.domains.main; @@ -120,6 +119,10 @@ in }; config = lib.mkIf config.swarselmodules.server.${serviceName} { + nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = { + "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6; + }; + sops = { secrets = { "oauth2-cookie-secret" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; }; @@ -205,41 +208,31 @@ in }; }; - nodes = - let - genNginx = toAddress: extraConfig: { - upstreams = { - ${serviceName} = { - servers = { - "${toAddress}:${builtins.toString servicePort}" = { }; - }; - }; - }; - virtualHosts = { - "${serviceDomain}" = { - useACMEHost = globals.domains.main; - - forceSSL = true; - acmeRoot = null; - locations = { - "/" = { - proxyPass = "http://${serviceName}"; - }; - }; - extraConfig = '' - proxy_set_header X-Scheme $scheme; - proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri; - '' + lib.optionalString (extraConfig != "") extraConfig; - }; + nodes.${webProxy}.services.nginx = { + upstreams = { + ${serviceName} = { + servers = { + "${serviceAddress}:${builtins.toString servicePort}" = { }; }; }; - in - { - ${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = { - "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6; - }; - ${webProxy}.services.nginx = genNginx serviceAddress ""; - ${homeWebProxy}.services.nginx = genNginx globals.hosts.${oauthServer}.wanAddress4 nginxAccessRules; }; + virtualHosts = { + "${serviceDomain}" = { + useACMEHost = globals.domains.main; + + forceSSL = true; + acmeRoot = null; + locations = { + "/" = { + proxyPass = "http://${serviceName}"; + }; + }; + extraConfig = '' + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri; + ''; + }; + }; + }; }; } diff --git a/modules/nixos/server/opkssh.nix b/modules/nixos/server/opkssh.nix index 178e3d7..1cc01bc 100644 --- a/modules/nixos/server/opkssh.nix +++ b/modules/nixos/server/opkssh.nix @@ -11,7 +11,6 @@ in options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; config = lib.mkIf config.swarselmodules.server.${serviceName} { - services.${serviceName} = { enable = true; user = serviceUser; diff --git a/modules/nixos/server/packages.nix b/modules/nixos/server/packages.nix index 6b954eb..af6702a 100644 --- a/modules/nixos/server/packages.nix +++ b/modules/nixos/server/packages.nix @@ -13,8 +13,6 @@ sops tmux busybox - ndisc6 - tcpdump swarsel-deploy ] ++ lib.optionals withHomeManager [ swarsel-gens diff --git a/modules/nixos/server/podman.nix b/modules/nixos/server/podman.nix deleted file mode 100644 index 80bdc22..0000000 --- a/modules/nixos/server/podman.nix +++ /dev/null @@ -1,38 +0,0 @@ -{ config, lib, ... }: -let - serviceName = "podman"; -in -{ - options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; - config = lib.mkIf config.swarselmodules.server.${serviceName} { - - virtualisation = { - podman.enable = true; - oci-containers.backend = "podman"; - }; - - networking.nftables.firewall = lib.mkIf config.networking.nftables.enable { - - zones.podman = { - interfaces = [ "podman0" ]; - }; - - rules = { - podman-to-postgres = lib.mkIf config.services.postgresql.enable { - from = [ "podman" ]; - to = [ "local" ]; - before = [ "drop" ]; - allowedTCPPorts = [ config.services.postgresql.settings.port ]; - }; - - local-to-podman = { - from = [ "local" "wgProxy" "wgHme" ]; - to = [ "podman" ]; - before = [ "drop" ]; - verdict = "accept"; - }; - }; - }; - - }; -} diff --git a/modules/nixos/server/router.nix b/modules/nixos/server/router.nix index 6dc482f..51311be 100644 --- a/modules/nixos/server/router.nix +++ b/modules/nixos/server/router.nix @@ -1,15 +1,6 @@ -{ lib, config, globals, confLib, ... }: +{ lib, config, globals, ... }: let serviceName = "router"; - bridgeVLANs = lib.mapAttrsToList - (_: vlan: { - VLAN = vlan.id; - }) - globals.networks.home-lan.vlans; - selectVLANs = vlans: map (vlan: { VLAN = globals.networks.home-lan.vlans.${vlan}.id; }) vlans; - lan5VLANs = selectVLANs [ "home" "devices" "guests" ]; - lan4VLANs = selectVLANs [ "home" "services" ]; - inherit (confLib.gen { }) homeDnsServer; in { options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; @@ -17,27 +8,13 @@ in { services.avahi.reflector = true; - topology.self.interfaces = (lib.mapAttrs' - (vlanName: _: - lib.nameValuePair "vlan-${vlanName}" { - network = lib.mkForce vlanName; - } - ) - globals.networks.home-lan.vlans) // (lib.mapAttrs' - (vlanName: _: - lib.nameValuePair "me-${vlanName}" { - network = lib.mkForce vlanName; - } - ) - globals.networks.home-lan.vlans); - networking.nftables = { firewall = { zones = { untrusted.interfaces = [ "lan" ]; wgHome.interfaces = [ "wgHome" ]; - adguardhome.ipv4Addresses = [ globals.networks.home-lan.vlans.services.hosts.${homeDnsServer}.ipv4 ]; - adguardhome.ipv6Addresses = [ globals.networks.home-lan.vlans.services.hosts.${homeDnsServer}.ipv6 ]; + adguardhome.ipv4Addresses = [ globals.networks.home-lan.vlans.services.hosts.hintbooth-adguardhome.ipv4 ]; + adguardhome.ipv6Addresses = [ globals.networks.home-lan.vlans.services.hosts.hintbooth-adguardhome.ipv6 ]; } // lib.flip lib.concatMapAttrs globals.networks.home-lan.vlans ( vlanName: _: { @@ -47,7 +24,7 @@ in rules = { masquerade-internet = { - from = map (name: "vlan-${name}") (globals.general.internetVLANs); + from = map (name: "vlan-${name}") (builtins.attrNames globals.networks.home-lan.vlans); to = [ "untrusted" ]; # masquerade = true; NOTE: custom rule below for ip4 + ip6 late = true; # Only accept after any rejects have been processed @@ -56,7 +33,7 @@ in # Allow access to the AdGuardHome DNS server from any VLAN that has internet access access-adguardhome-dns = { - from = map (name: "vlan-${name}") (globals.general.internetVLANs); + from = map (name: "vlan-${name}") (builtins.attrNames globals.networks.home-lan.vlans); to = [ "adguardhome" ]; verdict = "accept"; }; @@ -76,7 +53,7 @@ in services-to-local = { from = [ "vlan-services" ]; to = [ "local" ]; - allowedUDPPorts = [ 52829 547 ]; + allowedUDPPorts = [ 52829 ]; }; # Forward traffic between wireguard participants @@ -94,7 +71,7 @@ in late = true; rules = lib.forEach - (map (name: "vlan-${name}") (globals.general.internetVLANs)) + (map (name: "vlan-${name}") (builtins.attrNames globals.networks.home-lan.vlans)) ( zone: lib.concatStringsSep " " [ @@ -116,68 +93,7 @@ in systemd.network = { wait-online.anyInterface = true; - - netdevs = { - "10-veth" = { - netdevConfig = { - Kind = "veth"; - Name = "veth-br"; - }; - peerConfig = { - Name = "veth-int"; - }; - }; - "20-br" = { - netdevConfig = { - Kind = "bridge"; - Name = "br"; - }; - bridgeConfig = { - VLANFiltering = true; - }; - }; - }; networks = { - "40-br" = { - matchConfig.Name = "br"; - bridgeConfig = { }; - linkConfig = { - ActivationPolicy = "always-up"; - RequiredForOnline = "no"; - }; - networkConfig = { - ConfigureWithoutCarrier = true; - LinkLocalAddressing = "no"; - }; - }; - "15-veth-br" = { - matchConfig.Name = "veth-br"; - - linkConfig = { - RequiredForOnline = "no"; - }; - - networkConfig = { - Bridge = "br"; - }; - inherit bridgeVLANs; - }; - "15-veth-int" = { - matchConfig.Name = "veth-int"; - - linkConfig = { - ActivationPolicy = "always-up"; - RequiredForOnline = "no"; - }; - - networkConfig = { - ConfigureWithoutCarrier = true; - LinkLocalAddressing = "no"; - }; - - vlan = map (name: "vlan-${name}") (builtins.attrNames globals.networks.home-lan.vlans); - }; - # br "30-lan1" = { matchConfig.MACAddress = config.repo.secrets.local.networking.networks.lan1.mac; linkConfig.RequiredForOnline = "enslaved"; @@ -185,9 +101,7 @@ in Bridge = "br"; ConfigureWithoutCarrier = true; }; - inherit bridgeVLANs; }; - # wifi "30-lan2" = { matchConfig.MACAddress = config.repo.secrets.local.networking.networks.lan2.mac; linkConfig.RequiredForOnline = "enslaved"; @@ -195,9 +109,7 @@ in Bridge = "br"; ConfigureWithoutCarrier = true; }; - inherit bridgeVLANs; }; - # summers "30-lan3" = { matchConfig.MACAddress = config.repo.secrets.local.networking.networks.lan3.mac; linkConfig.RequiredForOnline = "enslaved"; @@ -205,9 +117,7 @@ in Bridge = "br"; ConfigureWithoutCarrier = true; }; - inherit bridgeVLANs; }; - # winters "30-lan4" = { matchConfig.MACAddress = config.repo.secrets.local.networking.networks.lan4.mac; linkConfig.RequiredForOnline = "enslaved"; @@ -215,9 +125,7 @@ in Bridge = "br"; ConfigureWithoutCarrier = true; }; - bridgeVLANs = lan4VLANs; }; - # lr "30-lan5" = { matchConfig.MACAddress = config.repo.secrets.local.networking.networks.lan5.mac; linkConfig.RequiredForOnline = "enslaved"; @@ -225,37 +133,10 @@ in Bridge = "br"; ConfigureWithoutCarrier = true; }; - bridgeVLANs = lan5VLANs; }; - } // lib.flip lib.concatMapAttrs globals.networks.home-lan.vlans ( - vlanName: vlanCfg: { - "40-me-${vlanName}" = lib.mkForce { - address = [ - vlanCfg.hosts.${config.node.name}.cidrv4 - vlanCfg.hosts.${config.node.name}.cidrv6 - ]; - matchConfig.Name = "me-${vlanName}"; - networkConfig = { - IPv4Forwarding = "yes"; - IPv6PrivacyExtensions = "yes"; - IPv6SendRA = true; - IPv6AcceptRA = false; - }; - ipv6Prefixes = [ - { - Prefix = vlanCfg.cidrv6; - } - ]; - ipv6SendRAConfig = { - Managed = true; # set RA M flag -> DHCPv6 for addresses - OtherInformation = true; # optional, for โ€œother infoโ€ via DHCPv6 - }; - linkConfig.RequiredForOnline = "routable"; - }; - } - ); - + }; }; + }; } diff --git a/modules/nixos/server/shlink.nix b/modules/nixos/server/shlink.nix index 00853db..023b831 100644 --- a/modules/nixos/server/shlink.nix +++ b/modules/nixos/server/shlink.nix @@ -12,10 +12,6 @@ in }; config = lib.mkIf config.swarselmodules.server.${serviceName} { - swarselmodules.server = { - podman = true; - }; - nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = { "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6; }; diff --git a/modules/nixos/server/slink.nix b/modules/nixos/server/slink.nix index 8ca9509..8e71aae 100644 --- a/modules/nixos/server/slink.nix +++ b/modules/nixos/server/slink.nix @@ -10,10 +10,6 @@ in }; config = lib.mkIf config.swarselmodules.server.${serviceName} { - swarselmodules.server = { - podman = true; - }; - nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = { "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6; }; diff --git a/modules/nixos/server/wireguard.nix b/modules/nixos/server/wireguard.nix index dcfa71d..98d9fdf 100644 --- a/modules/nixos/server/wireguard.nix +++ b/modules/nixos/server/wireguard.nix @@ -95,14 +95,6 @@ in ) ); - topology.self.interfaces = lib.mapAttrs' - (wgName: _: - lib.nameValuePair "${wgName}" { - network = wgName; - } - ) - config.swarselsystems.server.wireguard.interfaces; - environment.systemPackages = with pkgs; [ wireguard-tools ]; diff --git a/modules/shared/config-lib.nix b/modules/shared/config-lib.nix index eac2370..1bc7e2a 100644 --- a/modules/shared/config-lib.nix +++ b/modules/shared/config-lib.nix @@ -1,27 +1,27 @@ { self, config, lib, globals, inputs, outputs, minimal, nixosConfig ? null, ... }: -let - domainDefault = service: config.repo.secrets.common.services.domains.${service}; - proxyDefault = config.swarselsystems.proxyHost; - - addressDefault = - if - config.swarselsystems.proxyHost != config.node.name - then - if - config.swarselsystems.server.wireguard.interfaces.wgProxy.isClient - then - globals.networks."${config.swarselsystems.server.wireguard.interfaces.wgProxy.serverNetConfigPrefix}-wgProxy".hosts.${config.node.name}.ipv4 - else - globals.networks.${config.swarselsystems.server.netConfigName}.hosts.${config.node.name}.ipv4 - else - "localhost"; -in { _module.args = { confLib = rec { + + addressDefault = + if + config.swarselsystems.proxyHost != config.node.name + then + if + config.swarselsystems.server.wireguard.interfaces.wgProxy.isClient + then + globals.networks."${config.swarselsystems.server.wireguard.interfaces.wgProxy.serverNetConfigPrefix}-wgProxy".hosts.${config.node.name}.ipv4 + else + globals.networks.${config.swarselsystems.server.netConfigName}.hosts.${config.node.name}.ipv4 + else + "localhost"; + + domainDefault = service: config.repo.secrets.common.services.domains.${service}; + proxyDefault = config.swarselsystems.proxyHost; + getConfig = if nixosConfig == null then config else nixosConfig; - gen = { name ? "n/a", user ? name, group ? name, dir ? null, port ? null, domain ? (domainDefault name), address ? addressDefault, proxy ? proxyDefault }: rec { + gen = { name, user ? name, group ? name, dir ? null, port ? null, domain ? (domainDefault name), address ? addressDefault, proxy ? proxyDefault }: rec { servicePort = port; serviceName = name; specificServiceName = "${name}-${config.node.name}"; @@ -36,28 +36,12 @@ in proxyAddress4 = globals.hosts.${proxy}.wanAddress4 or null; proxyAddress6 = globals.hosts.${proxy}.wanAddress6 or null; inherit (globals.hosts.${config.node.name}) isHome; - inherit (globals.general) homeProxy webProxy dnsServer homeDnsServer homeWebProxy idmServer; + inherit (globals.general) homeProxy webProxy dnsServer idmServer; webProxyIf = "${webProxy}-wgProxy"; homeProxyIf = "home-wgHome"; isProxied = config.node.name != webProxy; }; - static = rec { - inherit (globals.hosts.${config.node.name}) isHome; - inherit (globals.general) homeProxy webProxy dnsServer homeDnsServer homeWebProxy idmServer oauthServer; - webProxyIf = "${webProxy}-wgProxy"; - homeProxyIf = "home-wgHome"; - isProxied = config.node.name != webProxy; - nginxAccessRules = '' - allow ${globals.networks.home-lan.vlans.home.cidrv4}; - allow ${globals.networks.home-lan.vlans.home.cidrv6}; - allow ${globals.networks.home-lan.vlans.services.hosts.${homeProxy}.ipv4}; - allow ${globals.networks.home-lan.vlans.services.hosts.${homeProxy}.ipv6}; - deny all; - ''; - homeServiceAddress = lib.optionalString (config.swarselsystems.server.wireguard.interfaces ? wgHome) globals.networks."${config.swarselsystems.server.wireguard.interfaces.wgHome.serverNetConfigPrefix}-wgHome".hosts.${config.node.name}.ipv4; - }; - mkMicrovm = if config.swarselsystems.withMicroVMs then (guestName: { @@ -65,7 +49,7 @@ in backend = "microvm"; autostart = true; modules = [ - (config.node.configDir + /guests/${guestName}/default.nix) + (config.node.configDir + /guests/${guestName}.nix) { node.secretsDir = config.node.configDir + /secrets/${guestName}; node.configDir = config.node.configDir + /guests/${guestName}; @@ -78,7 +62,6 @@ in }; } "${self}/modules/nixos/optional/microvm-guest.nix" - "${self}/modules/nixos/optional/systemd-networkd-base.nix" ]; microvm = { system = config.node.arch; @@ -91,7 +74,6 @@ in inherit inputs outputs minimal; inherit (inputs) self; withHomeManager = false; - microVMParent = config.node.name; globals = outputs.globals.${config.node.arch}; }; }; diff --git a/modules/shared/options.nix b/modules/shared/options.nix index 28f2e2e..5d3f169 100644 --- a/modules/shared/options.nix +++ b/modules/shared/options.nix @@ -37,18 +37,6 @@ type = lib.types.str; default = ""; }; - # @ future me: dont put this under server prefix - # home-manager would then try to import all swarselsystems.server.* options - localVLANs = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ ]; - }; - # @ future me: dont put this under server prefix - # home-manager would then try to import all swarselsystems.server.* options - initrdVLAN = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - }; mainUser = lib.mkOption { type = lib.types.str; default = "swarsel"; diff --git a/nix/topology.nix b/nix/topology.nix index dc22d6f..72f92e8 100644 --- a/nix/topology.nix +++ b/nix/topology.nix @@ -4,250 +4,189 @@ inputs.nix-topology.flakeModule ]; - perSystem = { system, ... }: - let - inherit (self.outputs) lib; - in - { - topology.modules = [ - ({ config, ... }: - let - globals = self.outputs.globals.${system}; - inherit (config.lib.topology) - mkInternet - mkDevice - mkSwitch - mkRouter - mkConnection - ; - in - { - renderer = "elk"; + perSystem.topology.modules = [ + ({ config, ... }: + let + inherit (self.outputs) globals; + inherit (config.lib.topology) + mkInternet + mkDevice + mkSwitch + mkRouter + mkConnection + ; + in + { + renderer = "elk"; - networks = { - fritz-lan = { - name = "Fritz!Box LAN"; - inherit (globals.networks.home-lan) cidrv4 cidrv6; + networks = { + home-lan = { + name = "Home LAN"; + inherit (globals.networks.home-lan) cidrv4; + }; + fritz-wg = { + name = "Wireguard Tunnel for Fritzbox net access"; + inherit (globals.networks.twothreetunnel-wg) cidrv4; + }; + wg = { + name = "Wireguard Tunnel for proxy access"; + inherit (globals.networks.twothreetunnel-wg) cidrv4; + }; + }; + + nodes = { + internet = mkInternet { + connections = [ + (mkConnection "fritzbox" "dsl") + (mkConnection "moonside" "wan") + (mkConnection "belchsfactory" "wan") + (mkConnection "twothreetunnel" "wan") + (mkConnection "stoicclub" "wan") + (mkConnection "liliputsteps" "wan") + (mkConnection "eagleland" "wan") + (mkConnection "magicant" "wifi") + (mkConnection "toto" "bootstrapper") + (mkConnection "hotel" "demo host") + ]; + }; + + + fritzbox = mkRouter "FRITZ!Box" { + info = "FRITZ!Box 7682"; + image = "${self}/files/topology-images/hunsn.png"; + interfaceGroups = [ + [ + "eth1" + "eth2" + "eth3" + "eth-wan" + "wifi" + ] + [ "dsl" ] + ]; + + connections = { + eth1 = mkConnection "winters" "eth1"; + eth2 = mkConnection "switch-bedroom" "eth1"; + eth3 = mkConnection "switch-livingroom" "eth1"; + eth-wan = mkConnection "hintbooth" "eth6"; + wgPyramid = mkConnection "pyramid" "fritz-wg"; + wgMagicant = mkConnection "magicant" "fritz-wg"; + wifiPyramid = mkConnection "pyramid" "wifi"; + wifiMagicant = mkConnection "magicant" "wifi"; + wifiBakery = mkConnection "bakery" "wifi"; + wifiMachpizza = mkConnection "machpizza" "wifi"; + }; + interfaces = { + eth1 = { + addresses = [ globals.networks.home-lan.hosts.fritzbox.ipv4 ]; + network = "home-lan"; }; - services = { - name = "VLAN: Services"; - inherit (globals.networks.home-lan.vlans.services) cidrv4 cidrv6; + eth2 = { + addresses = [ globals.networks.home-lan.hosts.fritzbox.ipv4 ]; + network = "home-lan"; }; - home = { - name = "VLAN: Home"; - inherit (globals.networks.home-lan.vlans.home) cidrv4 cidrv6; + eth3 = { + addresses = [ globals.networks.home-lan.hosts.fritzbox.ipv4 ]; + network = "home-lan"; }; - devices = { - name = "VLAN: Devices"; - inherit (globals.networks.home-lan.vlans.devices) cidrv4 cidrv6; + eth-wan = { + addresses = [ globals.networks.home-lan.hosts.fritzbox.ipv4 ]; + network = "home-lan"; }; - guests = { - name = "VLAN: Guests"; - inherit (globals.networks.home-lan.vlans.guests) cidrv4 cidrv6; + wifi = { + addresses = [ globals.networks.home-lan.hosts.fritzbox.ipv4 ]; + virtual = true; + network = "home-lan"; }; fritz-wg = { - name = "WireGuard: Fritz!Box tunnel"; - inherit (globals.networks.fritz-wg) cidrv4 cidrv6; - }; - wgProxy = { - name = "WireGuard: Web proxy tunnel"; - inherit (globals.networks.twothreetunnel-wgProxy) cidrv4 cidrv6; - }; - wgHome = { - name = "WireGuard: Home proxy tunnel"; - inherit (globals.networks.home-wgHome) cidrv4 cidrv6; + addresses = [ globals.networks.fritz-wg.hosts.fritzbox.ipv4 ]; + network = "wg"; + virtual = true; + type = "wireguard"; }; }; + }; - nodes = { - internet = mkInternet { - connections = [ - (mkConnection "fritzbox" "dsl") - (mkConnection "magicant" "wifi") - (mkConnection "liliputsteps" "lan") - (mkConnection "treehouse" "eth1") - (mkConnection "toto" "bootstrapper") - (mkConnection "hotel" "demo host") - ]; - }; - - - fritzbox = mkRouter "FRITZ!Box" { - info = "FRITZ!Box 7682"; - image = "${self}/files/topology-images/Fritz!Box_7682.png"; - interfaceGroups = [ - [ - "eth1" - "eth2" - "eth3" - "eth-wan" - "wifi" - ] - [ "dsl" ] - ]; - - connections = { - eth1 = mkConnection "winters" "eth1"; - eth-wan = mkConnection "hintbooth" "lan"; - }; - interfaces = { - eth1 = { - addresses = [ globals.networks.home-lan.hosts.fritzbox.ipv4 ]; - network = "fritz-lan"; - }; - eth2 = { }; - eth3 = { }; - eth-wan = { - addresses = [ globals.networks.home-lan.hosts.fritzbox.ipv4 ]; - network = "fritz-lan"; - }; - wifi = { - addresses = [ globals.networks.home-lan.hosts.fritzbox.ipv4 ]; - virtual = true; - renderer.hidePhysicalConnections = true; - network = "fritz-lan"; - physicalConnections = [ - (mkConnection "pyramid" "wifi") - (mkConnection "bakery" "wifi") - (mkConnection "machpizza" "wifi") - ]; - }; - fritz-wg = { - addresses = [ globals.networks.fritz-wg.hosts.fritzbox.ipv4 ]; - network = "fritz-wg"; - virtual = true; - renderer.hidePhysicalConnections = true; - type = "wireguard"; - physicalConnections = [ - (mkConnection "pyramid" "fritz-wg") - (mkConnection "magicant" "fritz-wg") - ]; - }; - }; - }; - - switch-livingroom = mkSwitch "Switch Livingroom" { - info = "TL-SG108E"; - image = "${self}/files/topology-images/TL-SG108E.png"; - interfaceGroups = [ - # trunk - [ "eth1" ] - # devices - [ "eth2" ] - # home - [ "eth3" "eth8" ] - # guests - [ "eth4" "eth5" "eth6" "eth7" ] - ]; - interfaces = { - eth2 = { network = lib.mkForce "devices"; }; - eth3 = { network = lib.mkForce "home"; }; - eth7 = { network = lib.mkForce "guests"; }; - eth8 = { network = lib.mkForce "home"; }; - }; - connections = { - eth2 = mkConnection "nswitch" "eth1"; - eth3 = mkConnection "bakery" "eth1"; - eth7 = mkConnection "pc" "eth1"; - eth8 = mkConnection "pyramid" "eth1"; - }; - }; - - switch-bedroom = mkDevice "Switch Bedroom" { - info = "Cisco SG 200-08"; - image = "${self}/files/topology-images/Cisco_SG_200-08.png"; - interfaceGroups = [ - # trunk - [ "eth1" ] - # devices - [ "eth2" ] - # guests - [ "eth3" "eth4" "eth5" "eth6" "eth7" "eth8" ] - ]; - interfaces = { - eth2 = { network = lib.mkForce "devices"; }; - eth3 = { network = lib.mkForce "guests"; }; - }; - connections = { - eth2 = mkConnection "printer" "eth1"; - eth3 = mkConnection "machpizza" "eth1"; - }; - }; - - nswitch = mkDevice "Nintendo Switch" { - info = "Nintendo Switch"; - image = "${self}/files/topology-images/nintendo-switch.png"; - interfaces.eth1 = { }; - }; - - magicant = mkDevice "magicant" { - icon = "${self}/files/topology-images/phone.png"; - info = "Samsung Z Flip 6"; - image = "${self}/files/topology-images/zflip6.png"; - interfaces = { - wifi = { }; - fritz-wg.network = "fritz-wg"; - }; - }; - - machpizza = mkDevice "machpizza" { - info = "MacBook Pro 2016"; - icon = "devices.laptop"; - deviceIcon = "${self}/files/topology-images/mac.png"; - interfaces = { - eth1.network = "guests"; - wifi = { }; - }; - }; - - treehouse = mkDevice "treehouse" { - info = "NVIDIA DGX Spark"; - icon = "${self}/files/topology-images/home-manager.png"; - deviceIcon = "${self}/files/topology-images/dgxos.png"; - interfaces = { - eth1 = { }; - wifi = { }; - }; - services = { - ollama = { - name = "Ollama"; - icon = "${self}/files/topology-images/ollama.png"; - }; - openwebui = { - name = "Open WebUI"; - icon = "${self}/files/topology-images/openwebui.png"; - }; - comfyui = { - name = "Comfy UI"; - icon = "${self}/files/topology-images/comfyui.png"; - }; - }; - }; - - pc = mkDevice "Chaostheater" { - info = "ASUS Z97-A, i7-4790k, GTX970, 32GB RAM"; - icon = "${self}/files/topology-images/windows.png"; - deviceIcon = "${self}/files/topology-images/atlasos.png"; - services = { - sunshine = { - name = "Sunshine"; - icon = "${self}/files/topology-images/sunshine.png"; - }; - }; - interfaces.eth1.network = "guests"; - }; - - printer = mkDevice "Printer" { - info = "DELL C2665dnf"; - image = "${self}/files/topology-images/DELL-C2665dnf.png"; - interfaces.eth1 = { }; - }; - + switch-livingroom = mkSwitch "Switch Livingroom" { + info = "TL-SG108"; + image = "${self}/files/topology-images/TL-SG108.png"; + interfaceGroups = [ + [ + "eth1" + "eth2" + "eth3" + "eth4" + "eth5" + "eth6" + "eth7" + "eth8" + ] + ]; + connections = { + eth2 = mkConnection "nswitch" "eth1"; + eth7 = mkConnection "pc" "eth1"; + eth8 = mkConnection "pyramid" "eth1"; }; + }; - }) + switch-bedroom = mkSwitch "Switch Bedroom" { + info = "TL-SG1005D"; + image = "${self}/files/topology-images/TL-SG1005D.png"; + interfaceGroups = [ + [ + "eth1" + "eth2" + "eth3" + "eth4" + "eth5" + ] + ]; + connections.eth2 = mkConnection "printer" "eth1"; + connections.eth3 = mkConnection "machpizza" "eth1"; + }; + + nswitch = mkDevice "Nintendo Switch" { + info = "Nintendo Switch"; + image = "${self}/files/topology-images/nintendo-switch.png"; + interfaces.eth1 = { }; + }; + + magicant = mkDevice "magicant" { + icon = "${self}/files/topology-images/phone.png"; + info = "Samsung Z Flip 6"; + image = "${self}/files/topology-images/zflip6.png"; + interfaces = { + wifi = { }; + fritz-wg = { }; + }; + }; + + machpizza = mkDevice "machpizza" { + info = "MacBook Pro 2016"; + icon = "${self}/files/topology-images/mac.png"; + interfaces = { + eth1 = { }; + wifi = { }; + }; + }; + + pc = mkDevice "Windows Gaming Server" { + info = "i7-4790k, GTX970, 32GB RAM"; + image = "${self}/files/topology-images/pc.png"; + interfaces.eth1 = { }; + }; + + printer = mkDevice "Printer" { + info = "DELL C2665dnf"; + image = "${self}/files/topology-images/DELL-C2665dnf.png"; + interfaces.eth1 = { }; + }; + + }; + + }) - ]; - }; + ]; } diff --git a/profiles/nixos/microvm/default.nix b/profiles/nixos/microvm/default.nix index 689bbbf..b00d5a1 100644 --- a/profiles/nixos/microvm/default.nix +++ b/profiles/nixos/microvm/default.nix @@ -20,8 +20,6 @@ general = lib.mkDefault true; packages = lib.mkDefault true; ssh = lib.mkDefault true; - wireguard = lib.mkDefault true; - dns-home = lib.mkDefault true; }; }; }; diff --git a/secrets/public/wg/hintbooth-adguardhome.pub b/secrets/public/wg/hintbooth-adguardhome.pub deleted file mode 100644 index f917a4a..0000000 --- a/secrets/public/wg/hintbooth-adguardhome.pub +++ /dev/null @@ -1 +0,0 @@ -emVomIbxGS95tDiwPpUbsRTAur/TZ+BRy7+4737Sv1Q= diff --git a/secrets/public/wg/hintbooth-nginx.pub b/secrets/public/wg/hintbooth-nginx.pub deleted file mode 100644 index 4f23f14..0000000 --- a/secrets/public/wg/hintbooth-nginx.pub +++ /dev/null @@ -1 +0,0 @@ -G4NXSwhwU5a2K1q3oAwmnOtBlCj15J2aqh6zIJJtggE= diff --git a/secrets/repo/certs.yaml b/secrets/repo/certs.yaml index cec5da9..50999c1 100644 --- a/secrets/repo/certs.yaml +++ b/secrets/repo/certs.yaml @@ -8,161 +8,143 @@ sops: - recipient: age1s0vssf9fey2l456hucppzx2x58xep279nsdcglvkqm30sr9ht37s8rvpza enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFdDZiY1BsaHhLYy93L2Ju - TkJHRUdTU0VFKy9jd1p2ZmJrU092Z09yMTNvCnpzbXFIZ1VMVk1QVzN6YXFmckQ0 - U0hFam53Z3V5U2xYNjkwU1UxNmI4ZncKLS0tIGk1MC9EV2hnMFN6aFRtekt0enQy - RWxXVmhJU3NVbHdlS1Rsd05sSkZiY1UKaK5bSDPhQlVTryAYr/9mIgmXDzVp2KWF - M4FQURHk6kvSIVjHNfRyMX0IVtCFZMSmVpuPUP46J/5kzdN59Jn2Bw== - -----END AGE ENCRYPTED FILE----- - - recipient: age18cgqlely56hgmhscllkmafwpjdk6dwep6ej3vkk97dzemp8jtuksqrrjjl - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLRElrSnhrM0ZVQ043K1Nk - VTNlWDVDNW5veDNPM0RuOWZTZ3IwQ2pBdmpFCktEZFNvUTRrVVRBdFU5alhJSTE0 - RVlqRkl5MUEzZjhUVWwrWTFWMk8yWG8KLS0tIHJKZXJrNXZiRjNiZEh6VEhHWnZT - dlI3RTl2MW43YVdJMVlDaUoxSDV3YTAKBCjLqctIpPeTYsRxhj0/7DzR0q1cGe2d - w0B8DmH56XP7vq+nLh6+imWFLsbEOS0lRPHRRBEiimEkYljO5ZkoZg== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpZW1LTVFtaGVraTFDRVI2 + dkNRV0tpdUg1YmdiL2hMVUlodzFJM1hHUkJBClRHaGRMTDNlbVpDS1A5dzBpc2Yv + ancxU3lSRTJNMFBjeFNoSEF1Rys0YVUKLS0tIHVpb2g4bnN4NHJTdHJrSDdKVFZY + aGNOMDgvakoxcWJ3bEVyeFZOQU94UXcK/mjqz9Ys7ZEm2+9Y+mLrQVqoC5g5ag85 + Xp9Fo7gmsgc9lZwgxRPLzIBeWcaN17NIaMRDMxTz5cdDCRi5JP9FiQ== -----END AGE ENCRYPTED FILE----- - recipient: age1g7atkxdlt4ymeh7v7aa2yzr2hq2qkvzrc4r49ugttm3n582ymv9qrmpk8d enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3TEREZ0lVR2Q5aEN1S2sv - dVhURlhhWTJBdEdhbHlXZGVQa2ZwZkhFd2lnClM1QUJrMW1GU3FuVTFwUkZxR0xD - YS9kVFVRdGZKMVVRTk5sNm9nRVV1YkkKLS0tIExyKzlJUHhUdEVhSGJEUUs1YlQz - Yk5WMERLb1MyVTRvM3hkVVFNU3ZtajAKqH9sLSNTacfRj4c/FeeOyCITdz9zwgqm - e52OOUzI9nmq3zbhzd7b2nWHlJ2d/vmFN0u4oEpLodQPqBy/cvuoLQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXMXRHK1Nud0VEMUh5OFRZ + Z1ljcmZyRG9yRFFwdWtTcEVXc3NEOVVId2xjCnVIb3cvSG9oODJvd0NGd1BIb3A4 + TmJ4SGdmd1FDWCs2c0YvZXkxWWFidG8KLS0tIHIzUlloTUhxY29pQ081akFGSmRO + Y25iUkw4bU1sUzZlUHEyWDB3d3hlZDAK4auJRQylMD3vf/PeMdImqRrx86sT2vdM + lbmSBNqry2CueSgvFp2z4q+NOE4F5z/rlc0GZnUvdzBTLZ83C1BYoQ== -----END AGE ENCRYPTED FILE----- - recipient: age1ly2endyt0y9xyddj6yuj4nw6fa3ltvzlvew4cr4lzs6dv8dkavpqadmyxx enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEbmRtN1FXaFYwUTBsbEhr - T0tGcVkvdmhjOWZMLzZ3UUpoQ0V6Y2luRlNrCnU0RThMcXlabWQraHB0ZjNldFRW - bUtRNGgwNDZhNjF6MzlQM2V5RmVRRnMKLS0tIDB0ZUpPZzJFMndSZXJNQWEzbjZQ - YVJxb3NLNEJkNXlzR0Q2MUNhZ0NGeTQKC204L2g3b/ER0RtnTaGtuZSukTawgiC0 - 94UolrcApg2tAUDJR9AqJ0iAAu8KSkcy77mQIs1t1d5lwejwsOBUMQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyZFpCaWNlSGdWTG9EanBC + MlVKZ1FCMHpzMkNJUTA3QzZ3aUtCbmFIemxjCktVZ0V3L25NNGxLaWRVbTZCWjBV + NXJKSzczYUd1ajJ6U0VsTmRpQW5SalEKLS0tIER1Y3VCTzJ5TjZ5dHMxSG8yaHM3 + OGFWc240c0lSYXEzWlp6eGtIcHpnUlkK+7wia8nrB982IdbW8zXg0p4Zf/3XE+Rn + u0Nsa7cbeOpB+stTV/i/2ayY86+zkN8UQXJnlv+AVf3Oe/3xaKsZ1A== -----END AGE ENCRYPTED FILE----- - recipient: age15klj4t7gpfp69472mne4ue62pp6m4e04dmjyw7yf30qtqd3vl3uqjmcyxm enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjbmZRNDYwVjhacnZzTm1J - MG5FWVd5TytPNWhDVTR6Z2dxdEYwbEU5VVFNCkVpdmMxTmR2dHBKNnZNTmF4c3hs - eUozU2VkKzlKMjhWaDJXQUx3ZXdHV1UKLS0tIEtNb25NU204dFovM2xvMEpDYUJX - QWZLNDQvZjZjaDZiN3JLcWswMkhtcnMK0kkTPKMgKNiOOgen2BQANozKY0npxINI - ZhKkf/eQsPD5kUbD1gLshfeOS+GOcDJSjrYigneJo11yEhNVF7juDQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzUzNPMUE0M3Uzc2JqTUhk + ejVmS2FpSHN2YitaRHNMNm9abHdTSUF3QVdRCnlQcW9aMFh5MHRHNjNrWXFrRTlF + TXNBN3FEY3dPMHhNbEQ0eGdacGNvbkUKLS0tIEtoWlFqblROSndGOEZwdEN2cXcr + c0IzdGY3T3E4Vmk1SzkydEVLbng3MG8K2pF8UY+89cI0dh7xgdrvl7fn8f05jSpM + MFcVBU9ySITPb3lcGtOKVcyyh8OaTusdZWmzbnl/dKr7kWjg/M8l/g== -----END AGE ENCRYPTED FILE----- - recipient: age1k73gy5em3js9zklnnkzp5hme9k04lny32fgahmzddknjw5c295asdyr4x6 enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0VVBQaVluOExJSnBxaWtn - N2RXb0UzaFgvTmpXcENKaTkzb05Vb3hMeHpnCjRVSmhTZ01sVy9ZRnZrK1FTa0Ey - TnJmYlVaNGFLRmZUcnFXYkswQnQ5emMKLS0tIGNuMlBmYnNzNXczYTljbUY3bUtk - TkFMSlZzTjVjMkVUaVcyVXI3cXc0K28KUDg9+qZqrbUk+D8TEG2p5tu6v8HgGfHK - MGkbN/+3wmitC2T1HEdA18ULGrmd1SFN6qGIfYOkR6dkhETIs+w/jQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQZmdsMEpVanFKdEhaNUlp + Tk5KYllvRWRhQXNBN2VzMGxHSVA2aVhhclZFCkdGWWhLakN4dkVVMnhMYkk2ZmdF + TDhtOGlpWlF3QlBKWVJkejhwUERZczQKLS0tIGMvdWpXV3pJaytsY2kvbXlsY3Rl + Wm56NTVKcmdESG43NGhhWk0xbHZFeU0KUwZW24hBFmC3PR5iP4e5eMt94I4xHgo6 + qB2ceOd4c86h16+XiJvhiYbPQdvuKcHoMSdmt2ZbHstzeuOn1ZdClA== -----END AGE ENCRYPTED FILE----- - recipient: age1cmzh82q8k59yzceuuy2epmqu22g7m84gqvq056mhgehwpmvjadfsc3glc8 enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHSjhleGt2Y0JTU3ZRWnda - US9ScWpPYTk2Qlhjdlh6RS9JR0lzTVc1djMwCm8zZnJ2a1prOW9Vc3h4RjJXNE5G - d0IwYSttaC9iVGZaejBmK1J6SXc0aTgKLS0tIGZvbnJTZ29xcDJGbzkraytKb2tY - OUIxMHJmbTlhei9nSEpQeUtIWjJLSGsKwLTnTxIqkumhWoVbt7eKTU03upmZYvF1 - S3a4mS/FZAU/9PgtHeY7LF4a0wwnHBAOxTwKcj8lYPWQzfPNSBFEBQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEZjEvNlMzQXYvZG9QaXdY + SDFqSDUzVE1xNE1sM0l5RXNJZllEL3c2Y3dzCjFMTEp0eFNRTndWWExYS1phSjlu + MGluSVZPOExnd3ErN2VZVTJIb2l4WjQKLS0tIHd2SEwwaXIvRXhEVFd5OC9vQ3ph + azdrTklmaWNYR3RuaitKbHk5WVhsb0UKgpHMKCR0/LzLWUgH3aasF9tETrapgsoB + oNXyxH7ry8jE+WYw4p+oOgSpNVuq9ae2Hot36u3hTjgXuub9kF2IhA== -----END AGE ENCRYPTED FILE----- - recipient: age1wmx8y2hs83j2u5srdnfxljrzxm8jtxl6fr0mq7xf2ldxyglpzf2qq89rpx enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjMmF1VkdhUHIzYW5sdlo0 - UnpRUjNieVREc09ONWtqQTdWQU82R2g2S1RzClowWVpMZTEwM1czdW0zWmdiMGd3 - V1djaDBpRFZHU1BZbmRhUDk2RndmaGMKLS0tIG9oQmlKMW5TVE1lQ2ZEMnU1c0pI - dlRVNFR5ZDhJcitoaXdmdFBHenM2NEkKHrWek+5xtVdwVaLF7FuhdJJCdZxvg3ib - JKIN6/IKg6v8wWbts+oJZmH0+ibv3dPPCNll0U0toYGBkbJVUUiMbw== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyNFFWendCOFptUU15a1kz + TTNmSTUySkFrN2ZNUmZzNDVTWG96SDdwNENNCmx0TmdnTnVRYWo5ZHJQK093bG1X + TWk3Sm41RVFUY2FPVUN4TldjaEs1RUEKLS0tIFF3Vm9sY1BIeUxteFgwd0xaVXRt + SkJ6WmlobXF6Y01semFHUnJUK0wzZWcKMwhhIBUZxXRsaemaaJ7zFXJ8CH3Gw6N8 + nNZUTPb7eg7yvHIiST7EqO57qhpHuxqK/OCFBOIPYs/wjdO806ubAA== -----END AGE ENCRYPTED FILE----- - recipient: age1mjgw3nxlnqdj04mgjz3wn7fj2nl2nxla4p2r2fn4nkvayfgp09pqllxzyh enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXQ0FYTnBILzF1TENDVFcx - Wi9pZUg1eGNiTCtGdUFrRERBVGxxR05jQWkwClBLK0FBd201ZzlRVC9aQUIwUzlz - Yy9Sc2dpQ2l3Ty9ST3JrdU54VFN2UlEKLS0tIG5ldXY1R1k0dGlsRXhPYlpLS2Yv - dFBoM0RGQXVLdnhxVnJ0V1FpWmFkTUUKCHv8KQYB2QdcTdCB3Wig7YTRKt1ZiqkA - MT5A0z0rizax0YZLGJ7QJlWkT/EmX0EsV62cvjzXeUkE2FKpYffiNQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByUXA3T0Z6eVpGQVZheWFF + N2NOV2NjZFdlTUwySE16NlBuU2pPRlRFV25NCnlxOENwa3lKMlZHcXhhMkd1dHFH + bXAyQXErVlFvSnNvekxkWFpsNW1rc3cKLS0tIDRSS0lVT3BYNXZUcWk5dTNMc2Qw + ZjBKOW5XVTJiMFhpdm5qeUY0VjBqT2MK83ZdreVtLQdV5zPPjRpcDVKPtU2heVME + yhXwR5VmKKpSHnu9uYSzIjyWoLQA7uLD6GcFkUEcUuRifd0tYMJTuA== -----END AGE ENCRYPTED FILE----- - recipient: age16vzhcvz8tyxj8e0f47fy0z4p3dsg0ak4vl52ut3l07a0tz465cxslmhevl enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1VVlxd3RrRDFnN0Q5SGgx - OGlDV3lyYmRQTjBsZ1kydlI4UFNVMUNZYmdRCmh0dzdEUmFDWmU0VjZHZHhhN2ZX - MW04LzB1ZHc4K1dCbGVBK1NMRDJJbDAKLS0tIDEzclhsWWhIRlUrU1ZjV2Q2dExF - cW42NFdBa1JKZTRpb2Z3aVpNVDJaWFkKynL65X4AjGw7PDrFZw+J34KajCl/TfZ7 - fA1c8fyngnt42FuKVoSHiIrEUCfFEsf37NbV5WQFF61V0bO83EX5qQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTZWl1dGFGajFZNzhJZkUr + Nm5hc0d2WG9QRDkraWYySVpiT2twakpqa2pVCjhDUk94LzFZalkyaUdIVE5YMDJL + V3NLRHUvaWcwbEpXcFNOVTlhMkg2UVEKLS0tIGxrYk9wVWFFd2V5ZDNycVA5VXUx + Y2wzNGFGMTJXUUpPbGxuMU5nWlFvU28KTmP0byJFneTPHUJ6e+ScSiKypMrz7TNV + FHZ78vmNIzcstLKgXwK23hyEIYTtgrLOP37B768fAM8aHiqGQORs+Q== -----END AGE ENCRYPTED FILE----- - recipient: age15cx90pnp54xp5gxlt02yn9j2pz968wp3l5ukdkx55xuecp34e5pszjku4m enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1U2d3WXpqbkNQUnhvNmxT - NE1hUDFSZXBTOFlQMFYxT0F2VkdzK1MvRmlnCmkvc21GMTJjNmlXNWFxS0JsQzBL - MUVoWkdMR1hOd09MZUF4bUpubi9CM00KLS0tIDdCVkxXenIwN3F0YW1COEJxMTFn - a3VvbEZUUHNJcEhUMllud2tYQU1RQUkKDG5dUpTAKHdGrnD1U2JWWv2Ue/LShVwt - XRgdjTwmXtvf2s9sIetX2rLiJxcLkpRz8z+AjK5c3GWxF6ZVPuuGvA== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSakpNTmczZGNWUmlxODlS + eURFTUcxLzZtSU5RT1J0cE56TXdPb3NsRlJnCm1pZVBGNFJrd0w4cFhFMkxzRmYw + Q2thUU1DVlhBc1Z2d1EvVEJvKzVQOG8KLS0tIDk4MUJ1Q1dIM1lkdC9KbjgrNG1n + YjF2TzltV2NsTVNRM3pRZVByS001R0EK6d+Hwl4dQB79n5Baq8kQKUqYaifbp7PH + YUZmR8xwiJP87oFmD2lETgJQyWDvGBk+nM5glAjIqO6PEhJBvviVHw== -----END AGE ENCRYPTED FILE----- - recipient: age18quey88vge7xytclg2nuq4ncme86dg04lxwczqxczmdchnjg3p0saehsnh enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjQThNQVJyR1BVOElNNldl - ZmphdkE4ZVpaaHE2N2tPdGpxMFFaVHUzZkg4CmlsSmtRdnVMSDhTK1p3S05Kamhi - THRVMUE2d1NDc3FIdUpXQXoxa00xRk0KLS0tIEhhUnBIQnJQUnZKU21vTHk5WFVt - cUhkVFRNMHFkdVFMQTdWWUwyVGZxZU0K4Dn0V7ulWdSOnsFSaFTBdfOz6RD0R3Ba - MOM2I0afFAcbQI2rzdySbGzy7yJeuA1puBbrHDMOkVCK2soYm3Gerg== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRVVYweEtGQSt2Qk9Ic2pJ + QnJlQ21wVzJTZGNrby82dU41bDRkWTFvandnCmtYSUpFRkNSZ2FBNFhpSURQVXFt + ekhBaHRlc2tSS0lXdFdRdXR5SEd2MzQKLS0tIEZTeFhqZjgzZDVwN2NxVVluMVlE + ZkhzSFkrS2NMK1diL2RwbnNzTzNQaWMK7/Q16epHfSDQ4q29DN0WpLKCWh2rnLJC + cKR+gQKXUNzt/7Osh6eWuCVWMfc9p03ruvlxrJ416Am4k66kbAmrQA== -----END AGE ENCRYPTED FILE----- - recipient: age1ax5hqk6e2ekgfx5u7pl8ayc3vvhrehyvtvf07llaxhs5azpnny0qpltrns enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjOVpRQVJBVWFnaFR6SnBo - UXdrTk4yMW95QStMOGFqV0paSHp2Ly9Ga3pNCk1PSnFOWFUramM5OUxLU3BibG1C - blJtc3dNTWlBek5POXRMbUZDbG1WelkKLS0tIGZkVEErZ0twTFV6dWhVanUrdlpY - VkJDQ2Vmc3FPTEJKbWcrQkRwYnN2TG8KO245mM0A94pLL4/EHi6/eeh4rak02IuR - n8rBcJ/U4qOD+1QNW+mHbGiNNSHLtGHuVrM5uKaruRJDmxzNWQjmXA== - -----END AGE ENCRYPTED FILE----- - - recipient: age1c2enwel9un28dcs4wg0vcyamx9a4a6g3walkhu8w5lqhmd804paq9d24as - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkUXdnZ1FLenQ3SjNwN3c1 - aTREVTBhNEIrN1NWWUJ3SlRrQmppSnVTc1JJCnFydzZoNEdxUVdDUEQ4UkUyUTYv - aXAvZmxXT1ZkSmpCWUpWeWJZYXFGcmMKLS0tIDdySzROS3dxSk1id2FKbHZ4UERG - ZzZzYjVjVCtMdVpoM0tzY2w4Mm9aSXcKr88HZkBxwuRzDtb/I8D7uopzjglZQsKD - oEd1uz/uYhDvy58MIKz9nnTMKyPUOE+uICZbjZ25ZsdkcDdCWNhyig== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5OXhuNk1VcFhpWWJYMHBN + U2pjWXJNbFpUZUdBbWFxOHRZY3N5bmxwdUJvClpTc3ZiTmpyZW8vS2UyNGh6N0l6 + UHBnTk9lSTEyOGFvSnRKUE5rN0lrRDgKLS0tIHRsOXJiR3RwVlRXSzlVRG1PRWxu + Zk5EVlJUekwxYWpuVkgxQ2oxcGI3K0UKmA+Ae0Ja6CfkGL3yhpGsmHVdZLPz2/Sc + TYeUhIwKRJql7Rg4Yu0aG//2gK0HKLnSOq/nJtSIJ+8P87OKTYg8iQ== -----END AGE ENCRYPTED FILE----- lastmodified: "2025-11-19T14:09:27Z" mac: ENC[AES256_GCM,data:tZ6QzVPivueZiC9Qfb3KNZAv02QatgHRNnlM+Y0iV4BZkYoBjxeDojutizvAMwUarnubUdk5I6m2OZK1mvVDZKXyI6zALX4JMeT2xYQWRHYzHpOygLhhGwTFVhV+0C4jN+eJFF2cNf9lu7NuZI9ylZSOY8I3YKUl+l0l3CkXUl4=,iv:JSGOUq+j9T/NXspn70dfu0J4ISV6vVFZUe/Z1CirrJk=,tag:Hm9N55f9qMc056nSTR1piw==,type:str] pgp: - - created_at: "2026-01-02T21:17:29Z" + - created_at: "2025-12-15T21:53:33Z" enc: |- -----BEGIN PGP MESSAGE----- - hQIMAwDh3VI7VctTAQ//cFd10y5cI5pCudkNrwJjjCvaJmP33pteHYJrzH951JFt - FmO5NVPxFkyZIApN2LJ+neqDhfOHWoAqb+2GWeAnKQwqWWD3mAMzTFbZ/GnfNTpJ - tdGh/PtTawnjl5olwv/TSDj4DJSH9B/r5KJG+2oKvDNYHQ06K6qVoZTtlI9wA8nR - TLZlqlHlLNrYBBKNH8hUcdwCbd9wlBZGY/dhprTUlKb+W7i5LszQJuKdmxUj4njq - QVjxMG9AHKn+SU4awAOyEI0uzTdKApem1REaJE/d+quaR7KLCjZIpQ3n4SsbBUfJ - yAsBv57JAlxbaG5xuMZ/kjWQaGiufUK0J9IBfEKAyHZM//iFl+CAPNzPrQDPI4wy - 6HRL2r9EvUwZb6vJYskd8Od57nT4/0+zV8bSzh18JkEc9UKvMn7d4bx7AnKU+rsP - cDeIC5JTJjygaiodIdYAYS81FZZGj+t04hrAzkiPZcM/+3JdHNkuxV4jKbD6ljzr - xdCaJUXSmGrK4uznLFoIBz4A35UHSwSsa8s3RUL1Knem59cGSMVqfz6nJPQ/0sOT - tI+8VI5HCdJ0vlNw669opzgGGiaIKcBKWfrXsxYkww9ekWxbjWaBcFLKm3g7p/mh - KzFRmQwcOXG6nQ2ROUnL18Jh1u+iiXvzc17yK/6xuh3lLi+wvfRXMb3/ePG4j86F - AgwDC9FRLmchgYQBD/918RvwuPqcGLYgUJLJr/ycnAG5EzoSA7qqBvItgoJfzbah - oCnnVRwAyvvvYYyqWrpIxc9X5w8vD5CeLDWEX4slm6AXUbBFK9i+tesmXC6D7du/ - Sb/DHYH1Fa168nZ/oK2YieVQto6VS0WK37WqT6thybyEpYZu898tE9mY9riKlE+B - JHKjGailLl4KeaWbZQgLNP9KKi1wwOC/Ae43SS3XqFWu0zx/l4RHn/KvNNVcYyc5 - UuuBHhFem12f14xVy2bwjELTkQfImlBFmPmbN2sqOIG8maFzdwUVfVMcAR2Ceq9Z - pTOL2q7NCZ/JlwZ25ficJ1Og4Wnk3oTQwZswoN+nApIF7Td1QxmDLnGB8xmrnLpn - 7A1PCo9IR3MdOatqN2xvotV1WotYTz3lcqpHfsYpscEBuyozxVw++1c2+QpZtmBQ - C3MQoqUDXBwvku5BfVG97XFy1QDCCTelUPdNCvIkXoJg9AUugPYRokCcI2bTybFY - unL0sirc8+/mgEQTwZgJXDhtvYTpps0pj5PFwdDHRDgrW/CzSkLz05HIKl+NKDmc - +aIxFLAQiFBiqgJneb5q3GK7uZq0YVIb86MD5sqSNT2Utz1KMzhL56sTjPEtn73E - zfwMX/EpCkpshsfbG1hLZeKPsYZBAo14Jbv/IfWHX0OXp6EVWrLM4FT8sEEwWtJc - AeNU3uXSpOW5xlKv6bpNSl0A9C8XYK28FU8JaENq85Q5VZGLf4JP2auFXQ2PWbpo - 9MmhPhMNk4a5aDh+AqaB7yXCFvqzsGEJu8Xqe3gAN8Jn9ThMvUW+nwm56A0= - =arGb + hQIMAwDh3VI7VctTAQ//T3Ld00/QPCKpVc4bonVGR1XRF8POkqr1eGc9locjDs+x + MZFYAUApLXsM2A7W6hPa+sgffHTPmyjg85xC3XC+Z9aWCnHAh0tFjU0OdBaMOaK1 + ha3nX3FmmC4QEuUs4elA0/CwfRG/16/bRTV+ys1jESM8AnQt9RhsBtDqJ42wNLFW + zlM96X+7j3DGyQAkgFV4qW4uL2tpPgnTgpvhjotW4Fl0xsBzf8E09IvmDGAV7sbt + JQcSAUxZilKjVlwutz2AnAOl3fLaaBuNIYySr0r6pc4uv9W9g9z3NdxkKLrdAN4w + UJglMIRai7Pv4DA9QdC6khJUswngfrk5GWuRTkqNSMkVOi5pl9y+Tdw9qKuSVFoE + GGmMzdmbFd7XOAYwIawAZqWAqlZ3mJaxAwSwut1Gls0u6BBQh4wjYJW6yknS8qJg + Gb92+Ly4r3/Kt+iOxpL9Uz6JUWtk4DFRCAdiwGdie6tnoB6VI01SVzkw2aDj7deN + kG7AFx1kofX+kUvi6gKK6kN0cZuwCOlyUE7OUSWSKWCmVzqUiDMy2WUdw+x5arqc + zjstPzBWW/hLr5aY8vHpPONoM32KWc6ewKnxeVt8kjCh64IHOJQ4c6ilgghqECUd + DN8AnpCXWeP09LkOu5rNX9miuLAEIGEYXZoP4bfVHKxP6jsx9jQdEBD0G21RaFOF + AgwDC9FRLmchgYQBD/9lPhj+gc929oxlP7cEanqOpcb3lHpS6d6wOF1PXoFn48P/ + JMchtMpNfQZ1kDW5CcdoG31zeTzhjpUlYVuZHhvhBuT+pEshjZOsw7vY0NAdScFE + /45MrKsRKeHEkhKcke6w2BNW+o+202ZIjSZv+1QvAQYt0wGfI9EzYclE9CV9zcrm + 3M5exSXVOYgt6REwEVKb0OaoAAgNrlRpJRj8CjrJ5g1vN21wG+anqhaxYoWFdsXm + LMKY9eyAAiFm01RU7cSHfl1Qy1op3KzpbQyabQ6zIbq7BS/ouo4jGyMyHt3DPT1e + EY7dkNFcZh5sIIZEmKWjFbjIXT/urVWdKJPfkdC/QLsCvm37V5sDs8JB9JFivumA + LcNgFVmoCdmM8K2f98q3R6K38VsNH+AgcJA87RKGnHMw3NVnHthR6x4T6+cknK09 + e0iV6wdazNN5/1Bmu1Y/JrnaGyIAuyoom0Nrv+OTVgjjenftw+J4GsWIpicSYHHc + mN8TcFqqrZ9QjHQS9BMXFNLC+m1HGpP4Mi8J7haEh6cIURFVkmZRDl+SUwnqX+BN + XtHs2q0Ht6jDY1K93StrXTFqNTasG31MUEcs8og/KkUhT4LGRIrAJoR70jPojV8c + TQsT/bLFgYVvKaKPRoI6SbJyhQeoJMnEoDFAZdlB78KBMcRSAHZt16j6f6bke9Jc + AYQEzirwmSjViuIEnu57k96w1UHJB+rjjgP62C88A0ENr97UbCacIC8EemFN0xPP + UDubuNbq7O9XAfoXbKy8jqeciZVo40AF8YN3HZuRnrppgik5zzs4o3yBv5k= + =1hR6 -----END PGP MESSAGE----- fp: 4BE7925262289B476DBBC17B76FD3810215AE097 unencrypted_suffix: _unencrypted diff --git a/secrets/repo/common.yaml b/secrets/repo/common.yaml index 3f054ac..c32b307 100644 --- a/secrets/repo/common.yaml +++ b/secrets/repo/common.yaml @@ -41,161 +41,143 @@ sops: - recipient: age1s0vssf9fey2l456hucppzx2x58xep279nsdcglvkqm30sr9ht37s8rvpza enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvcTNvUVVSZ2R1N1FKWWw5 - dGJHc2swRXN6SmdvZ09zTGhYa1VqWnp3L0VzClZvYmhYTjdnVytBZFI3c2JqdlhI - M3NiNVFQTXkzZ09ESkUzamRleU02WFEKLS0tIElxaENIb0V6RElZeVZFZWRIRzlH - UE1mM0VEOExFNm9OaUV1NFh4cEc1alUKX6niNF5QxQ9ub+grPkUqeLw+gjBcwV2A - Y7zeR9eYAABCkDh789luQd37LXP2QdD90hiaDGMQChVMpmcIjdP34w== - -----END AGE ENCRYPTED FILE----- - - recipient: age18cgqlely56hgmhscllkmafwpjdk6dwep6ej3vkk97dzemp8jtuksqrrjjl - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOS3g4dEhVYlBGMXNzcGN6 - ZldoUVRtY3FsNVNpcXI2cTk4T3RzNUQ2cW5NCmFmUXRXb3REaXZTVk5MemhOaUNk - bjYyYThFSm1ZZ2JRcDF4WnFxSndxL0kKLS0tIGJXZEsxRS9LcVRrd01xYzM5QVQx - MW9TYkhMRUdXZVVBeVkvRUFQWElhMW8KIhz1sFGRNkhVyLRZjA3IyYInRbNhN/Qq - 5OWHJj/iS05xunkPNoWfxphRtHRudljgDXpt2UwYgWoTm1cAnoIj5w== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1UEUyZDNVQ3U0NklpU1Bs + VndoTnRBMW5ESUlDWi83TUdGdXpMeDdRam1rClh2SU4zRmFscWtSWFMvYnlySXAw + S0hjcVZZN1MwTm1kZ2xUcVhxQ0wwdHMKLS0tIGE5djdQZkl6NFdJMUJPVWh2ZEJW + Y1BMbDgwaDliN2tLdjBYOU5TaG9uaDAK0bHyEDpXoM1hZlhw9uJVOpCG8FnfONyh + cZKAl0ykQ5dZ6pQo8K/4jtOf08GesZIRenyCxIE/lNZBvFg6OgJBJw== -----END AGE ENCRYPTED FILE----- - recipient: age1g7atkxdlt4ymeh7v7aa2yzr2hq2qkvzrc4r49ugttm3n582ymv9qrmpk8d enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXbkc3aGtMcXRiTm82Nllp - aHRJdFVvcXp6ZEorNmVmUmIySzdRWW8ydWlnCm9oYWZhTStJQmNSL21hVFFyOFpL - aUFmQk0wbzVwTWRtSEtkQ3RFc3hOUFkKLS0tIHo4YzU0aHhFVmZCTGZWclNpakdn - eVVDYUNXUk5BM2M4MFJjVlY5NzJKd0EKt/vaHVeTowmbc8MfQwHqxnbolf0t5Th/ - wBQHe+MUBg9lCr+TqDi7+TaRYa93V0oiBVQ1uDLweV5olpOi2ttc3g== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpcXFsVzNBRFlsQUxiREZI + dG1UVEE2c0NzSjk3bEM1UWlXMU5wakFZTFRJCm5VQUs4alk0TlYwNmRaOUNFOHdW + dC9CTVRuODFnMmpxRGY4L2l5azU3MTQKLS0tIE00Rm1BSDh3NnZRZ1BJbzVLL0t3 + TzM0TExsbUVXRUhKMDVMS3B1VzYwZGsKDD5JXe6ySfCrgiVXN8NjI75z2nr6HuhD + cTx0S3m3KD+uyw9bVVdUkRTCFaLwD05080PN46uB532HsZAMLLSFQQ== -----END AGE ENCRYPTED FILE----- - recipient: age1ly2endyt0y9xyddj6yuj4nw6fa3ltvzlvew4cr4lzs6dv8dkavpqadmyxx enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDUVQwYXNiVTE3dENRV2N1 - Z3AwcDk0YkRFZkRjZW9KZHFlYVNaWHljMUNjCnJmN2pzaXV6RFk4NmVFdSthYVcx - TVpTclp3NnlBakNaYUQwMmg3VVM1SDQKLS0tIFF2enEwWXAwYVVTeWxNY0kwRWdC - bVJuaEdsOERBKyszcHRYUFpUcm5zeDgKISCkCqLSCUwSM7XqrY+JMW9OE9q5sfbB - EXVLqqjqBICQ50vtnGywG70qu3WXzpuVy0NK+zA/3sgVpXuU6/Cplw== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJTFYzakJ4cVJoMnhTUDFx + SG82QWFMWW9La2lOcmdPNlpaWjNpNk11M0hZCmp6TXI5Q2NLa1ZieVdlbllhRUtB + cU1EVkZxa053NFJkZUs0bE00MnpsZGsKLS0tIC85UzhzQnNKUlMrdDB1SDJQZDUx + d2h1MEJHcjdxTXEySTlLNFlnSDJoSXcK2kWhF7v9mm3EIQoJ4aQIT8I/INKB3lSf + xEscNVOqeOGnfdrOIYHBWhWIsBNRsgfJMIxFY8TVxmDNGj6r4GqvHA== -----END AGE ENCRYPTED FILE----- - recipient: age15klj4t7gpfp69472mne4ue62pp6m4e04dmjyw7yf30qtqd3vl3uqjmcyxm enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArYnQzTm5nMHUrTForWTlq - akhabVhFRlVxQmZFS3RId1RBU3FTYVl0NUJNCmRGUlp3QzR2RFVNU2Q4aGlud1BN - bWlzWnNUQnJlelVsS3dhWTdyTGgxUWsKLS0tIG9sRE00QVozUzJ5eEJtekRQWmVr - YlM2WXdQTFJRMTlZQ2xlTzMzbXFFd0UKZBiT6x4zfpKQctOCUFmBQHzWZ2rFIIKh - Lx2oteWtHrGABf+wc45ypz6CBEJjw7moBf7ZCupOOL+jIJpe3UriqA== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSVWU3YlNtby9ZVWNWZ0R1 + NWV1VUo2V2hJSmJYVlJmVkloMzVxbVFobVdnCmxJV3ZvUzBrYmFLYW5NNWVWdDl0 + TDkzZmY0a0FHQTVmOUwwajhtaWRqNjQKLS0tIEJFUE9Oc0IwTXpJUFFjUWxXTFBW + NmpVbzRDbzVGOW5iVFBQYU9FdFJtUU0K1NAuCYjrYUZVLajR3h7Le1p7ZDcfGYpr + kctaY2S80mPxN2Dv1Y81S0G84ptmi7NXTCghDrPhkdrnzFd+egeWvA== -----END AGE ENCRYPTED FILE----- - recipient: age1k73gy5em3js9zklnnkzp5hme9k04lny32fgahmzddknjw5c295asdyr4x6 enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFcHZqNFJWNGFOUUNkZTlN - L0IzcU9qR09BcGQ5ZGxGMmcxaWx4SHZDakdvCnZpc0N4QzNzTU1XWWhZYk10QjVN - dHEwMS9xOGRBSlFKQi82eE84aGMwbTgKLS0tIHNjNUFCaFdEM3lmTlhNUDJHQXlM - ZVhBQUNoYlMwQ056V1ZCRUdrdG5ESWsKO8a6+mhNR2jzTHuKROp0QbFFLJD0TN/e - 5zKySP6bHrlcK9fguXWnOqshWuxPdECNmE32L0pm9maL7G2T4FhvzA== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkdHJCREhwRWdqVXVYa1o0 + dEdRNjhxd1VxWWI5b3dQQUVacXdmNUxWSFZrCjFFdEJHNmFGeVhyZVdSeW5BQXNO + L1I5VkdBK1FEZFQyblVtOWJOYzl5U1UKLS0tIE54NENJRUt5bzNvN0NIVVhlNEQ5 + YXFPeDBQZUJsL0IyNFVpVFB4NUdtZ28K4LIamLUU4zn9MY7NphIjfCMSWlwLkF1c + 8zqOyNS5tpjCsdZ47IInoPSxtlKEq/97PV/nUzw1BTH10Rxx3ENCGg== -----END AGE ENCRYPTED FILE----- - recipient: age1cmzh82q8k59yzceuuy2epmqu22g7m84gqvq056mhgehwpmvjadfsc3glc8 enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGWDdyVm51cFZ1SjNVQU5L - UUFqbEhkV2puWEJxVmJkb1prOGNnZ1pRZG44CkZpOEZ5dUdjN0NYWXZSK1lLMERG - M3Rwb3FLa0crQmx1YkFZTnZlVGF6Z2MKLS0tIHpmd2RyZC9ZR2lIQUszZlNQbUJu - bVNkMTI3ZXpDY01KamRFb0FmY1B2dWcK1RRtVtIwzgckwxX5YEQWdL+BHUdEAD57 - 9Y/lLGzhGHwRA9lYaN8q+cpMDjhuIDiDqSZV7N16EZcOjZ0MIjZonw== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1djk4SEFBUXF2U1FOQjZ2 + eTEvaWdMcTFzY0ZBTk1XUGE0UGUzNVMyYmlZClUwRU9KeGc0cVZGSTdDaERQSWhL + bHhwa3RtUWZXSWFxYmF5UWtLK0JabDAKLS0tIFR1eHFPVGNtRDJFMnNoaVJnUHlJ + d2k4TjF0a0tkbFRvVGR3ZS9XcndpcXMKpqZXI/APjHSqR+j4/k4UcQfdL7toFGHJ + 9vRdsWWYGae3JABNpFGC8xCpvEtdPyMwEQw0JpjkRz3n0KKSa0XL3Q== -----END AGE ENCRYPTED FILE----- - recipient: age1wmx8y2hs83j2u5srdnfxljrzxm8jtxl6fr0mq7xf2ldxyglpzf2qq89rpx enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzaXZTNU4vNTArazNxZnBz - ZGNrWXJ6Y0JSaGY1UzhjdzhIdVVsNjlQUERZCm5RV0Ftams3US9WVzA0eHdOTkpX - RVYwS3MvUXZNOFFUMG9VKzh3aWk5YjQKLS0tIHZhb2ZSYndLcGJIK0xURTRBR2NQ - OVN2ZURGSWxCNkViK3NFSVRqdUo3aWMK4tjIx7paJg7bTgTwjnXjbpHE+Vvf3YbF - C9Ekp1Kw0k+THfTgnjwyNWuaLv+8VoLqt2k10H+oALjLHxQKpPSmCw== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvSVR1SzFxSFphazlaM3Jv + a3V5Um5hMS9SU3FHTXJmQW1ncWh1VTdXNEhVClI5NmowcDdzSWVsTzRWSzN6L2JC + R3A1NElHdmFFU0psejNlWkNidTlWVUUKLS0tIEZWMjM0b25YSXRCS3U5aXdTN05W + eFUyYzZydWdvTjBTV2JnK3dQam5Ya1kKBhrX+2CX9ZJdymOY5yC2thfUY3/N2TB2 + LqUctgXpqxk67bupTN/wkfSkYV+//FdSdVtLiopnXHC5k0QIVizCSQ== -----END AGE ENCRYPTED FILE----- - recipient: age1mjgw3nxlnqdj04mgjz3wn7fj2nl2nxla4p2r2fn4nkvayfgp09pqllxzyh enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1ZmV3WUc3SGR3OU8wb1RX - aGVLUnJWdU5BTE1uSy9YSUhVUHIrMEhDVVVrCmhNYW9yd0I4RnBaSlJRRzR0R2NS - R2JkSENzQ2N4ZW5Xdmh2cW9iZHVvNW8KLS0tIDA4cTI2YitUMFlVL3ZlVFJlT1du - eXh3ZkJyRk1oOUlmM1dwdGUraXZsU1EKCVvFlj0X0Q79116nQ+8Ybsjk1HBE55vh - /j5g7ggeLdCcoU7qEevHvBukbGa84xmiwJxa13mumI7Yi4383P8Twg== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2bW5hblpKNGlYRkwvVXpz + ZDlNdkNjS1ZPSGZUbXdnZHgrTE1XaWw4Z0FnCkNEZ1JFRDA5eVJEWTVGdVdwdXNI + Z1JXUnhXOXdTV0RoZnNYNnAxREZvV1kKLS0tIDB0dlM5ZVNzRlVzRDU5QjZDcllU + VFVjc3pZdHphT1dwYnV6NTFtTmViSTgK7a6/HWAV8Bxf3d062LFXB1QyTqvfLFPB + ZrTV01HMKzleFY3Fv9HLjJNGt/l54ZVdq+Ea3sp9UUfw+BKMpoqrrA== -----END AGE ENCRYPTED FILE----- - recipient: age16vzhcvz8tyxj8e0f47fy0z4p3dsg0ak4vl52ut3l07a0tz465cxslmhevl enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMZkptNVRuYWZMWmZkdXMz - VDR2OEpOM2E2S2tZOTNPaXQ3c0taYVBZVm5rCnNqWnNHNEt2SlphdmhZZ2hGS0JE - RXlDQ281cEtjblNZeVBvWkVUaW5lc00KLS0tIGRLKytBRWNvUmlJZ2RzZHZWdFRy - K0VWbzdiOTRvbllSb1dIemVLNnZiWjQK9StbdLSPG2h98Dao5ZG3qvhvD6iSg3XK - MhgksJ/YfuWo0aaLMZ++1jjGD3O5DE3QbGrBA5R2RcInvUi7jHWBtQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0M2dYWVBZWVFNQ3JnWXVn + YVNnYWFzdGxXeVhLQ0tBdzdaYzhaN0p6cDIwClRXNUNtYTRiNXFCZnZ6WGQ5WUtJ + VzBRV211YzZ2VzNkTTJtblNFZ1hiUVUKLS0tIFVhVEpCRHZOTzVsUmlxT1VXZWZx + bi9pWnhsY0V4TjIzN1hqeVhkb3FsNTAKcngM/MK1uLuw2i9AOxPnscD+OLopKIuv + B9U7mSE5zRyYFgXK8Y+s8r3CBq9NUFlKFv8Rl9wmD7EMa1DfZ5GF7g== -----END AGE ENCRYPTED FILE----- - recipient: age15cx90pnp54xp5gxlt02yn9j2pz968wp3l5ukdkx55xuecp34e5pszjku4m enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyMjZLa3J2dUlDNnJmcUtq - VndpSWxGREhCY21xRlpNb0F6dVhvZXV5YkNNCmJaVFFRdGY4NEdUcTZ4ckhmZldM - TmU5TDRwTG5QMGVHN3BwOWZuTFpQWlUKLS0tIEg5TjVjOUpaa1dabTlzM3REMmtz - ZUVWRGFsbDNWRTBaVUpnZlZLYW1GT2sKInrMXDj0MLNb4r2hwZEsw9HxpVE/eThv - TYyiPbaNkzr0EqDcOQQ/3MEw0Q2XPaMDdCG18u7kYlGGwdYNcWRgmw== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1Q1lSdld6Q2kxMjJ1WTlB + M1I5MTRpMkNiRjJJOUVKRnlJcnZsd0UwbzBjCmlsMlFvMnp6UitRcjR3NCtDZ2Jz + TjgxSmwwRHFMQjlrTUFTSVBpNU93cXcKLS0tIGxxMXU4aURVbjFpSGlLS2JYNVdF + MnhxTURKWWdzWCtaMS9lTjM3YUdNSDQKhNFCq2mRvWMAsCUXrpiW69ti5LfBilp+ + 8B+mk86cFxhpaZtQLOthSBhhzTTdScCKDTywEVV6K51x1DGHqrYfbA== -----END AGE ENCRYPTED FILE----- - recipient: age18quey88vge7xytclg2nuq4ncme86dg04lxwczqxczmdchnjg3p0saehsnh enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0UVBvdXMzRVRuc0N4NktF - MzdnVExNWDNGanc3cGc0NkNoajJROFR2MUM0ClIvQnk1RmJCWXJZcjk4aHRYUTkv - cUN4NHJaSWxHckw0NTV4WWxKWHZHelEKLS0tIEs1em8xamQ4YnVpTzRZMDg0UkIz - b2N2RDRYemVDSzZESVhUOVR6MUEydG8KVLj9kVMaZeKDIQiVQF9lu80wA0m8CuMD - IBCwg5sHoz7fAK8vHpUPKh2XooD2BL9q0pPZCc3sCUjQvLgW1ZK1YQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtR2NWOW45T0VSeWdPSHBM + OHJWRUUyaW5qbWx4ZytGOHJuQk5rRjlIRjBVClFJSm1kSWdGZ2xwMFE2TVRkSG9W + Z0FRS281UU5oSDkzMHkxOXhIMnpzcUkKLS0tIDNNTUhMR2Z1UVcrOFhRWWRYdUFF + T2d4dnJxTnBueW1LWHl3VnJMTm5abEEKUpUtH/deey97QuKWMFxabVSrpzzfaoSw + pR7nianRBaD8b8HsC8V7x98CenFBK0jVQAkx9VGMgqIGDsTaHiHPhQ== -----END AGE ENCRYPTED FILE----- - recipient: age1ax5hqk6e2ekgfx5u7pl8ayc3vvhrehyvtvf07llaxhs5azpnny0qpltrns enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2YWtZNlJBMUVna2tmODdo - TC82U0ZtMFV5L3Q4NktxZ1N5cklyR0ZUZ1R3ClNzSEhEVmg5WEpROTZIQzQ1dm92 - UGpxcHNzUytVYUM5dFJDcVVzVzNuWU0KLS0tIGtYaVNBTHNYNVZQTnZUN3BZSEh5 - eFQvUWx2Y3JPa2VCem55TkR3M3U2M00K5TSdJyIS1yCV8GIYZgWlSC/y2r5+hquL - RLougeJFaSXiZ9AOzsnC9jGzzBVvlsf5RNH+fYsK9oHuTH3Kv/s8Jg== - -----END AGE ENCRYPTED FILE----- - - recipient: age1c2enwel9un28dcs4wg0vcyamx9a4a6g3walkhu8w5lqhmd804paq9d24as - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwWWRpTkFsWVZGbkY4dmli - VzRQaWt0UFM0L1BkV3dTSjMxbm4xMFhCT3hVCjNXbllqNDl4cXhZaDJVd1gxQ2No - d2tLL2VSY3N1T3E2WldHdDlwNXBycE0KLS0tIGd0YzUrZzF5cjlxVDBwWCtiZHNp - RVFnZWs5T1pxN3VHRWdnbjR4UFFIcGsKUnEeBhX9K2tUNd48XOvpb0n2OoeUPyq2 - N+LBxwPYoSxoiZAW0vDg4mNcJwALYDXA5ew0fSZj1nP2LvaROV84Jw== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2Zk9wN2hRTzJYVnZ6RUwx + WFVtdzF2NUM1QUxFRjdYNHVOWFErK0dOM0NZClZpc0JQZzBNc0lFd2IyZDAremZQ + aWxmK1ZtOEVZRFF5ajZ2QkFmK1J1bWcKLS0tIElpNHh4eDZZaFNWczl4MG9ZdjJ5 + L0gzWDFia2Jha0lDaGZaSWEwOWFmb1EKJqqjxODIgVeiMKtV6361sjYQa559pKCG + 1pKczlzXxL1FliBQoZZGq55NR4azWYEl/yV5tee1dtUohJW0pAyScA== -----END AGE ENCRYPTED FILE----- lastmodified: "2025-12-23T01:11:36Z" mac: ENC[AES256_GCM,data:e0WoFBQSR5q3GOQ+GMJGBd4lNBAMqlnVjtUq3snxrdvcytb9YvKnoYQH+GjbdGIiqrND8pOVnZt34AjkR8YfpWe+VrkP3Vj/3l+1GjF1XIHbzBNKOQHdYPSVsH2NZwftcAdphbStf3GTlb+b+cpTn4a9Y4pTNGVoOaOA1tBr8bM=,iv:sPXktitTNMkBhHr6E/QRZCVKrgyED9/o9hiivbObACI=,tag:tTNr4UEf92UrtI0Jvi5o3g==,type:str] pgp: - - created_at: "2026-01-02T21:17:35Z" + - created_at: "2025-12-15T21:53:36Z" enc: |- -----BEGIN PGP MESSAGE----- - hQIMAwDh3VI7VctTARAAzjG3sJ25PaNOD6VowSNYaaK4DCY6PU2LGCCpJWzDXnwo - irJZUtGOiqeZeu/8BdWmQSwBiI9k/JuCt131rwXCrtj0+Yj0MRKTK/xc8NoDnW5t - R0CpQnWJ8yc1RRAMhx9l26HXH44786rhVt5/4ZCvq2mje6Ha0yK0vmjO6P+WR8kA - AUCuVUtQCtN5UP0yecdRHl6MvZe1qPd8tv3kLittJ2c48LD02CL3g0ZeATtCgiGN - 5h9cBfDQnFcBh5EuMxn3AoGQjIJollCS5fRNNi1VUTp4uyAqYnyRjnORNI6vRk2k - hju5W5ThidbYQlJlwO6hZM7e/sW/XM8RWi6x4TO1VN8MuXavKnIbzlOKmJZlLbb/ - yp0ueIzKuJpEz0nQZh0DFCD/D8yoTAfgtXgzzZKuUgErhkCQEXe/xKPDFvSKkWqA - AnVl6RwyTl5110Ea3535K3vycYR0EAxapEqzEZ0Ez/o28wR/1hgMrTWE9f++6HwT - wZ7EiPTs45yzZYJ0ONE4s9u9HNIvUY4UX3ncIhvTIWMyASfS2dbDu5fqxg5e+Szk - 9QcDL0bzLnGCmR4w6fKUl2mkupTMsi6sfRFMzGlabK6FizUnpwNQHd2LAxL7rNF6 - JiD6LxVQfY/TfKqQdKa93Ctf2k/tkdW2aw8JKZh02V9PqXUax0N4uR/TxOjKa/GF - AgwDC9FRLmchgYQBEADJTfHgtKmwdG4s+Mbml+VD3f0tDJnbOXBfISFp4+s/6Wf+ - kILyeL7V4yllzJWqUZ97IH4BScUBSbvcg45IvuzgfTrBTx6ZSa3OQYo+2KS76Wsv - uQkItpGdsVSrLYDseH4cOWev9D5zscU+pEdT6VKXP47UHbJPdxQ2IU0oncrMatgm - rBh+PfB+XeJRX9mKzsL9qVWuc5k9SVcsXLKSCM2IJszfRy/vsSJcAphReHxXHSuO - XYGVkSYLGgzA1by0wjZ4Gi3y8MVaUEm8rXYVnbaVRnx5bntEfj1pTjmqStH0EE07 - vkOooLLDFaP6o4c58jvRTwXBWKlBbgWqoSBgm08OPKQpFFpM+14GrLqGv5ECti6W - 299pjfyWU99ILNG6RdQiS5MLA01z4wWYXRlxyNVXOHlspVaacX8cE3/uGOslURwH - ZbDgmpyAr3Ss5nj7s8plnxpYIRdXNCgPJ8qZtEVSuQkHbkHMKUJ8gycQNRcB8wZI - H4EtOkeG6mLt7WJlWa4T2VF1AEfQXZoewkaWCK7JekY+DPyyK+b3JT6qArAMvGMl - apVaDegSptYYUteO67yHwP83GNAGwDY+o1/ECZhG4ucGkXYpS6MCBkyCeV++gy3B - qotF5Hr5xSOK8jzFm7k4UUiBiQmv8IDh6UUOOXAzejxn61ZYPdA+aEIBiSoueNJe - AffTd0ldG9HGm016X1uYrN63xNCRA6kVUWP+2c86CTGX2GKHb4YgtULBrVRW8hUR - KoofPhcaEVIUvrnMrPDIrp25Uh4DRakUMQUwsOjfliLmm03/07IJziTMWTZkYQ== - =qR6M + hQIMAwDh3VI7VctTAQ/+J73641lle7VHi7015hM2tzDaDhtLfoPl7R7jz2dOSmFx + FXfzu0kHK6Mg44WC5pcWvIHWJA9D0bKlMO5pxPO9vrG6tNU6C24WuibaLYbYWQDV + 7Gxbgi1SPEhLZY4BOU4nObRqR7GfDyHMVASKzzO5Rp15t4vxKko5VyPYPkX96XrG + OHcxeHe6BYBKCE6beee2KPtVfWtWxuKmK57inzeSnCGNVAXI/6RX7GMcCa1Y865C + QWvSmO8h6rEvCtj6heNdj39p1Iz1MckqAepsaTw6hpU9yiLkkiGzimZaeOJjU2V7 + hOfqmawpPWwGic7pcKE1kcbv9e7ogtcIOd1up1fWNn9jZ3wErwUiFYfT2oKfqlFB + rkO5IrDy6zvfF8diKmHM7/NiXwUa6h32uHxnLv0AcK8nOKaCW4ZcWOwmbu7gcZIb + 3Kl9teuaJ5FEV/7giz3lf8Fd5ljyGOUE3t1TWjJxzI0ovBjFMy8l5DEWhoNejfqI + cB2AbQqXuuOvdMTC+qaftpE+XXiIHniwQ3IzkUzhUE5p//xF2pk8SZkQ2iDn7Bb0 + 10p8TD8aLM7AuHd0fpkZPxpAyHCrN++i4wjsv8qdq8obmZ/BzsY4eUJnvcLlfaER + zMUuoT2JhbSLaFRgxgGrm/ez022X4pFmF5ONbbTrAEMxwcmvp9xGwy/krV43qX2F + AgwDC9FRLmchgYQBD/9PgG+2n2k5sUCLh266s4cHKbpVZdOnJ2uSiImyCtW95H2T + Uy0EpafcYyxEs/Hzz73UKaGDz9TwP2cAEVjQ4YumvrKq38SthyFXUAsiI8skXkic + LSEgEWzD0hmvW167mg1PptQyiPsgfAOBw6X6QdOFWJ3nadf8+2AV55JvHuQ9SxC4 + ejOsrVCQL7rMhNTXP2TSfm+ZFM9U6Qbv/xSXKPRBiqEsN/DZXD8BXTUY7KBpazOI + Ttjapr7DcI1ptMK/AIG1eJQAOpgRSsy6z+INpGsvbUIaAJDn8XFEt7kSMXGmQxDJ + oGtwHH1oDXK+ws/F3bn1FPZZlBVbq7fpSoEBBqnAd2jrGibEWEZ2zRBDSROalqCS + fA72h/1ZRUfx8iFBRd6Mu2PJAQ/oecZV+dcIlTD7B3v30HyAZTtVC2Mtdmxqi03U + TFTfhaeCNlficx1R1VtgAABlAMBeGerb6AuBVf9vziRkXiWcP/9RdYuTEJskHjZb + VXCQbEKck0YQHOds6QTu/+QlLZUoZF1LXVKF1iy+khc16oKYhRBUL58eJTOpYbtE + PUrayC6PXE0tKg1Ghe/yVsW9rLWmu7FMdAvM44/PjyI66zAwzKEu6STVahIrpxje + qKd1jugtsmR5kNK5CsORvval1iA6/UhU9fGdV9Zz1t6eyrMNatWk9yOO6uIq3NJe + AVqzW1bH3U8Ys+C7M/FHBskdSPnwgvANKb5hswadBkkRGep01HIJK5QdUj0W9CQ8 + obHQ1j0Rlzs70r6cxpruM9ddmGqP0/yRGncXHowrnf0ZnTzZr+Dhs+whA0V3Zg== + =jCXG -----END PGP MESSAGE----- fp: 4BE7925262289B476DBBC17B76FD3810215AE097 unencrypted_suffix: _unencrypted diff --git a/secrets/repo/globals.nix.enc b/secrets/repo/globals.nix.enc index c95426f..bcead07 100644 --- a/secrets/repo/globals.nix.enc +++ b/secrets/repo/globals.nix.enc @@ -1,70 +1,62 @@ { - "data": "ENC[AES256_GCM,data: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,iv:O0b7UxLyCOGRu8N3dXjDtHuD/O6vHO3FWnsFT6LyjFU=,tag:qysiXpaiHGvhtjYwS8gjQA==,type:str]", + "data": "ENC[AES256_GCM,data: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,iv:Fep8PNrxh18J4n8gYLbmJ2+Jn7kD/4KCLs11GDDfshM=,tag:UwkE59mcIslEcrqNQ0qCTw==,type:str]", "sops": { "age": [ { "recipient": "age1s0vssf9fey2l456hucppzx2x58xep279nsdcglvkqm30sr9ht37s8rvpza", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1YWl2aUhsVUZXVGZHUnhm\nK1hSUVl3ZW1MeGZGWDR3cGNrS2E1WnBCY3drCkNKcWcrZHk1UVZuWkdDRGoxRnhP\nVE8vYzRSSUpOSmRsYUZRaXFDbWVXT28KLS0tIFVLSFRPd3hKTEdtMmkwRFBWdVZ5\nd0hyYXVmYmFubjdHN255b0d6c0F1RlUKHlNhWypoeqRe9wuF5jGh2omhGTvnTtt6\nWRWnEw1i3wa1HFJn8S81oppvGrjmnGYPgaXcHjb4OHxt+9RKQYro6A==\n-----END AGE ENCRYPTED FILE-----\n" - }, - { - "recipient": "age18cgqlely56hgmhscllkmafwpjdk6dwep6ej3vkk97dzemp8jtuksqrrjjl", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2WE9XZDZJV2tMeGhBanNH\nL2hLUVIwVk54OGFJSE1DMW5BMGk4aGYvTVZJCldKb000N1dFQVVxSFVoblpHSm5C\nM0dpUTREdlAvbkxaS2pLUXdtNjdYOEkKLS0tIHR6djdTMld6dTJSS3ZiRmpVZWtI\nWU1rT3hHWG5rdHU3eXJRTzlWcnV3RnMKI9jX76xcdENMjh4Be4gIzc0qedHUQtk+\nB7ORW+d2Wf9PdlTt3LZazjzw3xu8A+02IBsqwzJJjBIedDnRd/oUqA==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBaUxQZ2ExRmVJSWFnZFEv\nQ1A5VXNXZjZ6SHlLcnJtMWtSbTJyWm1CdFJFCnRBS3I5YUZkL2NyT2ZjL2M1ZmxT\nbWpoRHVCbVRwS2NqcHdOdkRQNkhzcXMKLS0tIFlzbERHVGJLL1hYczRBbllZaDc1\nVTF3dzM2TjlsY3pmV3ZDS3lGM2tsbE0KYOKd7D1jm5fgrdC/GFlZtxhnfsN5m0AB\n5gOWisPQYezayKs12Ver0t2reLV0vr63BY+mdi1qmTa4lMCzC1cqLw==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age1g7atkxdlt4ymeh7v7aa2yzr2hq2qkvzrc4r49ugttm3n582ymv9qrmpk8d", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBESU5DcG1XV3hwb3VmZHdk\nblg3cHYyVVJBWGcrb1lJVEdnNGFzWWtPWUY0CklOZHU2ZWNoYm9ESHhJakl3THQw\nMk1XS0N5K1d1MGdwaEZ2Y1gvZDJqNEUKLS0tIHFvUXVNWHNPZGpTUVBnWWhTampG\nc0tSTC8zUVBuQjN0VjlNRkswZVFJaGsKSZ99ix3CP3IQ0m0GYVML7fa3R0gD5N7z\na1xwlW7e1bSEwMAUyPy5+E0alvVdC1nP95LtDyyPMkSXuiNJLbV07A==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2WEMzWTMxSTdsUUVNYmNH\nRUkyQVpRWnQ3N3ZFN2dleVJNRmp3VENWaHpFClAxSGtqRi9GUUdwMWgrbzJLVkxW\nM3loNU1rNTFiUm1tMkpWQVV2b0RZZG8KLS0tIHNuRGtZMEdqaTh6VDMyZU5udm1G\nQUphdzNjU3NQTXBvQVpVeWczcFNtczgKjDN9tdNkTD1PES0CdB3aclsuQr58EGZC\n2dOpw8XOOZ6pCoPeaoLdZKv/prtSCdfwW4NKcKKWc9NRd79qg63WGw==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age1ly2endyt0y9xyddj6yuj4nw6fa3ltvzlvew4cr4lzs6dv8dkavpqadmyxx", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBVlA4WUszaWQ3OUc5RXBM\nU0VQWVVKeThtcU9SVTcvdi9VVGtGRDdqWTNzCkRZTXd1a045ZXZWUnFUaXUyNGFM\nU3lodFRtQjVudlFHVS9WMXFVbGo2bk0KLS0tIGVKZVZEQ0x1ZnI4cHhOK2k0elYz\ncFkwMWRHejQ1eURORnpaekNReUg5U1kKKghYvqmOysmJ12ZXjeUomoqc0O334Hcv\nnulvcj1NSwhVLKUZ4JalNrSNo/4xFcdyi7hn2d9DlkkU9KJ9OcWBOQ==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFcGg1L0w2czJCVit4bE9I\nRWs1UXBKREYwaGVNS2gxYUZTUnc4M1lXSVZZCjg0OGw2dk5BUjl0cFBBWjJwUkRU\nMmxYZWtqRWZKQnhVWHArTTJaVlpLV2MKLS0tIDZpWFRYSWF3TThSSEY4MEM0ZHg2\nNVVpSEpSS3d3YlloVHZYTHhhQkwva28KHcZko+q7mRJk+eDTSVyk3wYG8VLfnUJs\nH8uOoFaIwH5sf3K+1/LvUEGp7rEgbqHCTgRXrylNB2jQKq5bYkYlsw==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age15klj4t7gpfp69472mne4ue62pp6m4e04dmjyw7yf30qtqd3vl3uqjmcyxm", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaRmc4YlduNzlaK3VXQVFt\nRXdHckU2TlRLUHltSTRxV0Y0UnBJTkFwdm1BCktBWWIyMnZYZnFvWEFRaFd2d1Vs\nc2VVbkY3WlZhRXN4c1FJTnl5dFBTR2MKLS0tIGFKbmdPL200Y01mMzZObEFqZElq\nTkpVb3AvVWswdkNEUWR2V3dXMHpMZDAKFUAb6ZxAycB4PbjUgePEWmUpbWRomU+A\ntpFpU30ZeWSicsRQRbzm340ZmtAhVk0Ud1M2N3J0TcIpre3CghZ9lQ==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFOHRxVzI5RllzUzI4MnNC\nN1IrOFRGdTQ1VExBYUozNDNXUTNpa3dPUTJzCjFvaTRON3hJd09zOVprZjExLzMr\nYTNCWklKR1Q2UVUvNndNc1RyS0ZPazAKLS0tIFVuZ0dYOWxaMjFYajAwRSs2UzBv\nUDJGcHUxSmZCem1Sc3BmNFV5WXVWTUUKkiqZwgj6iCmAGW9VGRVU+wuRuauDaUjF\nVorMFhPjU/Ukb5PjaGzTH2LxsfW3Z3vH1S3iQM3xSRgRagW2ut3VHA==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age1k73gy5em3js9zklnnkzp5hme9k04lny32fgahmzddknjw5c295asdyr4x6", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5ZU1vVUMyOHBXTm5iNUZz\ndWI2TVZpQnhkdVc4aUlIWmpwbUtwRXlDTkFJCmY3bVZ2ZmlWVEJjVy9oeEN1b01k\nR3pTUUlFTG54c0dyWUlQQzN5TlJFL0kKLS0tIDZGTGlHL1FoWC96dUdJS1I0UkpX\nVWowM1dmVnhYcEJXaEQxTitPQmsrbkUK7R+HqB6ohYcS1rQDfIJ5lHHcqeYcpRTT\nT23fTqjGlDmVUzDUdUISZeaVtTsaAwtq14YWdi1UEzwbGBdUQGmb/g==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtdUlnZDlvaHVkN2ZDYVBq\nVWVSNXhHNVV5OGNUUm9RV0VsQ1pHNld5VUhZCkloaVBWc09jTnhLc0pqbzdmRW8z\nbnM4QXRnSXBoNDdvVGs2cVFYcWZ6cU0KLS0tIFZLUlIxVjBKdVBJaDBGMGVJT1ND\nVktFRHQzNnlZSE1BRW1wVFkzWlZ4NTQKo2CcfWKQ7wdiqfmaSokCCpf4CZnaeTBX\n/jb0saoV6Hp0n92mi/60eZIX95wWwGe4NAAisFFD+UQGWSCukm18Mw==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age1cmzh82q8k59yzceuuy2epmqu22g7m84gqvq056mhgehwpmvjadfsc3glc8", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxL2pFNG1JTzNQUzN3bDJI\nTi8wU0grcWhQcmp3SzZUYzdqZmc0TGsrNDNnCktwZTBYZEg1dnZsYXhPU3NtL05I\nWHZtQ1Q4YUdYay91RzJaQXVRWW51bTAKLS0tIHNDZ0UxWkRVQlE0L3JjaTZmZzJP\nQStKaGFISEJEVTdQSVdIOVMzNjdhWVUKbMH8jkFLlkvbl1e9mndT9civieCuH/z2\nweqBunzI9ANMqQvBH0HxWymUz6kc4Rg9HpChcLx5be2M1URl1VUTiw==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBja0dhd1VzMVBBcFBTd3dw\nYlN4QUlvREhtcnpLTjFQVGNQV244T2JnVlNzCnlwZXI2cWZhVUZpTzVveERaZ2R2\nR0Y3RVNrUnNMNDM4WlB0YWF2bWxzQUkKLS0tIGFEemp6emloejlneE42UEY4Qitm\nK3ZBdFlVM0dIM2wxWk5JZCtqTUhWVG8K/q+YNSZT+HsqYTdxyB2FrrVCpSywDhkf\n796xAJjeXRX4E2ETN2QvHQ6EGG2tZFkQzVcWGX1ozugi8ZZe1mJP1Q==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age1wmx8y2hs83j2u5srdnfxljrzxm8jtxl6fr0mq7xf2ldxyglpzf2qq89rpx", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJd21EYyszUU4xdnkxZVRT\neU5FMXVQcEFtM1VWcVBHK2lVOUdkaHk3aG5zCldkWWx5SHVzVWtKRE1LUUR6ZDRF\nc3Z6K0QyYWRiekh0R1pvSTR5UGpLR3cKLS0tIHhGWFppR3cwTEVTUUUwc2dsWUZz\nRVdETzJ2V25LUTU2a3AzWFFZUC9GTEUKrF9QLJEVxxMG0iJULun2QKmd1ATQUGlu\n8nnEWHOpuI+tZS4VM7bjs43fFsN/D1dwA4LFlVfYBNfH0EpVs/CjQw==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUMzdIVHRFbUFrLzlISVQw\nbG02Ukp5R1dlNVJaZmFpZmRSNVVpd1pDb0Q0CnVpL2JrMHRyOGF2bmVqRjNCc3cw\ncXZyNmxsZ2tFOHBjdGcvYnplcDVKKzgKLS0tIGoyNHI1bVdOcTR2MXhWZGhSTzI0\nSE1SdGVFRDVac3pLSE1TQ09BaE94aHMKMN9YNj4wbAdlR4VGoCPYVrEtQeFcFZh+\nWfhl5ra2R1yB+JNkxgf0jDKJUlEjlW/DKl/FOJ57g7lpNhPfUrMGkg==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age1mjgw3nxlnqdj04mgjz3wn7fj2nl2nxla4p2r2fn4nkvayfgp09pqllxzyh", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5anZvRXRFRDRoTFFlL2Rz\nYU1UMWlmZVgrMGpqNC9oK1VhQ3lDbUNRVW1rClJhNVp4NlczWEdWWUdDa3dqSUhn\nLzQ5TTJyZjFrOUtXTTdUSytBb1pCcVkKLS0tIHp5NCs3cCtlNnlFUHN0ZkdNaWVs\nM1hpVlI3ZTVFSUFsdFBVQnM1MlJOUzQKLjYXNFjBkCo/+Sy+/3gzWPXRhAxtvae7\nJGGNUk9AoTPM/VSiKEJL3F+X+z3QvoiMjq/+uLU2hKMlYOH570X1Rw==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZM1A1VVBKTE5IOXlqRk5T\nQ3RJOXkzdFpkUmIyRXdRL1ZsSjhiSGxldWpNClNJRC9sbGJ6SVlFVUdWcXI0WVhV\ncWJTckxteGhkRFFqZDNSL2lIMXJONXcKLS0tIHBkajc3dEFQZUNEQ0ErTXlTZUFr\nRUJ4SGNuTWJIQWNNMFlpc055Z1NxVk0KPt1CoTXsvKs+XytsIgkjqxM2fQLJmC10\nTS5PQ3NgZhy5rT7ejnQUQeb2KDS/uN6dCNrWHK6R/OLR3wKzzASuGw==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age16vzhcvz8tyxj8e0f47fy0z4p3dsg0ak4vl52ut3l07a0tz465cxslmhevl", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvcXVLanhqYVMxaTJ1NGx2\nNEFvdHRFWmxiS2dMUCs2S2N1OVV6N2IzRHhrCnB4TWZUQ1BqWHVTMVBFeDlSL0tU\nYmd4L29UV3ZVUGk3Snp3V3ZpYmlSdlEKLS0tIFVnYnY1WWJ2dHlWT2o3ZVV1aDlB\neXN5THRUNi9QR2pVUC9IclFBa2gwV1kKghCqpelZh84rvtwH7BjPWma4h+0axaUR\nntG9Bpoya3JzVFgyuae/ljmXf4WQvB+OBhh88GiHwXqX4SpH6udvrA==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3WnhRTjU4R1R1MFJPRTNi\nN09LM3dMdlJlQkN2WnBmQWJPQVg4OHl1M0dRCnhhZVkrNTF3NUVvYUFGN2tmSHRT\neC9yc2dOUzFkTEV2NkJubElhNm55MlUKLS0tIHJZRnBxRWdBbWVUOUdJVWdwY00y\nOCtqMk4ySjlTZ2UyeTZMRHJwcktPemMKdOZleZmklSOQTo4fnCzjm4fC/KReWTzn\nJaS6FzbAWc/SwNIs+c/UHfCAWTQkX5xma9uzLOdr0/3cuu00+k73dw==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age15cx90pnp54xp5gxlt02yn9j2pz968wp3l5ukdkx55xuecp34e5pszjku4m", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3NW1lRFFYZjFOUTFkQTF3\nTWpqdGx1Y0lncjFxemNJNmpqN240VjJtWFN3CkhGdnNOVGF4aGdlL3k0RThOaWN3\nU1gvdUQxY2k2YXg3VTFwVTlFdWRSYUEKLS0tIHQyOVJOcjZselNtM2ZRWjZpQlJm\nZ3ozRjdmeWtHNWpESXpCZ3VtK1Nrc28KM0Hjz2wjsefnqAXqcqhE/kCJVXR5r4CD\n4VnG1bl4MV5dcaWooG9RBTgU1eSnoa1CQeH1SBS18ueA6/kRF+RuYg==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEWWNOdjJPNzQvRFdRc2xL\nT1FHM2tpV0tDSUFJdVJyTXk3cXZKWm5Cd1NFCi94dEVOT1NyRDhlSHZGRVpmMkZS\naWJLdzJMaGkzTnFicG8yRmJCdzltR3cKLS0tIEg2ZGU0SWFTQkR6aUdzc01VOEtS\nckhkM09FWnBqdkNVZng0ekVvWHdFNW8K+dutcLgF/Oq35B33/vxAiePxCLlcvC6H\nH/doZRDyor+93hWpC0nXJxJiPu3Pc0oYznDK/gRWYTnynBu2GP0adw==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age18quey88vge7xytclg2nuq4ncme86dg04lxwczqxczmdchnjg3p0saehsnh", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLNHJtSGhZTkR3ZG4wY2NE\nRHozK2cxR3pkZUl5TXREVFRma2ZJN3kzdmo0ClVLb0xXZ1pLVGJ6eGlsWmI1QzNo\nWnRNMTd5N2NYY29wQlZNOUtvMHRVNEUKLS0tIGU4QU9Fd2Y3aEJYT2JvMFdhRFpj\nRmRqRno4RVMzQ1ZzRDRMVDdFQXpiMEEK2QJ0gKd3QOKIVWYfFMbDCwmhPyBuFXG0\niqyCcJIyut/XzoqMTIuyyNWk+74ABdwj+vFPuq0nxnJUwiwnDrT+lw==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzdGp0dkxpNDJpSHcvRURV\nMmQxcHJiWHhhNWlkd01lMVpCZ0greUZoeUQ4Cm9iQ1NUSHVIN012Vy9lWmpRdzJ5\nNmFwT0lxYWJyNHFDRlhEbEJDOGFYZTgKLS0tIEJGUXM4dlMwRGhoNW5JRGpSZElC\nK1kyb0V4MHBaNFRGZGg1dk12MFNrNGsKKMAWhhYHwWe+wXweyZNOldNKZbN93n4A\ntgNSFIpgCXYHLEryxby1nOZfyUVFNrCFdgN3DQQNy9KzUrCBuVb/tQ==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age1ax5hqk6e2ekgfx5u7pl8ayc3vvhrehyvtvf07llaxhs5azpnny0qpltrns", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBSTVmQUJ4THA1Ui8yMGxM\nN1dlbUJYSGxycy9WUTE2eSttSVYvR0RIL1VRCmpKbHBFcVBld2lKb1lqdFE0TkJ6\nS1ZCM1BYS0RLNUwzcEcwM01aOVV5V1UKLS0tIE9BNitEelVidDdzZE9QbE1Qb2hk\nWVY2emx0Q3BLbkNhdWJEYys0a2ZyZnMKqGe5ckj9cK1LnbtrOfPJPdhJCIBm2lOt\naq8nl+REJ0xFR2Pl4SMhIbqDgo5oV349OYQfRUBMhVE9XUUa5TsEAg==\n-----END AGE ENCRYPTED FILE-----\n" - }, - { - "recipient": "age1c2enwel9un28dcs4wg0vcyamx9a4a6g3walkhu8w5lqhmd804paq9d24as", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwS2paRXpLVk5yQzV3Zjly\nYkd5Q3NTU2xCaUlvZFpPQVVxUm5BZldpWXlNCmd2QzVFR0NuZjgxb0R5VDFmNHhN\nQnFhRWs3NVhBY2dlOUhmMmZYVytaOGsKLS0tIDUyTi9BK3l3RGhLWWxJbVZNZUV5\nWS9pTUdsUTJ6YklRNWhWbG9KVllZSTQKUsrU53r2xbnheBj9aEc2V2ZwKICFsU+5\nVXxUdwwmb6WTE53kK/yV0zsrWTDocb2/4e7qBUqnMb9Wgk2VHvhe4g==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvbTFqR3RScWxnTFR3dlhv\nNUNEVGRkUDB4L3J6ckJIMWZCWk44RjdpVmxRCkhzZTBuSGduanBmQWsvNW5XMWQv\nYVZmNS9FVzN3a05kUVBheDljYUUrcHcKLS0tIGxPN1dWVkg4NUpnZGJ6VWFJWFVZ\nYnNvRG94MmFxYnlDQ0JyeDNFQldzdlkKsp+nYSR6Lxq8b3/dpMO7uTbNnO0Bva7w\nb9s908PLaZEN1jywEoba3yq743vuEHCKQWFIfDtsRcbNR6Yr4d2eGw==\n-----END AGE ENCRYPTED FILE-----\n" } ], - "lastmodified": "2026-01-03T23:44:12Z", - "mac": "ENC[AES256_GCM,data:7+fRKPv0JkwHiWZOvPsp+gYHaDN2Dfdrm9cWLY378cA9xqcLpim1TvxeG3UaQQuFV6KSBiU7jBlZSOUUToXSG9mBL/pcLsErBsnqg1Wph7mK0JLzKUxPXJQIlRzZh0KmG1GCSHGQBqVQjVgyw4qUfmUdq4QZ5k5tWcQK3yCpuQA=,iv:1Sb3CkP9ad26vQjCpRLv1wXFtEHZL01EObPzstwY4C4=,tag:k1EC+zR/j/HZ1sejHFXv9A==,type:str]", + "lastmodified": "2025-12-24T23:33:32Z", + "mac": "ENC[AES256_GCM,data:mrwZUGeMtgAqSd2v387rGaf0bHZDC1IjIUlFPzB3Tj7CHE9Li4vAp7f9Bvd6v62eNcuwrnW8UoXju63fdDLK7l3EczdWsA/EJrvxIr29x+NByzfbUtShexg24mwsN7HMBnhyvil1CF4PMN4EmxxOn05cXOsAqln38IEPY6n6+SM=,iv:7PeUcjVA5u1KXsBZv+UrVQaCqEjXqY6wnELDEeHyQ9c=,tag:A+bETVg1tlHZlAm0rJ9Z8A==,type:str]", "pgp": [ { - "created_at": "2026-01-02T21:17:44Z", - "enc": "-----BEGIN PGP MESSAGE-----\n\nhQIMAwDh3VI7VctTAQ/9H7LfgDWyE3F7SrLQaGdx8rNwWy8olBcJC2O7C8usiBUH\nCqKNUUAfXaOqsNoZahWES2KNyTZgARGW/7lsQU3ISrYD/gxn45Pf8HyVXag2qbKQ\nSmYii8HXvrST+XHU7aErAZb293ByBSBvlg9JfQK8lNTKccvIKLLHTI8Xo/EkjUtl\nvfRocIPzesBnOBxTwvuWvnI+nvcuvael3UoKK9V9HaFBrS3i9U/z2EROaBOY+LI8\nCNgSaUNEGqeYh7/g3hSMzLWicM+3YS5MnlVDJIaERz08XvjgAfnqlmZPINZGCKpg\nUY2fBJKkG2lUsx4dfs2XcoIayygA9IIN4kPztI8jDL+KTh2he2iyfDEzTGqZ+Yfr\nbWzoUNxtCT5FluVYLsAUYBJB2TZhQJeNHpV+dOLzs0zTRbzh0f6dQQEs6u1W4ZVe\nRN8UwO+e35Bcn5sJ48y6143BCaJGsNwKg8wqmhOejUV6F8di9nHWasXgaxZKPbnz\nxIyt8E+PvWIYYQHadUQ0SIL5TMWU4csyoDvRbpQxYPVMl/Fi6v1khW7Dw3thhOPD\nXAygAQ3SDr2bzB4ZlWAozx9D4b2jgPk1qMHMHmypf4vdTqxKVs9UhzLRLK4IYDKB\n91drnFsAPhOzgx24CPEZANZEln/IlRmIFPReVCT+8sAvqDU+1CROSvR+OLqwfPyF\nAgwDC9FRLmchgYQBD/0dgT3VStJ6BJH29XYsfQsQcHSGgYan3Ecy6g02d3h4Md1r\npJN4s2THrlHe4LVLIyZ5xdetrxSvU6uz5TM2jAXL6cYLEFyr7FqrHNWHDXcbEiE4\nRgtVxV0P0c69skkVnBSObvc9drD/m7jbAy/9dsTs/1Xij1eAgvHlcItadAQVKCYO\nd7E5jFJfVmtQQ0VWqC6Y1i4tb1J/UKRGUG0T2oP9RkXPdCctVMr8J5DwNIw87p2Y\n2GF87yDM/D7mo6Gk00aeOYFPej9qTQHNo0e1xCw30cGOqlGQpcr+3Fc6hdt+ww8e\nPHVbR7ZA/OifnbBk+Wi1qqIlO4+FdxTHpOK8lZP1A/B2XtJsrmWGLPTHHw2iiIR4\nahPpsBtxOyGZXB9Qr/kTX+uNUQOtFXVbxi0AgnQ3W+UkJlpSd5BhxeeN/IqC0Xsd\nvzhv8A8evy6dEwa4eoDPdECBfHfcXQX7Cin4WFef1Vr/6r/mL4OvY+yeMRmZ0J+O\naEPeP5zX3u9YBZyjay3daLCTS2Jqoh55Vp1e94Hzi2CpZexj+tvph92CHAf0yJz/\nIbJfO1VXSMBnpRDzzM+lSGEv3RNk5OXre09j3kThuscGqXKH4+48qbhYBLr9TkCB\nVwxwYijDEAst0XOky+RXZxtR1muAi/hA07H1jZK0lMJYv26T3SL3pDSheMrxGtJe\nATYtKOMookgjDuzsQAthoIL+bV3Lx5yFJjF+phwL5vqTLWa0xj2IBUSnmXnUgCa7\niRLsMPrLG7qvX34Mr7HrOFRXWQjy8SdmU7PHgUyBAyK8I0JFl+mzF8x+fbRYow==\n=gdhs\n-----END PGP MESSAGE-----", + "created_at": "2025-12-15T21:53:38Z", + "enc": "-----BEGIN PGP MESSAGE-----\n\nhQIMAwDh3VI7VctTAQ/8CWW8rCTmkuQS8SdFyDVBOu1xj4lQZn8hUVDVBfExU7EB\n3c+cO8DmvVBMCzwiwD4dgkektoQ6UqInEL/beYKc4MPUUZaXLHDXysbL5Z1iAHBZ\nFPsxgE7BmPManamCewqrcBYFeHTGVzSeU6FqZDkpNkzAkjyktq4Lj16U6JTzJhjV\nw+IiU7Lg+MBym7POPYqqq8EVGtNKWNPA3T9i+bYXirwPjyNbRjxghe76I8O4zWsQ\n5vnQZhkkwCaavBusNdg0Dffl7UkFDhFCjXB/Jgfwsb2JpTxjvWgBwsfb2qT7EnPA\nOvdi+wM3nyhvQM1yMhAoAXTjlJRr/coEw48LhvcX+u+TUr1nyrTktEzcuEFVW3z8\nq+TCLT9c87GonIJOIoGaE3oUHiyVtsYeMGBpIVAW2H9eA61LtOIj0/NtO8YDGdAr\nnO2G+LxEIr1ZEstNmKaiJKkrfmgYG2fl3zu0bZS4Sm9xuwOsLvGxc6e5Bd6Q9Aw8\nOllbWoeF23j5NLwi2JXDJ8zUxby+u/Q5AmxoyuFsCgMzKQG6F7VCkDoVx5gyetMl\nQNfrjElPOv0e0wVtHzf7wqkey1ulI25P6FD4ZoCaLYLU31eTA6d1vRCX0GxWs0Tf\nDiXZIVRvONk/2naH5rN6Qz7fT+Ub5g1ZhRB0Z9NK60GXnYZhQ6FnuRyWpv5eeRyF\nAgwDC9FRLmchgYQBD/wIIRbPDxsE1uJh1/PXlRPGu9G6WBl3FuiuqbimzHFKDApZ\nzw4qVwiZeVYmxOC3ZokA23Oe+hIDSgjIeVt94XvuentxmblOwEL+Mr6qpwQEPYvE\nh9nBgGWpwJzVfZcrtwVIoJcv9NmkYPMspKj3cgCCYZmbr3PbwNaaAmfn0h/FjGcS\n0pjEGlJAr6wODsxZBJ7mim8LOzXj2Ep+5ivqT2GwuIAeR6ahabClanMzoq/ayHKk\nAtUKBja+UZwRKFh0GSir9jmICDNrrQIqTE0d0MFQicSnjrHus+mHF1hMJkm6Zw35\nypm9zEbnSnVx0DFifSTth/69h63i7H3+CW7EqkfZ/zWpmPa2D6wg+SmhLnsWpclz\nJPDQOwiiBgFloJ+4BDM3vscI8KHhWcrRTuwD8RwUB/5BLw1WWfQ+6yOK9lWDtvaL\ntibk/iYz+fM6y8VQEHwF1S1EcdHW8VlcE/xPTS4xOukShbJmMSW+0Srhm5swRa9q\nty+txwUcU3w+IiLpxp34GoaxK3qz3OWpF5yAG6dMqZ5q/6u9PcuDuMVkMW26gj31\nxryWCoemlrp6DW3Gfmp6EeyVUNVbiJdXmU4jnCjWViQei3AtQ062yES8b/HDUyFg\nVmPfcTN0hpWPBxQGWGDTvDC/LzK9DeHLVUGhCoUlvBwS/zDbgAoo7xmUe7IqkdJe\nAT0zalGWoZdsebqWwp0txgrsgn17VzILFHgvmgU7NgjN8cTwiQ5odqAEfkzZQ/nx\niEfVFYe8fmzQVrCcDsCcxGBOavPTFQG5HbY5ssDSur3QfqKW7PgkPztPl2IkDA==\n=r685\n-----END PGP MESSAGE-----", "fp": "4BE7925262289B476DBBC17B76FD3810215AE097" } ], diff --git a/secrets/repo/pii.nix.enc b/secrets/repo/pii.nix.enc index c54f933..4cd6a2a 100644 --- a/secrets/repo/pii.nix.enc +++ b/secrets/repo/pii.nix.enc @@ -1,70 +1,62 @@ { - "data": "ENC[AES256_GCM,data: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,iv:CHxvIxUy9RNlieC17BWfSKFqz7wHvC9epHnBnaHZFyI=,tag:TSxK0lMVpDTo768ZWbJy9g==,type:str]", + "data": "ENC[AES256_GCM,data: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,iv:4ZbxVxZHzxn2eSqP8h8eV53IV9J0avHBg1R6/TgAmtY=,tag:SqndgxyiwbD89LSrZBMnuQ==,type:str]", "sops": { "age": [ { "recipient": "age1s0vssf9fey2l456hucppzx2x58xep279nsdcglvkqm30sr9ht37s8rvpza", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOU3VqNFJpVEFBN2lwWlNS\naExNbUpMMWQ2Zm5kWklxR0dMOUZUVWNhYWxrClFBRkVFUkhaSVlTamxhRTc5d09H\nWW9wVzdxTkZjME5pbVVmUnBXakpaK0EKLS0tIHFIY2JwTDB2REdqWHRSQkFoaGE2\nN3FWbCtpUm1SSFg0b3BEN1ZwUEhINzAKFjA6KD3PK7BZRYkHLSs58ffMHrCwhvy/\nrF0zA2UKhIBN1LvYlyDdO2yZSOCK+0iwEuvz++VhDm1UnR0hDNu8Tw==\n-----END AGE ENCRYPTED FILE-----\n" - }, - { - "recipient": "age18cgqlely56hgmhscllkmafwpjdk6dwep6ej3vkk97dzemp8jtuksqrrjjl", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoa2F5ejliVW80blE4NUwy\nTUdCamtkZ1hPMk9hQ1I0d3hYV2o2R0p5NVNBCmQ5WGZLS0ZnYzRUTk5rc0JKbEQ2\nTEM4V1hNdEhzWFFJbWNuSUpVN3ZTT0UKLS0tIEU0TGlNYVJZV1dCQkRHM0phYmRH\nUVg1bi9IQllUQWpkYTA1bGRyMWVIRVEKPiZdGYR0bxk2ldQ/4Ce1RcXyZACcCjD3\n6oDBe1DT7mPHN1jPertICLYW8Q5/LBRX63AJxZIi+epZMGszI4m48Q==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzTXhjVDNLUW5sT2ZsbXhx\nRENRREhqeVp0KzBIVUE0RGo4eW5HZ3dRV2pNClY2N01ac2VscjRiOUdtNVBnSFg4\neFdSekl2UlZZekVFMXdVRVBnbXI4TGcKLS0tIG84RXQ3bXVxTmxXQm54akhxNG9I\nSzZxejlwMjVVRkFVOEFKYWJ4RFNOQVkKwUtbMRKa0CJYCa4TzHwMisw/mBCGroZn\nGnK489S1W833OkLtLApjsFowpoHpaizPMcrASTTkc7h+OtQ3yJlMig==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age1g7atkxdlt4ymeh7v7aa2yzr2hq2qkvzrc4r49ugttm3n582ymv9qrmpk8d", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1T29EeXY5cDA1em1oWjhn\nYXRuci83ekU2d21ZMFc1R2tPT3c5RHNXazFNCmFYVWNwYXk2Q1pTQW1pVWpPNkV3\nb0UwSk9BVUJMMTFKV0xxQUgrNVNmYUkKLS0tIDNpcW55MTF6a29nd1d4WHEwNTZh\nWDBNcHF4S1hwVzFTaTVycHUyMnNFaHMKCJDevUKtn46qMNpNjTIctBVMCLs5lH5Z\nfU2rzvwIBxwn16NCOAInRxQEOASYITYo7FKuMD7W+3eQf0vAj22LRQ==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzcGFhUWMzdlpQZnpxejBK\nUzFKcXFsRHIwdUJQdmEraDVJNGJuQ3RqUFZrCkZNVDNIZE9XSkxXV2UvaFB0cmQz\nUSsvUi9VRm5VSVN0NklqOHZhdkZySjgKLS0tIGFYREFxOXJrOFBCa1pua3oyVE9r\nS0l5QThvZXkwZ1Q5dytjNG4yaklpbHMKLVslGe5lj+ED2496KEcb8ccWW5YqF1qG\nSJGwZf6xRl8cLsbCE8qfC9zlZ9DDc63U1bgLGgqkEvYnmZ76BX6GXQ==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age1ly2endyt0y9xyddj6yuj4nw6fa3ltvzlvew4cr4lzs6dv8dkavpqadmyxx", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlZUhxUDdETlZCRnNJbldO\nU0NiV0hRVmtNYW5TWjdvOThyS1RSaExaWmdzCjJ3S1lXVmlFMjIyUEdad2xDWmlM\neFJOSnJSc2ZIMEJuK2NLVmdXSzRvcG8KLS0tIHlmZTNra0pzVVA5QThhN1ZaY0lO\naTN2S0VSTVgwSzBVZEN0em53STE3Q2sKlaQp9T/T7ZRY8FLB7yksMOwIfRWs/s7G\nPk3JnpuptFehhI/FeYAh+0fznBuTCKjqXF9X96a6RIFIC44/nKlfxQ==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnWE81MW9LQllDQTZ0OGh5\nRDdCK0RNMERJTFQ0RlpWYjV4RkU4ci9waWhzCkx2MEh5UmkrdUVWUmxGN3J6c0RQ\nYWpUdGE3T2dWNmMzV2x4MENYYmgwZkkKLS0tIGlra0RtYlhydHJCeUxFekZLdTcv\nbk1wOGszc2xQcVhUM2ZzNDBqQ1NzQ0UKftq1Kcxi+GHGf5SNswuprffd2SA6kKKl\nH+I/btSl+Sl9GTmTu3HTkAg4+Bux6uJtBAGqWyTOfRWV79Z5bQBNwg==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age15klj4t7gpfp69472mne4ue62pp6m4e04dmjyw7yf30qtqd3vl3uqjmcyxm", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzdVo5cUswRm1yS1BWU20v\nN1RlMkRXR1dhcFQwdXZhUVNWbkVrb2RrVmxFClZVVDJ1ektCT3NmYlk1WTBXVGUy\nWllkOTdlZ24wMHdKSmUzdmFMd0F6SEkKLS0tIGd3WGdueEpWTkNxQnZrbXdXTzhB\ncXVrNk43NlA2OWE1cnpqWmJKVktsNFkKwyaRDz53nk8nljSnqN+CXY7J1f2LmJls\nXfbOZfFH7Ayoelv0OCoWCm1ZfD5QLnTBoCZGCUw21r8YuXzu5+maoA==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0alBqQjFTa1FHOEU3VkZu\nMjc1R2diZzJyNHNLTi9MU1czdy9EVHpGR1F3CmdUanRteFRPL0R6Rk83U0diQk1F\nTVJXWHBMbWE4R3pob1pMdGtoV3NMWDgKLS0tIEZYZ3cwRFRJdERUeHYrQit4WGl6\nSTd2cmNHNkFHSy9DVjF5bWp2SVBTd1UKwx/D3B8UWQHcifsOxCDkpFsi4KVG82t+\n+8Yw1X4ls8h76Xvgvx9F0QbmCw7DXX4cP1xYlqIQBf0N+vMo9shBtg==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age1k73gy5em3js9zklnnkzp5hme9k04lny32fgahmzddknjw5c295asdyr4x6", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0dkI2RXR4aDlSaGhxQS9j\naXlXdjdscjJqQVQzblNQdkJxaWpSZG5DaGdFCmcwK0JKVHJZaDNzU1FlR21FUkd0\neW5nWHFhTDZNTnJzZFI1SEdTOExwN1UKLS0tIEhaclEvbXllRG5EWFBYQVoxMXBZ\nSXltdFM1a3Y5bFREVzhBRm1YS0orMHcKUrHg6YkMF20G+GdLI0J1pj1zLe06Xn3Q\nWwxgB6ctI8D1qs+0GMoXB7sOsfczgYtVt1hC6EvYpmiHW+g54GGRHA==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvT0d6Z2dtbm9vN0RweHVS\ncWhDb3VMWEFmQ3pGbVJzYU1hM1dJK3d5V0Q0ClBrVG43ZHhWQTZPVHY1MVRDb3F2\naE9lMzdWM28yT0ZLZWZielduM3pzZE0KLS0tIG84eWpZNktCTExSL2tNclVJMmhi\nVDV1MHp2VWpUNmZDbDEzaXhkVUQ5TzgK7Tdlsyya9kRwIc6oG3FBywJ9SWAvvKy0\nfYkW/m8pE9y9mPj62rqnAt4yS/GrSvKk1za8PkB1P5ehOWtxHeo79A==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age1cmzh82q8k59yzceuuy2epmqu22g7m84gqvq056mhgehwpmvjadfsc3glc8", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlU1NCRFRYUVkwZ1VMTVlx\nVStFYlBaY3NGTThpS1NYMnVSdzVCU29NV0NVCmdKU0dPM2lySStVOENZajVRU21C\ndmJHVkhqNWFpbEpqOXdxd1kydjNFTXcKLS0tIFI1QWdmSVRHaG8zV29MSFJhRWU5\nREt1THJJR0RrK2ZzWlAzQ3dobjVOM1EK9sczJcZo9sW/rlKczTo3PYRmgm+mJ/ek\nyRniR+IaC+cdiSIuDS6nz6XwGqIrTpBjizpq3a5uWTzwzscU+uMuig==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNM3R6VUxMczBwTGY3UUl0\nR21taWdlc1dpUnhOY1o0OFF5ZFp5TjNMQzNzCkNsbkN3SSt1TVFsMVgvS1FGaVZF\nMzlkdjkzbGVhR25HZmZZSThSUktUVVEKLS0tIGR4bzZRR1B6WVM2dHpkbTBNaEsw\nZkdYV2dnbmptb1pZeWJuVXRROXhzbjQKzranKLFffOHVcIhPq7oHn/KWGIIH+P8n\nBJAx54HVYVxWUH4XifkgDmYNsGrENOAO3RR3NZ5NlUG0FcTD5zP4Kg==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age1wmx8y2hs83j2u5srdnfxljrzxm8jtxl6fr0mq7xf2ldxyglpzf2qq89rpx", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4L0VvQXk5bWNVc2FUTk83\ndGp2KzdrclF3bW4yQlV4emdCQkIvTmV3WER3CitTOVZVWmp6Um5NVEs0aGg2TFhF\nRWtueVluSUMySVBjYVFmaHlYM1ZhalkKLS0tIDl5ZlZ6bEpIZW0wQ0phbnAwbThV\nVHZ6R1lCZE52alJGS1ZVMDljQzZ0TTAKptXEII9sr9zkdAXJLLCKVd3E3pOsgnIB\nLNqoJfg336E2aquo6LCjtBA0nSBxHkAnw0FFz81Kph7zK+Z1+tFB7A==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArMkI4VmRqc1paVG9lTFVF\nQ2t1UnhmUElkSy9rdUxUMFpDaHVQQWxFWUNZCm5Rcm53MDFNcnRTaFRxZW15STJ1\nZnErWTN5b1Q5ZzRGdGRBYS8wbWt0OUEKLS0tIHZ5TFo1RUhLU2V6Tk9tTEJSZFhY\nUTVxbGNWVmpQQVIzU1l3REh3WHpGR00KgJibUNT/pdv+Zf5EJaGEuiJTBYq8lyLz\nsjOLWTw9iNXA2bIPhk3PDGyttjcW2RrbPSU4cuN/O7w+ZMw//HWhYQ==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age1mjgw3nxlnqdj04mgjz3wn7fj2nl2nxla4p2r2fn4nkvayfgp09pqllxzyh", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBcEZVc1RpbC9vck5zYmh5\neWxObTlpMjlpUFZYWExCUDhQU1BHS3EvL1IwCk5xelVyRisyZUVLK3ZueUdRTmxI\nWlhZSlJQT1RSZXNZNWlxRFJpenhvb2MKLS0tIGlxeWl4VnFXQ1VVMXNmM2x2WXI4\nejd6djF5d1k1cm1Kd1JuNVBiWnI5TEEKnjIih/AMCQOakcmiEpG4Fqa+yYDafML/\nSepnQsojq99JF6oxtGAa1P6ibmAIglRtyo5ypRRTVMm6LWt8Nul1yA==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4WndZWUVMdEU0NGlBTk4x\nOVB3MjFvRjJqekgrM1BTN1NIL0tYWlRlOUZFCkZ4emtCZ2R2Njc5K1RseTF2TUxY\nL2FQK2VPN1Z3UXZiM2Zxb2lBOU1CSVEKLS0tIGtET282RDhYNVlOQXZ1SStrMWNJ\nS2E3ZlRPcEJQL3l0Ry8vMDIzUFFiYU0KqjPaREHI1rP25hH0Gd6rTMgMjy1NId/m\nCC12d6R28kVq1rGNO0mJw+FJ+Eu972Q87Nte/zz6ndcQmfAmXbfxsA==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age16vzhcvz8tyxj8e0f47fy0z4p3dsg0ak4vl52ut3l07a0tz465cxslmhevl", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1ZXpKOHRwWVByVXpUdHBS\nTEJ6dUJJSUQrSzc3MHZ0WHV6ZnM0dzlwTURFCjlxLzVDTDZhbGVpL3pQay9Md2lh\nTStxem5adyt0TVBjRnhsNmR0NnhLek0KLS0tIFhlWkQrKzFHall6Z0JXWEVMY0tT\nR040ZnhzTWFVbnlXdktVWnNuY00yU3cKmNYw+zRsH+KvxPW5o+fSKPKAVbxiVIoJ\nLZNXdAr6NGYMgKmvhq68M0C0mbLmmo505qb/oBntbfoGZJtSULAUnQ==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNRU5Nc2E5ZWhZZlU3OW5N\nMU91TGttdXp5RERlNlNmcHkyejdsb3JXMTA0ClJKTll3RjhrcGJyLy81c0pkYzhV\nYUhnTEY1dm9wTUlzTkE5cGF2alFrTFUKLS0tIDJtbDROS3V4Wm4wZXNzRnkrWk51\ncW5MbVNFSEROTlpOUFJFTE9BUXlJYWsKZiGBXaFa0mtbFoIG8pTjVgSSms22C5R+\n8EQ4k0fffsX2Ua4RL1DLiUxyNc9ck07E8hbp3L2lHRYBr/3sqtcSUQ==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age15cx90pnp54xp5gxlt02yn9j2pz968wp3l5ukdkx55xuecp34e5pszjku4m", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJeUVRU2hGM1RxS0d0Ykw2\nazc1MWd1ZEZweU9PRFRPRG1BblZTakx3WUdjCmlyZitaZGVwZHRZWnRrOGdSazMw\na25McWhRZ053Y2lRNmdMc04rNGkyTWMKLS0tIGtXRkZWVHdmRTNYcG9xZThZY1VY\nZ0gwQlptSHRzOUVCS3QrNkQ3aG9YelEKt+43DmQ0Zn1x7NIWl57eGxG3gsALxhMv\nImpMryrccmEV3Ddc2LPpxIaRYnFBJhTKDNOyuSOSD+I471PJlOu9yg==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRRkV1eVNGdGozRTNpWEpP\nTit5Zko3bEZWUStxc0lESWhTSGgvRGRtbUh3Ck9ra1ZoUHd2dEs1NGtiU2l1Wm9r\nMHprYkpQd3NLMk1ESmROemFyUjk2azAKLS0tIFlLeGZBUms2ZDQwK3dlWFh1N244\nVHR3TDNVcVhidWxPOVNNTUZiNHdUYjQKpNrP38lrlmazwR4MELuJphY5Ci7ZIqx6\nqefmDlF1yVyxIwoALq+Rl5yOrwYWr0CFXZxYeqfvgdQ22E5+AyzDoA==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age18quey88vge7xytclg2nuq4ncme86dg04lxwczqxczmdchnjg3p0saehsnh", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3emtuVmF1c1hnZFNtcFkz\neVlnbW4xKzJIVE10Y0NtWWZLMXRQNkI2L1JNCjhpb0dmQU5pa0VOZnNaejZSa01I\nRldSSUxOKy8zekpCQVZtUTFMOGptZ2MKLS0tIDJIWDk0OWc0TThTTDJvdkF4RnFn\nZFowbEppZFdBc21SNWlFQVo1bE44ejQK2YVQILlu2yxCkTdwAP7J25NOgSHeNgJj\nOCrH1TU7mjp6dlB/hxeUWDRCbmqHs9ko054ZdXrxY+9BeodA02B1bg==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4ME5PVjJCZ2FWUWtHUm9p\ndUc2UXg5RmhZNGo3YUR6WjQ4WjNaVnZHVlZrClZVb2NZYzVEOUpjdENIV1VDSUVs\nU1JvRzN4dTRXenh4RkNQY1VObGpHZWMKLS0tIG9hUHlaWjVUajVmMzFUQWFnUVpP\nVmxaNFRHWHJyYjFmSG16ZnJIdkNkb2sKlpc81NiI9AolycNrGaiLDYUvRrCbsMUe\nlUxLdCKo70CEnXTdLr2emhcxNwcSMljDPekMiPWcIFt9ScA639pFsQ==\n-----END AGE ENCRYPTED FILE-----\n" }, { "recipient": "age1ax5hqk6e2ekgfx5u7pl8ayc3vvhrehyvtvf07llaxhs5azpnny0qpltrns", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1NXlqMHAzUUZtbDl4Nnc5\nNmxISjVNUFJsNHlSUDl3U2RpWUV1b2phb0RVCkowVitwa2ViaEpFZUVIMG1LK0ZL\nVG1FU2tUdUFhNzRTeGI4bnNoc3ZuQ1UKLS0tIHZ3amttT0VkbkVuTG9yWkFQcEJN\nc0VqQ2RKb3k1Q0pkV0RjZEg4YTM5dG8KkUaAqAlF5hPuENwYWjVXFETePjtW7w25\nUUHOYmr+3j77FuT44TKYlmN4PJNAabbkDAcXDhBvtN4Ja41SGucy4A==\n-----END AGE ENCRYPTED FILE-----\n" - }, - { - "recipient": "age1c2enwel9un28dcs4wg0vcyamx9a4a6g3walkhu8w5lqhmd804paq9d24as", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3dGRuaW5XTFdPYlZMNkN4\najZRc1BNWUs1TExCdTAzTCs0RGpDM1lPMXhBCkxac2NmY1lpZmsvbzA4cEF4ekt0\nb3IvQTNrbk03ZWFKREhPZnp3OW5pNDAKLS0tIDdYYWR6NEIrOUtoYWxZdEJDWmdm\nT25XdkYvL2tXOEtFR1U1WlE4RjVGcHMKZ5MM7iTvGFi34ZoTNg65FHrJKa8SONcT\nCjdgJIcU/7wFbgTm295vvjfrXw54+pKUT3u9NqmPGVkA0o1rsBbZoQ==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGNi96SEpTVU1wa29DeDdw\nYm1weGNFVU1kdEdZMmRZTEJCeWliTm5mVGhrCkZhbmZzTGZoVHRmVTE0ZFcvMno2\nUkhVNFU5RGdOS1dEN3pZeGtBbHlhTW8KLS0tIEcwQk1LN1dydEpjSjlna3BwYlBZ\nZjNwdU5leHhJWTZqRElGZERVbFg0SkkKR5LI86bCwuWnzzF/+sYgnsEdHSCMYwr7\nhEaK43fFnD1zUKve/D8NmscJO0VAZIt7duzdeMLv7h+a2ebSXAJ7fA==\n-----END AGE ENCRYPTED FILE-----\n" } ], - "lastmodified": "2026-01-02T22:08:10Z", - "mac": "ENC[AES256_GCM,data:dwn1YbVF8pXOItkLrdPHIXN3ZoXsCuoCcCuv9Cz9UQBKaIISS7xDpwVLbpf2DMxPmpzjq7cbJHTe714Zi7uN9t80wN91Kt1YKIsr14kOAuJkoCZPh35Sanqo0tL347C24E3PrpvB26RWGPqA6CrKp13swDPpljMrdhz9GO5bzo8=,iv:NiEV6uQXthBauTe6otoPxaoPNsaEKQ0JlzZNYna8eg4=,tag:mUc+AUMoDADysZCSin5XQA==,type:str]", + "lastmodified": "2025-12-24T13:04:51Z", + "mac": "ENC[AES256_GCM,data:ktWaSwQTDR1bu9ztdt/KzvItcPxxCzhjAUqBKipe0SUZjxqmjGpQDBD1+p6dH6vSQEdcHDk9vaSMUZOMbOQYrQiEEqL+DLhAtRnc7zf8Mcd03uWjXm/4/J1CETKXlAIY/qsh6aHJoCpaSPOBnR0/AnP8xw7ae6c5j5wVYRQMmVY=,iv:Db56gtwzmAZuSFMAeyMTJLT3LMOTvDtc0CCCtCJzuRM=,tag:RtnhRlavbUxaSDMKp44VgA==,type:str]", "pgp": [ { - "created_at": "2026-01-02T21:17:51Z", - "enc": "-----BEGIN PGP MESSAGE-----\n\nhQIMAwDh3VI7VctTAQ/8DSXgLzTxvatqeyCClZwBZ1fczXzy1eCVMRCtd49ci9Fy\nZ28xzCeWf78i5QAEr7UtrkfcDYXojsaiTROQ1VbWm+Xx5SP00sOTsmlMlz4qAVpQ\n2uhIEX+v14jkTh4xluqVmqMnq2cFQCNSoCEJfeUzYiH+IR0JOpltGAsewGc8BVPF\nKCl+/PnybTFeNXNvJV+k6jdw9pboAid6ehJVFW0K7iJ5Ine4fCsnlTSs1xTbofhB\nfzxUDZqLc5VpwCvlM/aN/pFGwGhxezXwYo5arFlcW5ZTpakVWlpBQ9+qF4gSTfTU\nfOaLnKexJnbEIpfK3IfmftZnoSEucs+DG5Fyxf0TNXnovVBk1Q24f3r3b25lL6Pw\nLCkTVc1WB3EVPDkLho1KGx58A2BTLvl8beKXoBDpk+rIFnABVYjqjJcxRSmqgkV0\nSgYxAghk+6UZs9iREvn9ruWRaYMJz3Zyda1cfdbyeqRDi7cT/C2jVaq7LLDSuUQW\nwyKjrAXaHtuNa5goUwPnT4hDgImekXC8N1qR5fzI47/ZoYymeCxGt9z8geE3hEg7\nw4jYcIV+oHFenu7RB3b3NOZwchUEeBFPGlA274oM3nHrtKpL3fclnV1hvHmNEB0u\nirclqP9EYh3DLfvtcXXTpE8Pm5/8QPVbFTIqcc3RMA7b+SE8ZvE0xgMC1PxJN6uF\nAgwDC9FRLmchgYQBD/47FReVLf9fl8aqqiDUnWz3/3Rcz+KUp7UisUgDrdi3L2wv\ne8mYl32v8qOPVPkKyEPIdjLfLhdcv1TxP3U6UT8C9TeP3Edile2s7MbuO6u1V1yj\nSuCez5naXww4KiJozwl6FtAZZZ9aKRLLkxsPcfItkCPKlxcKc2DvEDWKOdHBWB0L\nKYBf0u8bF2SUHR8ykeKybc5imMg3/jI8Vbu0gt8TfihU2btqwR7Pd291421S6irT\nK4/8VCsB4uPz9JxF91XfW5m86NPCTODcTB2C9VIWmdkxnk4jpQmv6qwkQqVKdApN\njJO8P4vgu2iB12zq+dsmx9W+TfSizocrCbuUBieq64EOx80QtZEgGc8ORf7MWq+1\nrO6iC0QjlUnAW4oRNV/Qv3l7NSm0pCA9XQL9x7PMh0f3rTYLajOrYDI7cZticAA9\nC7ZuVjUiMB8ykj8nfflOsXUJyHVYT8njeMqVEixEWehj6aq9eMx1VStphS6C/cbr\nXQT96ISnIG0fa6fNqEqzXBES1HYvd6Wo/jjH70wzNCWezvJ5IDANPkEhvThc+MmW\nxgPSK1+1UEzJGQ7uDo4Aadwn/Fym3P558icaEdjt8Ykay+gZsIi7ANVhJa0SI5tk\nNKAXvcSA6Dq9tnILre+oLewf6A/AfFdUesiantEaKjUgWQtad2P3iDqyJHtsz9Jc\nAXI8hZQSfOmDjpgjG27pTajjhmwNQ7XD2ttm1iHp5ho16zYtS8bDtX7bEB35YyM+\nFBuxrwcUNDD/mfi9uAtcjQm3x/IdLU4e+NL07GvSEWRU5H8pUBPcaOeUqLI=\n=pnj0\n-----END PGP MESSAGE-----", + "created_at": "2025-12-15T21:53:39Z", + "enc": "-----BEGIN PGP MESSAGE-----\n\nhQIMAwDh3VI7VctTAQ/+NHWvBUy/8BbZsCHEEXhTI3FC372TPFUSj6Scr1Nfv/s+\nYozQw+up05n2t3f4WXro1zpfrxZeXmRv/wrWMb56OvNjCh27ZTyx/wooo0aljFkZ\nYPK5+nk/BvGBVXopiwF9Kj9IY964IdIi0rahYyGgZOigE40e9sPVAtFWQLefMpFl\nWG0iOrMez/4IUeqWhTZaNHfm0uo4y/69hEGtv4GA332IgdOPIslyzs5KvrvZci8R\nmqn88SUGNsyONFtwvrY5NVN4hr9UzklhecBD7NPGjCU0xW2PoZEjYD2SHP2eAp4Z\nVwq/lMux6oV62t/nTced43wIyGni5luwToPwrgWquSF73WaO3PiMFHH/4MXJxGOa\n+EKVehatyxK8tGo/H6fLhbK19vFlZFLKOmHZjQAikFVOfIxQSptnVIU+5j2wajkC\ncaMYYoUwlQGLxuG1X9RMdbEMQZRwKw5GfxSd0LlSFOOnBeWgm9W/0UawIjS/TIs2\ndZJ8TbInPyCjUWSUO1HK8qV534LfbuFCB4vzv1fBBrt3wwZ0M+QT4hBg6PeOrxox\nxToqsD3KBmmcnInMx0LJ3e5rh9X9CtzJ1DKgZweDpcawpSNg/BphruILlAKx8OEF\nOEPBou9XJTcDiPuExqPo4WDwfELHrjEDu2xJGgpSWS0e00KPHmFqTs38l0XB0++F\nAgwDC9FRLmchgYQBEACOCDUxvZ9S0fzxRc29eA8JdVtGslGtneZlHjoHAyRjpYGv\nfKFGR/HcFNcdPCahQoYyv9BdKJf1g9/jOhmX5TdE63fIcZEOrdeKAWFBaLdcOjOF\nUxT4wpiYGuOVslPkhGXIuQurjZipePVnt1/VFixrrENyEWm4DqGmq1Nr9FdJtwhJ\ndUL2zlBd9/jBKHV6+AKfmI2ZcSXu9gNelhUU0keU85TRBSa8tAWSBgxEOsMAxP+G\ndb1dp1EVtlwgce99GH5dyodsMyX3sMfjhmf3y7EELW3mg9h4gY88F4bRmbQUaHom\nGypHWWjqz5gXSKMh5sx0Mz3TNiQnxu4AGZUtuFffx5RjYyEw0J7xxtTfiHhPQ3C4\nL0iJ30f3SgNJZWQX1Cg90BFKc3yOEzK3ePzVoTX4BCnAGMKDRnU7GCSM4z1X0DdF\ncEstNxeWSWZ7UzlmQXl0WjT8i/fac4WL6rC9DiWnMDzu5ckyJi+LTZvbmftaHQhh\n1kB8jZ6n6pRSQFFZENNK+v1gBaNuBrmLzeGw865L7CEp8WjIkTdgXrD0Y4LUJnf+\nIQy8caHmcn0RyHsnYYiuKGvbknKR8ehm2N491I0khtKmxN7mupPaN9zdNjuSrpdh\nUw8ZK2A0OuiQuuDljbsa1HuhknR2QhPLoTrdFxV51T7pgEFSCiKiimw8LGD2ndJc\nAbVCL+b3lArUcgevMl02e7GUn9AjXJhaqRFtI8T20Zq4fM2ndBCeJU9ipvAF6q17\n4qCtUCx0M5xsS+2sWwTwaUH867c/JrvP2DQao/AUb58acvGZ4jRrZRoWZgE=\n=GidG\n-----END PGP MESSAGE-----", "fp": "4BE7925262289B476DBBC17B76FD3810215AE097" } ], diff --git a/secrets/repo/wg.yaml b/secrets/repo/wg.yaml index f7ad2a3..fe2e361 100644 --- a/secrets/repo/wg.yaml +++ b/secrets/repo/wg.yaml @@ -2,170 +2,149 @@ wireguard-twothreetunnel-winters-wgProxy-presharedKey: ENC[AES256_GCM,data:FZWAR wireguard-twothreetunnel-moonside-wgProxy-presharedKey: ENC[AES256_GCM,data:Y/EwbaVbGljiz9XZmr7+/udBfeaY+CLMfnKzekXP50Hu8ek8aA1/SKs2qd0=,iv:BijEDkfpRWox8CPwCoZLA42WihYIqHJJgSgOfsOGcG4=,tag:8+qEnqTsqyNdD4oVPiuQuQ==,type:str] wireguard-twothreetunnel-eagleland-wgProxy-presharedKey: ENC[AES256_GCM,data:dF8VPApd6iYKIZjBXB2rjIXIxyy2+U76TdyFuyUW0zSbtjzqn1ZKrhX4w/M=,iv:GqOHsS97di9sHqjndlq0EdWLcJ1EMLmDOnFJlBgTvYU=,tag:PdxEYlg3lPShUJYlANLjhg==,type:str] wireguard-twothreetunnel-belchsfactory-wgProxy-presharedKey: ENC[AES256_GCM,data:NAbVE7ysGDD6TT0RxdL6bTNloac4RBU1JWeTFqYo9PO6ZU2f/yq6aboi2AA=,iv:Ky4UvgRDEG1UgDmi+m5mHWHO+yUGzphQPYIuyAXDkhw=,tag:WP+/8q8jfitNC/rXN5Mp2A==,type:str] -wireguard-twothreetunnel-hintbooth-adguardhome-wgProxy-presharedKey: ENC[AES256_GCM,data:Gr9tP9SkizZOR4brFO3+7PqDC9pG5RojWa+xDDtqfZT4Xo6ZAN2002WGUXQ=,iv:Zj7oy/d/o5sNYTsyPaUQ9Th/xDuG7o82NpnP6TZzqeE=,tag:OI/DCxjJNpZC1C7foO4xsw==,type:str] wireguard-hintbooth-winters-wgHome-presharedKey: ENC[AES256_GCM,data:57KGUxn1BibZ+9H9mXg9EYmcy1JBX+M79ACL3Qt0XEMl0dFlk9Wq6cr3JTg=,iv:9QHdykNlUU1H0uco21zA8leQH73PAeL+xTVi6V9zx7U=,tag:6mfSCddnVGMBEAqCHDIIrw==,type:str] -wireguard-hintbooth-hintbooth-adguardhome-wgHome-presharedKey: ENC[AES256_GCM,data:zBfV5HMy3h6q7yEF6Cu7sCTONa8nJRmMDHgVFvHVinKmyj0qpf/WGfnyb3g=,iv:3JlNgsJHkE1EawLWIJaZsiZlu7pN9ymFQ5ZqdM7W+AU=,tag:pGfsh34HnL8mUhKyFkLniA==,type:str] -wireguard-hintbooth-hintbooth-nginx-wgHome-presharedKey: ENC[AES256_GCM,data:BGdVjcCyhrSgIIZtdoBUscCitNjBat56YjZOFx9Vao3vBMjoHFGY1WFV7zk=,iv:wxVClKJE6R178vCp/RE3PgBYYLIvOdSV97AfJagWZ8o=,tag:zbuMwlJYIKtV7ylwvgLutw==,type:str] sops: age: - recipient: age1s0vssf9fey2l456hucppzx2x58xep279nsdcglvkqm30sr9ht37s8rvpza enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOcGpVNWtxdTJLYWwxakNk - dW5vRTNEOCtBNzlPbEpGR2g5MDhIYU5pWmlzCmo2YnRGU3FCZXBXUXNTdm5qNzBD - dWNHYy9kZTJwaWxHeFFmZFh2ZTBtbjgKLS0tIEliVHZIbWFFYUdOUDljNVNwUTNS - N0c2ZStaaU8wVFRKeTAwRmtDV25wc2sKjFO0FeMx3v5Zn4Ipm2549/boRorripM/ - q11ro/tNhsSt+GJ4FTQA2hnmRj+fG7BQuTw/ewXC0posKS5optxAbw== - -----END AGE ENCRYPTED FILE----- - - recipient: age18cgqlely56hgmhscllkmafwpjdk6dwep6ej3vkk97dzemp8jtuksqrrjjl - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsTUVIQTFYanlUQWswRUg4 - bSs4ZWZYcnFMVUlUUFdyVnE0T21IVkdWbTFnCkd4dndFcWR1RXRLeCtXWlYvTUFn - Uk81dHZXdTBSekJkaEZxUWZnZnUwR1kKLS0tIHc1a2tpSmNOc0s4akRCVzVjcVQv - cVNDL1JGd3dGNnIxSHhNckFLcTFJUWMKzqsDS/S3wHigjHBSgztEmg2na/2fR9As - JxUe/ZSdEaMKDj2ZJ3EM8u5aY6Sp79aNypHsPcOXjhX0VoAwPtRqFg== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaQ1VJOVQra2htZXhTQ1Jj + Q2xxYzBtQlJBcHp3OWdvK0phYmprNnY3S1Y0CnZ2c3lRWThEVnNmeGs2aGZXNlZZ + cEZaUnRrUFFZZGFRd25nTnBrVjhuc1kKLS0tIHg0WXBQVGh2eVl2TEl0RkFsNElP + dXk5NmlTRHVENHRjbVVRd00vYkpoTGcKn4+hUSvHLU6xJA4UJSPWadFwPtyfKMii + 4wFBv1pRwUmxehIpS8C2HDnyBVnT0X/Sv00n27I2K4Z4/WzYTXPTdg== -----END AGE ENCRYPTED FILE----- - recipient: age1g7atkxdlt4ymeh7v7aa2yzr2hq2qkvzrc4r49ugttm3n582ymv9qrmpk8d enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrMjVXZVFnTEczbEg1ZXBG - RmQ0c0RoZS9pWXdhT0ZVSURLVGxTWFBWM0FjCjV4cjVER05YZnFaclJnVEllSURy - YmtzUzdOK0pldjJiaFVKVDcwY3VzQncKLS0tIC9xMUd2OVlsZ3lmRDYyYlZpYjUv - anFDWE1CNGljY3ltN1lpdk9ZK1JySXMK58PNBo74DHptQTfT1ozV3Ikgf5BccRIH - Bw26F4GF8hjJL1Gp8szouJ9iN/mSNR47NdQN0nWy0GfOs5fClFfWvA== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOM1VWRG5yRUx3MGNMK293 + RWJTQmgrUVRocHVuYkYwU0UwZXFrRm43cUZzCkFmMU9WT0M0cS9JQXJIMU1VZ1pu + TVZhc1lFNklRNCtzTmp0eldVaWhqUU0KLS0tIHJNbXV0U2VoejRCNWlFMG1RK2Nu + UWNoak1BS3RIY0NGRTlxcDIyYVlHM3MKHaA3riInA4NMkWQDg69uxGdR5f5l6rm5 + vywj80Mg/6Cy+mFtGc1y9RqqsFx3IpBW/ECeGrwtCLXvBKOnZ0gaZw== -----END AGE ENCRYPTED FILE----- - recipient: age1ly2endyt0y9xyddj6yuj4nw6fa3ltvzlvew4cr4lzs6dv8dkavpqadmyxx enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4T014MWhrRjdpRGkvallr - cDIwME0yUzZseXZVUlBra2d5aXgvOFh1SXdzClM4QS9zanRhWU0xZVFSdktDaWc2 - TnFWL0N2M3VmUFVMWFN1OGxqSk05QWsKLS0tIG14L1BiVnJ0NFJCYUZnWXl6TU9v - VTU1ajNOTWxWTG5OUWRFMStLRXJlTEkKR8JA3U5MLBwMnFDZtlbrkJxmY9nENsza - JCmxPW1BTH+VadbefjGPAEwVj8XqgTCw5f8awNNZFUUe0SIud80pmQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUZDNzVFdlU0NYVTFsUkVB + OVhzbStSQTlEblhZdXh5cmZGTXVXNWIyQUhNCjc3ZlBHWDB5czlZcmVWU0dWUEVN + OHp3YmFRaTl3Q0FxSGxheU9RSUl1R1UKLS0tIDhNUmpkbkFlNzRlbWQ2dXdGcXVn + dlJVaFEwNVN4RGNVNVN3djM5c244SmsKO/jb+qiWJUu7BE3VoVQDquSxAQWDcSj2 + g+vLyNsrc1WsxyegfRYExGAx+DJHOCg9GyACXxifCP7xTVwfvH+yfg== -----END AGE ENCRYPTED FILE----- - recipient: age15klj4t7gpfp69472mne4ue62pp6m4e04dmjyw7yf30qtqd3vl3uqjmcyxm enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFWmpBbXY4YVZmVkVzQ3FW - eGl1SWZqZWFSa3lmNFBNRUh4UG9qREhQR2ljCk00bElJcHk3dTFNaG5FT1NiOU81 - aENlNHpkckFoRUVpakpmb3lIYU4zOEUKLS0tIFBpQjFEa2xiMmNHM3NhKzMrMFl3 - Vm91bU15TFJwSUd5WXI3VER5WnFEZlUK89Iu2PeG/7mXaTaCUClCVL44VFLJEZpM - 1s6QFAemy/B5UYeZBQsWiN1v9yAktvA+B7BeS0lyZohpV6SypLgjGQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzRVBMTXcyV29kVVcyRTlY + SExraURsT2ZkamlGRGphRUpYYUJUb3hzV1JjClVTTzRHU0MvVkMvRnNid1ZYdkpP + ZTlUYnVhTHlKREtIK1N3MnRnZTNHWTQKLS0tIDdaTHRvV0s1dEJseXVSdTFXUjlY + bndzMzRNSHVScDhCZkV3MDQwYnllcGcKOHUp8Q2Qmgt0CcOZZL6obGKDT8fTJ5eZ + hOeJzPoS0MY8BEICcxekOl0MICOhlIySXKx6m4MpRjgnMVX1Y5OMIQ== -----END AGE ENCRYPTED FILE----- - recipient: age1k73gy5em3js9zklnnkzp5hme9k04lny32fgahmzddknjw5c295asdyr4x6 enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5RW9MOXMxcmZQRkhKcSt4 - cXJRYnVPVytOVDY1dlAveFg1eWlMZmxqcTNZCmVhaVZyZU9VcmNVczFLemNuYTJJ - SG5WWnNJNExBanVJb1VlT0VIWUtmYzAKLS0tIFBtSDN5aEJRVC90ek4weENZSmhQ - QUMrY0dlMStHZXY3VzBkZ3NZMFVnYzAK9C1GRRqXNWesrK3JYwol3hDkmjaBBUNW - 3CroUXgWDEQ5U8M3aFKSdhXND3WkPdDAKpt9cn34lEtlUOoy4MF/AQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOZnR5YlZXN3N1WnFUcm1o + clJ4cVFoNng3WFNKWEd5K3l2TTUzWW54dUdjCnc1L2l6WkJBVHQ4RXNrV25kSW5s + dE0rdnJqUmllUS9VVE93OG5idUdzUk0KLS0tIDNFaGQ4R2lwRUI3L1NxL0UyYVdM + VjJJdzBuNGsvazVEdzNKRW5OdTFFQlUK5Rz0X+FopwNYu8AuC7eJPxPAr/yiZSg7 + s0Di5Wy1kfKXdwRbgSgXFZifg7bC4wsetEGi3SPVOa5yIduoMyYmaw== -----END AGE ENCRYPTED FILE----- - recipient: age1cmzh82q8k59yzceuuy2epmqu22g7m84gqvq056mhgehwpmvjadfsc3glc8 enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2TTV6QTNBNzV1T1BVQUlq - OEVGUFpvNDlUT1lWanlQZ0E0cDhaY29vRUJVCkVVbzR2d2gwWGNESUZNSGJianBC - ZDk5anJ2V0hwQUVEMUg1dmZFLzFLODAKLS0tIFlGR0xGamFKY3lwUkhaRFMzK1ds - U2dyTlNkdFVTYXJKQ0pBRnE2S295czQKy0E1Iajqkzg8cyTYNXoqf9bas8BaBP4+ - x7kjIbKIgBbWpT3niLA6Zl+SN0tLva67ddau4undz7YA7OZ4VzZ2Sw== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoUkErTEtHSzJubXZXOEZa + Ymx3aTBjb01KbEtHUGROSllpMXV0UlpwVmgwCkRFcWs4RWJlUXIzeEtDVnJrQVpa + R09Ra0VOMHpGUUpUYWJyeks3TzRRRTgKLS0tIFA1cmJ4SmJEWXdaVGdwZjZZN01y + aTF1ZnZvOHYvZDhxSG5JSDR4Zm41NlkKijbFP2InlSCYZNR/kPWiedeRCFpLDx0M + susZTvBARIzPqR+nRNFQ/W7CvwPFPtWIBHR4lOhDmrFYjkCh085Ffg== -----END AGE ENCRYPTED FILE----- - recipient: age1wmx8y2hs83j2u5srdnfxljrzxm8jtxl6fr0mq7xf2ldxyglpzf2qq89rpx enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnajNaMk9JcE1xSHpyOHV5 - L05FL2lPd0ZBNVBEQ2thRDZEdHFYL3Nnd2hJCjltSnJ3MUVvSGNyclppNTA5TGsw - OVozcGJ6c3RCMXkxTnN0M25RcFhyVDQKLS0tIGljdHZUaTNhVEZKZE1FbXNaOGVu - T2k5RlNWWGt6a3NSSE9CQjFvK01mMncKuUQ8PeSkfj0RJgDRWbFXBFAuWAOvKAox - LxBKr1TZ4oHIYJjtgP9mnKpNL5ikda+EkdEAt7V7exy2m3SvV59frg== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJWEF2Vk5ZaWRFK29MTGht + SGFPSmRndDA2L0E0Qlhxd2RVeVV1UDhMMTI4ClhORmRrb1c4RnZDTmdQZ0ROYkE2 + eHhNbE95RkE1ZHYzYXluN3prUFRmSTAKLS0tIGVTcndEOWdvV0krOTRjd0dyZHow + NG9PZlBEaURzbDF0cGo2d2VvQnFocWsKmZk7kBvKqJMDBl8rIaLw3NrUbVxzrRMN + 1xSb0iK/JDsCBDZiz+dmb4Kha/LGV2DM+AyXD0p/qSQ23yJM8WMukw== -----END AGE ENCRYPTED FILE----- - recipient: age1mjgw3nxlnqdj04mgjz3wn7fj2nl2nxla4p2r2fn4nkvayfgp09pqllxzyh enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3TFR0dG5YVjRYZUs0bk5W - SE5aK0lRWGhMVFhNNmNKbCtLa2tibXhJL0JzCldGN1hNdldXVWJ0b3VwaVRFMzk5 - OTdjTGpMS1NUTU50RjFRaVAxSHcrY1kKLS0tIHNvaEdING1kc2RMalhZL1FqL09K - d29KMENYVEVyNzUwNEVvbitXSHVjUncKokOmKLepXUcsYf/5QUBlsd0G8ZyCsV6T - z9otd0AdEPeRTSbh5pJ05WYEIR929aEPlaLLGhIdEI3XCOHey6GpvQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4OS9Ib1ZITjVyTC9VS1JP + dkJRdGhEVlJab25zWmc1S0J0Tk9PL0lZdVFFClo1S2Rabk5qZ1R0NzZIT211N0Nw + M21scUlmZ1hVL2lSdGk4dEoyZW80UGsKLS0tIDIyMTdyWlNrMkxnSmlLamJJdksr + QWpZejBTSHp2T0F1YWtwQmdjRmtKVXcKM4Hr5Y2eDOfwadbTSAJu62KGisljfOfI + BiIqArmfyjo1upw676EyV5JeV3vbi2jTT1rn8QyodsSdnI9ms9Z4KQ== -----END AGE ENCRYPTED FILE----- - recipient: age16vzhcvz8tyxj8e0f47fy0z4p3dsg0ak4vl52ut3l07a0tz465cxslmhevl enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4ZFRFcDc1cWRLeHhmZ0dB - RFNOVGVpMENydmRMRkxuWXpCaHdxUWVwa1IwCmRUMmUzampKS3BidFVLYjJEOU1F - eEFqVXRCakpTclpGOEpMbUdVbkZORkUKLS0tIGdjUkg5UmRuV1M2Rmc2Uk5VeS9t - Z0ZtWWFRdkl5NDQwVjcvYmxKVG1wNFEKrP04VYIFR2V48RqpAMXgp1sDbr1NH0+0 - kvWoYuJcaKB1Tw3xBaLmrCjKt5Xd54linwpgidX4dOAqHjHWyNIHjQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhSjlMNU5KNHEwdUZLejZq + SlIvVUlvTyt5QktHeGs1QWYvcjN5Y2RrMkM4Ckkwcmx1MTUxWmoza0gxMW9pcVd4 + Q0IyL3hSNFAzQVliOHZjelpjQXZJZk0KLS0tIFJzRys5czdmNUwxeUJtVFk2Z0VU + cTZHRFRMczNvbjdLNGsvZEtTNHQySWcKgiQ+amm1xrvTrU0lZKIKg6VMaxiSkd1O + +ib0vqwWUXDjxxTYaLitRCB92fwem3lsUJgmhN1kcRS3v1COKimbtA== -----END AGE ENCRYPTED FILE----- - recipient: age15cx90pnp54xp5gxlt02yn9j2pz968wp3l5ukdkx55xuecp34e5pszjku4m enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBIeFFhbTRvQWNtaUNZWm5l - bnlBbVBlb28zd3hMRTFxRnlacUU5dng3SENVCnFDT0J0VWJmZXhueFFmTGs2TUlP - a1I4TkVnY2JPSkJlUmU2U3R0cFUzNmMKLS0tIGNLb2JVNnBZWDM0QngraUFkSXB4 - ZHR1N1Ivejc2VzFVdUlKL0lvdXJja0UKENB2JzmrXT/sFVpVzxR64OpoGwq65Q3H - KamGdqdsD1+MYsbnklUdHSJqqAbfTH+BYpjKtF+ZsPqaXcKB9VjKyQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxUGRlWGplcGtDb25Ua3pV + d3lIZWdmbno4bTJVMEtZVERUdkR2UlB1ekc4CjlnLzhMamxnYVd5OVQ0VzZuVjdy + NVQxOU5UcXk3M0Y5M1hLWU1WM0o3S2MKLS0tIG9xQWRRZS9SQW9sTS9FOUtjQThE + ZDI1Um1RWm9jeFllY2dmTUdEZTJqU1kKh2Vm61sylFJwsLOjdFVRUXtabg0YzHvL + jHfr0ihHqMWQLQnMVFDrkTH84cnHDZm/yTijXXRF/yAkxlVUF7Tv/w== -----END AGE ENCRYPTED FILE----- - recipient: age18quey88vge7xytclg2nuq4ncme86dg04lxwczqxczmdchnjg3p0saehsnh enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoWXJ0NUlEbXZNdHlzcmlC - N3VoaEFKVXdMTjJSYXV3Vlp3dmtFVCtNang4Cm93RDFVVXgrQnM4K2lraWNSVjBo - emR1MUlEdWJxY2h6RlhTdEx1SnpmZm8KLS0tIFlLenQ5WC8vZnpGVEZmVG1MbFZU - NkRQb3c0YjV1RnhzUm9CRVRtc3Z2MUEKbwFjrd9OxDUmw7SSMGYXjlzsMVL12iNv - 31E4a7ZCPw0zucoJpB3kFkQ/0vveOHZU3bjj0htm89H1BIaW0AZkzw== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBIR3MyS3NxWWNwRktuUGFy + THJ6SkhuZEhRWWNXNzhIYW0yekV6bG9MNkZVCnVNZU5ITDRJUlVWLy9hUUZrNFps + bGtsTWxIT2NrRFR2ZlhDZndubUlUOTQKLS0tIFl4Z093dHlGRXk5MytLMk40ekRy + Q2ZNT3NKZTRvdEZKWGhnQmhqVGp6a2cKbgjp8N1EOVRt1mcLBhWOl5vkNeeomu3L + ur5Orku3qMdm52Ff0msNzlPnrUmmblBcHSrsDvkWb3YI/Pe/zrRlJg== -----END AGE ENCRYPTED FILE----- - recipient: age1ax5hqk6e2ekgfx5u7pl8ayc3vvhrehyvtvf07llaxhs5azpnny0qpltrns enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCdDZ1QThYRGJ0Ni9QNk9D - eE41Y3BsMmJWVkRkV05FWjhlcXF6ZlhsOEFzClBzZGxpU1Y1TmJVOHN0czNNcjZn - UGVQSm5RRWhwZjVDMDV6Qzk5RmljMjQKLS0tIGp5dUljSEExUGNxUnRZcHVTMFdj - ZW5MY1NJMmRJUmcyRTJnVDMzUzB3cHcK54+0I7202n4P1kZGaCI5kM5BRAnNh/ts - 7ygeuksGvi+7gs2UFn3LCUdsaL7RsBuX3NBiVyBvE02gfKecT7W/XQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaY3ZqNHJSeVJlMlhnTXgy + QW92SXV2dlFsbjVTSlltWXJ6ajEvaEl6S1FVCk1oTkViQ2EvK0NiYlBZWGszRzVk + T0U1UzNqTXE5aW5xL3JwU3kwMnlacDAKLS0tIElBVGhncUpvNE1BS1UvZ0VSZUww + THZaSXhMNldUbHpBMVZQWXYwaVVQYWsKpUbG+lC37W6bzOuu9MaUmEZ5T1b5EC9k + VIY9XUoA7h0Z6G5Jrx/lrf6qsghMqd59gPA1qh8KlCJBAUJPHzQKVg== -----END AGE ENCRYPTED FILE----- - - recipient: age1c2enwel9un28dcs4wg0vcyamx9a4a6g3walkhu8w5lqhmd804paq9d24as - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKQ04yNzR6MXU3aEdFNU1J - c29qdk5pbjA0Q1FGcUZTaytrWFNyM3RXRVNVCmVyU2czclVjYmpmQmNuTmhHdUlv - MkpES2FmK1JLc0tmN1BBRW95YXl6SWcKLS0tIHhCendLQ0ZmbThYb2phTG1CWk53 - TTErRmhuaDlkenNSdkxiWEVTSGFEazgKZj2nEn4bgT8+oVUG38UDGmNrq9wAk7sq - 9PzYw3cjGwRUFwT4lV3vK8ZNU6DAepga7ebwxfPNjP35h9eMtRVQIg== - -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-01-03T05:23:41Z" - mac: ENC[AES256_GCM,data:D1iqvJh7qLoC6GlwFItacyb15X7LrnXZfSQQVhFRQRnVbFc/ECqM6P9OP4PlCfAH5Up0c/iv84MsE/UFubGKGR0i19lCQ78nLPNkFfvJ+NXg0sr03FiFmW0Q8hwzauzdMUiQr9/36D/ax+BVBTQyWgZEneiCY7KoDaQKJWzOGT4=,iv:+AZ+1u+TZNqrLMaDcHU0fgPsvx5HFprlKQExH5pIjyM=,tag:ytnj7FQQ6YivKncyZUHigg==,type:str] + lastmodified: "2025-12-22T09:11:50Z" + mac: ENC[AES256_GCM,data:D6qKXhSuYGPm9K7Al/la3O++DmOTQN5++96k44IIvgSR5Q3kTkMYxPsf3PWNyjMm09+9aRauuHPHj098+W1rXaq43Iqr24JAuaZNwLyxtqkaibv/Zhx1RgEWGXyOHDtlfIPoULNKVZ0ls2mtk40oQHsfhnRyS42m+HMQnL+tCF4=,iv:uzKbpZu9P05KbaXnBUxN4rA9nYOXpeK+E/scWoFxpcs=,tag:PuMdBx3JOT1EfFkOPV0G2g==,type:str] pgp: - - created_at: "2026-01-02T21:17:55Z" + - created_at: "2025-12-15T21:53:40Z" enc: |- -----BEGIN PGP MESSAGE----- - hQIMAwDh3VI7VctTARAA001QiHU3uO1goHUTsx+QnhCrfIBDjVAHhZtj8CEx1tqk - YaxNUNDra1uyGQqwdH1Ly8h6cSzeUfEtPfkjsvegYo58PSkz5F6mrpROkB1mzzfG - /H3MpCHTzroXPmrT3lNxXZyYqxGzcfLBLU05etEiFV+sV2mjoV1nYY2gTnH8XtV9 - HVayfxR4cYZOS7ox8SkGoTvZHsbNT5+jaJn7GqRjrcjmjd7S3gvq83ROe82YHNA0 - 1O04PSGwnaGC88E9Y/7segZC8Tl1e25Z0c8yMd8JHsn/RL8beHwUHTn6nuyo65Bj - Xmic9M5C16ur5yQtVr/+xU/FCbmkecsOL4u5YgECFt5w7zJZzfGUHa2Z5dIQ9T5o - 2oY/h+GsN9xTM/6ZVcgCbZrcHnIvP+5VmIEmXkdTtb4cvTFJMkDWxx7NrS8dI/Rh - 76hoCStleuLpw8+zwIYC4QdJfFWBaQyw8w0nON/qp4E+kyU8E3syMsjqFOqclSeU - vFDTvgl4/Z0nPxTl+IBzG0cBPMjUXgmvGZj4NAhZhE5nNwkA34GvmMcfjVhy8ROX - WWwgiFBP20Po7p3aHz57KA4UTkgIZfhK4BRbb4BhQoaYEcXL8Sata/SJOR3RT2vQ - 8uB8H8orPpugdafS4wLv/qcwYn6pa2ubEQG59WfihIomDWh4jl+i+kfnM5fYwX+F - AgwDC9FRLmchgYQBEAC4bp8seECcmzLFnRZsABQI/TJg7jKDEZuudEiEGmKUhhOf - Mz1pQEEHyh5aTFSJDVq2bNgPKt4NJ/bQL1QOq1lnsprpAAL6+HoyezA6ygfh6YmW - 8kJOwJrVXlgo+H3XD4XeoA7VFVdcHkszFYgq4KCd8KX+haSkt0Wbj0s7sQkKQo/j - PUUQN34pxfyJ0IiqlKuLgpu7ggMJkDqZGoYnXH91Qt9TYi/liMMx4wo82YOQFH0d - xJUewsVvUpjwmFotOBKdhk+zZlOoNNr7QnyZ2SRyXNUFI66fsw5QsbwDSXJ4Hy8C - 3RVRZ7baxw2p5wMyZQBtMyqu9quS/XED0cZA+sxvKOTrC24YbD+nb1ktc/9ZJghH - TZjhQLLhmrbHPNnrHIrnEJ6XrxbgNHWTFE+yX/e2lRIRGwz0cfgbY2pLFJ+6uhSu - PkodKyq/PCerYZPnUMjnLxogNtgZhf6jK4AzG2xuFZne37NBEaXY3q1ktwafpRia - 1UrO4PC2cwJpNuIpMfHbA8xieppwRZbqBSSAM80V12963cFakUxLmZdMG0ApFTDU - 5NoAxwBaRooHjTgYwdfgtjikwsPOf/VFWrB2IkBqF/QhxdV2sxasmJCM04e1gidi - 0prCX7KoMNtBnHpubfwV7sTNdhN15IKmyHNLw9hXfZZmN9UAh6LxUS/KHMZSv9Je - AR+Ty00mCszxvBco6ee6Tv7gEhBU2ZBhu4yyWZC5Kd0pNvr4ZtCGNNY5wIjv00jd - nNnMW7MrEF4Tz/So+1TJHiLLFuap2RpXifCHRiXDMHqOUuFUgGFSNNlhYXycXQ== - =lDR9 + hQIMAwDh3VI7VctTARAAq7Q/kBF7Xgf1sPEfLLNnue7G+uErtVHLwyGwqDRAE9aw + NQ9lg2xJIro3sJhaVz0EkKyuydkWw3vjAwltnRd6FVtfKnBeDirFJdoM2zOLNdQe + OYbpGp0/C2szgYkBqVU5hDh0Gzgho0UzO0rhwf/c+uVNTKPfUJBym72p2OKJSUcm + NWhf1On/aaHsLQ46y8TJxzoxI2PsziBXqMQGbKofAgnNPSyYRvzRWR5+1lShgt4e + KYLgzGKbLp+ENptPOmqLbKuuVhFX8WXULyRvS3hRTKjezncPuRqxG/GE+4BzS7ih + 6WZ+WBCeG4sNQaeTXDjtL18DyyzT9y+UihE8O+icIPvNpGkJgY5OiKfJU3W/Wqih + wxl3Pqgb9BDvz/jHMUt2GN07JuX1at/Plx/kG3xMmgrSJfDi5ZA6oiBi5B4AqOl5 + okn635mBXFnfGuz65hrP05P7p58BXLXvMZMsrk8kNknQu7mCeXUpDvXCFRo9xZnz + OeTc7LUP9Dp5rlSJSzkBibrZ4BxebFL4ujPQ+8cibIu2XAoSQPQUCmscq1D6K5aY + 37GS/HWwNzz3PimT/D2FlKpbE9Krn9z+H9a19DIpfdWhxD06pu9pLO9cPBmYyeHs + jAnd0RRg20mF2MBy2f24nu8+ziCARJQC0H9heR386zEDCKMCo2XkC0DqbN5CL16F + AgwDC9FRLmchgYQBEAC+cfiPynGPEFfdnt+Hta9/FMI5WMXMbV4XFqD0XW6VVRLe + 1o/kANe3TM2hFzf2qVfQ4oLPxOlQtJNylxYUl2Z9EJB+YLtuHgJ9ffx1Bkc2a6md + dxb2Qv6DaKv53EiD8quAIPhaC3XzVsfrAhwSL4pga11wFYEge1wXpGGFp2LNbghH + IW273sFPv6fBIqjM0dF4QtLFsphc6dRZdW6qzuFEkU++RvfZmoKdnrzMFTaYhiX1 + lwuHuiIWP3wX7YNGgTuKcecvlUo3kI67D6SGHBXVkeyejYH+wfzrApUGdHJ4NxY7 + l3xGkrWIwqWgqh5aNErgKAA8sUS/Gcn50UHlsmO5RY3qJQPmPK1p7nlH9IKktG+A + 6AvzdgWqHnqaA/Cb90bGJZP4m447XQHIv9UrwB+6rffRA7Dvw7oFsNnh8I3Nl/W3 + WNlJ1vuXmZXQhlBS/95DvWDOzOpqIh8XSYAR44506n9u9ZRh00dB/SQ5yTA7AjSX + +Jz4SAo+8I43CiBEUbGCoxRgwHa7h6UWK7LsXCGHkqHHS7VRWZ3MiZkrVdbwv8+D + fkcwHmxJQGxjhU5F/cdmMX2KYWXu93I2Ohk+vZ7IpDbP2H/G5epgn+pUHbEbBYrl + J874Pj2gKA8vJS7bm7tbMVyCebsRwzt2eh8qwAfJL9HAup7a+hIQaIVqxrvnz9Je + AcPIsNoAqTsZeGvL0LoLQJ5myKPsb9hs/pOYjRjjM6Fdyy1GwNCdTdcLFjTthVLI + 7JuiudM3Ce/c+mW7+57oKFAqGPB3HtAfye0A9bJ3R9co4LAvWSMk52ia+LanvQ== + =Iisf -----END PGP MESSAGE----- fp: 4BE7925262289B476DBBC17B76FD3810215AE097 unencrypted_suffix: _unencrypted